---
title: Instalación del Entorno de Trabajo
description: Instalación y utilización del entorno de compilación cruzada sobre el procesador LEON3. Instalación y utilización integrada en el entorno de un simulador del procesador LEON3. Despliegue en la placa Nexys de software compilado para LEON3
tags: LEON3_IDE
robots: noindex, nofollow
---
# T2 Entorno de desarrollo para la compilación cruzada, despliegue y depuración de software sobre en un System On Chip basado en LEON3.
<div style="text-align: justify">
Este tema describe la instalación y utilización de un entorno de trabajo, basado en Eclipse, para el desarrollo de software sobre el procesador LEON3 empleando compilación cruzada. El entorno incluye un simulador de este procesador, denominado TSIM2, y una herramienta de depuración, denominada GRMON3, que permite descargar y depurar programas sobre una placa que integre el procesador LEON3.
El procesador LEON3, de la arquitectura SPARC-V8, resulta de especial interés en misiones espaciales dado que, en la última década, ha sido uno de los procesadores de referencia de la Agencia Espacial Europea -European Space Agency (ESA)-, siendo utilizado en muchas de sus misiones espaciales como parte del *On-Board Data Handling* (OBDH).
La siguiente figura muestra un esquema de cómo utilizar Eclipse para crear nuevos programas, compilarlos y, posteriormente, descargarlos y depurarlos sobre el simulador TSIM2.
<br/>
<img width="90%" src="https://hackmd.io/_uploads/SyRJMwLz1e.png"
style="display: block; margin: auto"></img> <br/>
De igual forma, se puede utilizar Eclipse para descargar y depurar programas sobre una placa que integre el procesador LEON3, empleando para ello un monitor denominado GRMON3, tal como se muestra en la siguiente figura.
<br/>
<img width="90%" src="https://hackmd.io/_uploads/SkGLBv8Gkx.png"
style="display: block; margin: auto"></img>
La instalación de Eclipse se pueder realizar siguiendo las instrucciones de la siguiente página [Eclipse Installer](https://www.eclipse.org/downloads/packages/installer).
El entorno de trabajo ha sido instalado sobre el sistema operativo Linux. La distribución concreta sobre la que se ha realizado la instalación ha sido la Mint 22.
:::info
Los comandos que se van a proporcionar para describir la instalación del entorno de trabajo están definidos para el caso en que los archivos descargados se ubiquen en el directorio `/home/inta_pus/Descargas`. Para otra ubicación, como `/home/inta_pus/Downloads`, será necesario que en los comandos se utilice la ubicación correspondiente.
:::
</div>
## Parte 1: Instalación de los paquetes básicos
<div style="text-align: justify">
El entorno de trabajo requiere que estén instalados un conjunto de paquetes. Desde la consola de Ubuntu podéis completar la instalación de estos paquetes con la siguiente secuencia de comandos que deben ser ejecutados de uno en uno.
```shell
sudo dpkg --add-architecture i386
echo "deb http://security.ubuntu.com/ubuntu focal-security main universe" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386
sudo apt-get install libstdc++6:i386 libnspr4-dev:i386
sudo apt-get install zlib1g:i386 libx11-6:i386
sudo apt-get install gedit
sudo apt-get install minicom
```
:::info
Es posible que todos los paquetes, o parte de ellos, ya estén instalados en la distribución de Linux que utilizáis. En el caso de que alguno de los paquetes NO esté instalado, al ejecutar el comando de instalación se solicitará una confirmación mediante el siguiente mensaje, a la que deberemos responder pulsando la tecla Y.
```shell
Do you want to continue [Y/N]
```
:::
</div>
## Parte 2: Instalación del compilador cruzado Bare-C
<div style="text-align: justify">
BCC (*Bare-C Cross Compiler*) es un compilador cruzado para los procesadores de la familia LEON. Este compilador, basado en GCC, permite construir aquellos programas más básicos que no requieran de Sistema Operativo, como el software de arranque (*Boot Software* o BSW) que toma el control de un computador de vuelo tras un reset. La distribución del compilador incluye la biblioteca de C *Newlib standalone* y rutinas de bajo nivel para entrada y salida. La versión 4.2.2 del compilador BCC que utilizaremos en este laboratorio puede descargarse del siguiente enlace: http://www.gaisler.com/anonftp/bcc/bin/linux/sparc-elf-4.4.2-1.0.50.tar.bz2
Una vez descargada esta versión, su instalación comprende los siguientes pasos que deben completarse ejecutando, desde un terminal, los comandos indicados en cada uno de ellos:
#### 2.1 - Mover el archivo descargado a `/opt` y descomprimirlo en ese mismo directorio
```shell
cd /home/inta_pus/Descargas
sudo mv sparc-elf-4.4.2-1.0.50.tar.bz2 /opt
cd /opt
sudo tar xvfj sparc-elf-4.4.2-1.0.50.tar.bz2 -C /opt
```
#### 2.2 - Crear un enlace blando con nombre `sparc-elf` al directorio donde está ubicado el compilador
```shell
sudo ln –s sparc-elf-4.4.2 sparc-elf
```
:::info
En enlace no se podrá crear si ya existe un enlace con el mismo nombre. En ese caso, antes de crear el enlace deberemos **borrar previamente** el enlace existente con el siguiente comando:
```shell
rm sparc-elf
```
:::
</div>
## Parte 3: Instalación del compilador RCC 4.6
<div style="text-align: justify">
El sistema de compilación cruzada RCC (*RTEMS Cross Compiler*) integra un compilador cruzado para los procesadores LEON3, basado en GCC, junto con una distribución del sistema operativo de tiempo real RTEMS. La versión 4.6.6 de RCC que utilizaremos en este laboratorio puede descargarse del siguiente enlace: http://www.gaisler.com/anonftp/rcc/bin/linux/sparc-rtems-4.6.6-gcc-3.2.3-1.0.20-linux.tar.bz2
Una vez descargada esta versión, su instalación comprende los siguientes pasos que deben completarse ejecutando, desde un terminal, los comandos indicados en cada uno de ellos:
#### 3.1 - Mover el archivo descargado a `/opt` y descomprimirlo en ese mismo directorio
```shell
cd /home/inta_pus/Descargas
sudo mv sparc-rtems-4.6.6-gcc-3.2.3-1.0.20-linux.tar.bz2 /opt
cd /opt
sudo tar xvfj sparc-rtems-4.6.6-gcc-3.2.3-1.0.20-linux.tar.bz2 -C /opt
```
#### 3.2 - Crear un enlace blando con nombre `rtems` al directorio donde está ubicado el compilador
```shell
sudo ln –s rtems-4.6 rtems
```
:::info
En enlace no se podrá crear si ya existe un enlace con el mismo nombre. En ese caso, antes de crear el enlace deberemos **borrar previamente** el enlace existente con el siguiente comando:
```shell
rm rtems
```
:::
</div>
## Parte 4: Instalación del simulador TSIM2
<div style="text-align: justify">
El simulador TSIM3 permite simular el comportamiento de un *System On Chip* construido a partir del procesador LEON3 y de controladores de interfaces y dispositivos que se integran en la biblioteca GPL de cores denominada [GRLIB](https://www.gaisler.com/index.php/products/ipcores/soclibrary). Esto permite simular, no sólo la ejecución de instrucciones, sino otras funciones básicas de un computador como el control de las interrupciones, la programación de *Timers* y la transmisión y recepción de datos a través de una UART. TSIM3 es una herramienta profesional que tiene una gran implantación en la industria espacial. La versión de evaluación de este simulador se puede encontrar en la página [https://www.gaisler.com](https://www.gaisler.com), si bien, dado que es una versión que tiene caducidad, y para evitar que durante las prácticas caduque, vamos a utilizar una versión específica ejecutada empleando la utilidad *faketime* que nos permite fijar la fecha de ejecución. Para ello, nos descargaremos la versión 3.1.9 del siguiente enlace: https://download.gaisler.com/products/TSIM3/bin/tsim-eval/tsim-eval-3.1.9.tar.gz y el lanzador [tsim-launch](https://universidaddealcala-my.sharepoint.com/:u:/g/personal/o_rodriguez_uah_es/ERzr87wS2ihLnHBvxUEgd8UBORJax2GWJy6RzFSlc9StNg?e=JM9b4q) que nos permite emular una fecha de ejecución. Una vez realizadas las descargas, procederemos a la instalación mediante los siguientes pasos que deben completarse ejecutando, desde un terminal, los comandos indicados en cada uno de ellos:
#### 4.1 - Mover los archivo descargados a `/opt` y descomprimirlos en ese mismo directorio
```shell
cd /home/atcsol/Descargas
sudo mv tsim-eval-3.1.9.tar.gz /opt
sudo mv tsim-launch.tar.gz /opt
cd /opt
sudo tar xvfz tsim-eval-3.1.9.tar.gz
sudo tar xvfz tsim-launch.tar.gz
```
#### 4.2 - Crear un enlace blando con el nombre `tsim` al lanzador
```shell
sudo ln –s tsim-launch/tsim/linux-x64 tsim
```
#### 4.3 - Instalar la utilidad faketime
```shell
sudo apt-get install faketime
```
</div>
## Parte 5: Instalación de la herramienta de depuración GRMON3
<div style="text-align: justify">
La herramienta de depuración GRMON3 nos permite descargar y depurar programas sobre una placa que integre el procesador LEON3. En esta asignatura utilizaremos la placa Nexys A7 basada en la FPGA Arty A7-100T de Xilinx sobre la que se ha sintetizado un SoC que integra un LEON3 y diversos controladores de interfaces y dispositivos de la biblioteca [GRLIB](https://www.gaisler.com/index.php/products/ipcores/soclibrary), ya mencionada anteriormente. La siguiente figura muestra la placa de desarrollo Nexys-A7:
<br/>
<img width="45%" src="https://hackmd.io/_uploads/BJYkTAXca.png"
style="display: block; margin: auto"></img>
Para poder controlar la tarjeta es necesario que nos descarguemos e instalemos el driver [digilent.adept.runtime_2.26.1-amd64.deb](https://universidaddealcala-my.sharepoint.com/:u:/g/personal/o_rodriguez_uah_es/Efxt12sF5VxLhEFPg3KdN3UB6AIy8ORdI8DL-Fdwgq7_dw?e=htLd8x). El proceso de instalación se inicia pulsando con el botón derecho del ratón sobre el archivo descargado de forma que se despliegue el menú contextual tal como aparece en la siguiente figura:
<img width="45%" src="https://hackmd.io/_uploads/SJtlUJ4q6.png"
style="display: block; margin: auto"></img>
Seleccionando la opción `Abrir con Instalación de software`se abre la siguiente ventana que nos permite completar la instalacíón del driver pulsando en *Instalar*.
<img width="45%" src="https://hackmd.io/_uploads/HkNXwJE56.png"
style="display: block; margin: auto"></img>
Una vez instalado el driver, procederemos a descargarnos la última versión de evaluación de GRMON3 con el siguiente enlace: https://download.gaisler.com/anonftp/grmon/grmon-eval-4.0.2.tar.gz. Tras descargarse el archivo, procederemos con los siguientes pasos de la instalación que deben completarse ejecutando, desde un terminal, los comandos indicados en cada uno de ellos:
#### 5.1 - Mover los archivo descargados a `/opt` y descomprimirlos en ese mismo directorio
```shell
cd /home/atcsol/Descargas
sudo mv grmon-eval-4.0.2.tar.gz /opt
cd /opt
sudo tar xvfz grmon-eval-4.0.2.tar.gz
```
#### 5.2 - Crear un enlace blando con el nombre `grmon` al directorio donde se encuentran los binarios de la herramienta de depuración
```shell
sudo ln -s grmon-eval-4.0.2/linux/bin64 grmon
```
:::info
En enlace no se podrá crear si ya existe un enlace con el mismo nombre. En ese caso, antes de crear el enlace deberemos **borrar previamente** el enlace existente con el siguiente comando:
```shell
rm grmon
```
:::
</div>
## Parte 6: Configuración del PATH
<div style="text-align: justify">
Para que tanto los compiladores como las aplicaciones TSIM2 y GRMON3 puedan ejecutarse independientemente del directorio de trabajo del usuario, es necesario incluir en el PATH de búsqueda los directorios donde están instaladas de la siguiente forma:
```c=
PATH="/opt/sparc-elf/bin:$PATH"
PATH="/opt/rtems/bin:$PATH"
PATH="/opt/tsim:$PATH"
PATH="/opt/grmon:$PATH"
```
Añadiendo esas líneas al final del archivo `.profile` que se encuentra en vuestro directorio de usuario `/home/inta_pus`, lograréis que en cada inicio de sesión con vuestro usuario quede el PATH correctamente configurado. Esta edición la podéis hacer con cualquier editor de texto. Los siguientes comandos permiten hacerlo con el editor gedit de fácil utilización.
```shell
cd /home/inta_pus
gedit .profile
```
En la siguiente figura se muestra la edición del archivo .profile con gedit tal como debería quedar (revisar que las comillas son correctas comprobando el resaltado de texto de gedit).
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/r124-Tr5a.png"
style="display: block; margin: auto"></img>
:::info
Antes proseguir, cerrad vuestra sesión actual y volved a iniciar una nueva sesión de forma que se actualice el PATH y se puedan utilizar las aplicaciones instaladas. Además, debéis aseguraros que vuestra configuración de la máquina virtual tiene configurada la compatibilidad USB a 3.1 tal como aparece en la figura siguiente
:::

## Parte 7: Creación de un Proyecto Eclipse para LEON3
<div style="text-align: justify">
Una vez instaladas todas las herramientas es posible crear nuevos proyectos con Eclipse para el procesador LEON3. Para ello, una vez ejecutado Eclipse, al igual que en asignaturas anteriores, utilizaréis la opción `New C/C++ Project` seleccionando el tipo de proyecto `C Managed Build` tal como aparece en la siguiente figura:
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/S17GITB9T.png"
style="display: block; margin: auto"></img>
<div style="text-align: justify">
A continuación, se determinará el nombre del proyecto (`prac0_obdh_uart_23_24`) y la toolchain a utilizar, que será del tipo `Cross GCC` para poder indicar una compilación cruzada.
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/BkEXCarqa.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Después se seleccionarán las dos configuraciones `Debug y Release` que se desean desplegar tal como aparece en la siguiente figura.
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/By_HyCScp.png"
style="display: block; margin: auto"></img>
<div style="text-align: justify">
Y se fijará como prefijo de compilación `sparc-elf-`, y como PATH de compilación `/opt/sparc-elf/bin` tal como se muestra en la figura.
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/SJcChaB5T.png"
style="display: block; margin: auto"></img>
## Tarea 1 a realizar: Proyecto para LEON3 y depuración sobre TSIM2
<div style="text-align: justify">
La primera tarea a realizar consiste en completar el proyecto `prac0_obdh_uart_23_24` con la organización de directorios y archivos que aparece en la siguiente figura:
</div>
<br/>
<img width="45%" src="https://hackmd.io/_uploads/HJ04eArcT.png"
style="display: block; margin: auto"></img>
<div style="text-align: justify">
Los archivos que forman el proyecto, salvo el `main`, están disponibles en el siguiente enlace [prac0_obdh_uart_23_24_files](https://universidaddealcala-my.sharepoint.com/:u:/g/personal/o_rodriguez_uah_es/EXe-mbh1XRJJqSA1IweTmYkBj2GBQLyfHksj7KBbNRigRA?e=GvBWCF)
Para que el proyecto compile necesitáis configurar el directorio de búsqueda de los includes seleccionando el menú contextual *Properties* sobre el proyecto tal como se muestra en la siguiente figura:
<img width="45%" src="https://hackmd.io/_uploads/HJW_jPLca.png"
style="display: block; margin: auto"></img>
Dentro de *Properties* tendréis que acceder a los *Settings* de *C/C++ Build* y configurar los *include paths* del *Cross GCC Compiler*
<img width="85%" src="https://hackmd.io/_uploads/rJ5RiPLc6.png"
style="display: block; margin: auto"></img>
Añadiendo un nuevo *path*, se seleccionará empleando el botón *Workspace* un path relativo al directorio del proyecto que os permite exportarlo e importarlo independientemente de dónde esté instalado Eclipse. La siguiente figura muestra cómo os debe quedar el path tras seleccionar el directorio *include* del proyecto desde la opción Workspace
<img width="85%" src="https://hackmd.io/_uploads/SJTSsPUc6.png"
style="display: block; margin: auto"></img>
Debéis hacer lo mismo en la sección *Cross GCC Assembler* ya que en este proyecto también hay archivos en ensamblador.
Una vez configurado el *path* de búsqueda de los archivos de cabecera (*includes*), tendremos que crear el archivo `main.c` en el raiz del proyecto. El archivo `main.c`, que se muestra a continuación, configura la GRLIB-UART del SoC basado en LEON3 para disparar una interrupción (la interrupción externa 2) cada vez que se recibe un byte por la UART. El manejador de la interrupción simplemente lee el byte recibido (leon3_getchar()), sin hacer nada con él, e incrementa un contador de bytes recibidos (`rx_byte_counter`). El bucle final del `main`, por su parte, detecta si se ha producido una interrupción comprobando cualquier cambio en esta variable (`if((byte_counter)!=rx_byte_counter){ `), y responde al cambio enviando un punto '.' por la UART con `printf`, ya que en este procesador la salida estándar está asociada a la UART.
```c=
#include "leon3_ev_handling.h"
#include "leon3_hw_irqs.h"
#include "leon3_uart.h"
#include <stdio.h>
uint32_t rx_byte_counter = 0;
void uart_rx_handler(void) {
leon3_getchar(); //Leo el caracter para vaciar el buffer
rx_byte_counter++;
}
int main() {
uint8_t byte_counter=0;
printf("\nInit UART Example\n");
//Instalar como manejador del trap 0x83 la rutina
// que habilita las interrupciones
leon3_set_trap_handler(0x83, leon3_trap_handler_enable_irqs);
//Instalar el manejador del trap que 0x83 la rutina
// que deshabilita las interrupciones
leon3_set_trap_handler(0x84, leon3_trap_handler_disable_irqs);
//Deshabilitar las interrupciones
leon3_sys_call_disable_irqs();
//Enmascarar todas las interrupciones, sólo desenmascaremos aquellas que tenemos manejadas.
leon3_mask_all_irqs();
//Instalar la función button_handler como
// manejador de usuario de la interrupción de nivel 4
leon3_install_user_hw_irq_handler(2, uart_rx_handler);
//Configuro UART para disparar interrupciones al recibir un byte
leon3_uart_ctrl_rx_irq_enable();
leon3_uart_ctrl_rx_enable();
//Desenmascarar la interrupción de nivel 2
leon3_unmask_irq(2);
//Habilitar las interrupciones
leon3_sys_call_enable_irqs();
//Sacamos por los displays un incremento
do {
//Detecta botón pulsado
if((byte_counter)!=rx_byte_counter){
printf(".");
//Inicio Sección Crítica entre IRQ 2 handler y main
leon3_mask_irq(2);
byte_counter=rx_byte_counter;
//Fin Sección Crítica entre IRQ 2 handler y main
leon3_unmask_irq(2);
}
} while (1);
return 0;
}
```
</div>
<br/>
<div style="text-align: justify">
Una vez que el programa compila sin errores, se podrá ejecutar tanto en el simulador TSIM2, como en la placa Nexsys-A7 utilizando diferentes Configuraciones de Depuración (*Debug Configurations*) sobre el mismo proyecto.
Para crear una nueva Configuración de Depuración se utiliza el menú contextual del proyecto (botón derecho sobre el proyecto) tal como aparece en la siguiente figura:
</div>
<br/>
<img width="85%" src="https://hackmd.io/_uploads/ry-pHRr96.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
El menú nos lleva a la vista de depuración (*Debug*) de Eclipse, y desde allí, podemos crear una nueva Configuración de Depuración Hardwarwe basada en GDB (*GDB Hardware Debugging*) eligiendo la opción del menú contextual (botón derecho) *New Configuration*.
</div>
<br/>
<img width="65%" src="https://hackmd.io/_uploads/rJwaB0S5a.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
La Configuración de Depuración la vamos a denominar `prac0_obdh_uart_23_24 Debug TSIM2`, tal como aparece en la siguiente figura en la pestaña Main.
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/HJcVKABqT.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
A continuación, accederemos a la pestaña *Debugger* de la Configuración de Depuración para determinar el comando GDB a utilizar (`sparc-elf-gdb`), y la forma con la que GDB se conecta al *Remote Target* TSIM2. Para esta configuración elegiremos las opciones `JTAG Device = Generig TCP/IP` y *GDB Connection String = localhost:1234*. La siguiente figura muestra estas opciones necesarias para cargar y depurar programas sobre TSIM2.
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/HyWZYAS5p.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Antes de pulsar el botón *Debug* para iniciar la depuración, deberemos tener arrancado TSIM2. Para eso abriremos un nuevo terminal y, desde línea de comando, ejecutaremos:
</div>
```shell
tsim-leon3
```
<div style="text-align: justify">
La ejecución correcta hará que aparezca la información sobre JTAG y una línea de comandos interna de TSIM2 indicada con tsim>.
</div>

<div style="text-align: justify">
Al introducir en la línea interna el comando gdb le indicamos a TSIM2 a que abra un puerto para que GDB se conecte a través de él y pueda descargar y depurar programas. Tal como vemos en la siguiente figura el puerto que abre TSIM2 es 1234.
</div>

<br/>
<div style="text-align: justify">
Ahora ya podemos volver a Eclipse y pulsar el botón *Debug* para iniciar la depuración.
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/HyWZYAS5p.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Una vez iniciada la depuración, podemos pulsar teclas dentro de la consola de TSIM2 y veremos como aparecen tantos puntos como teclas pulsadas hasta que la depuración finaliza dado que la versión de evaluación tiene un número de ciclos máximo de ejecución.
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/rJ3Uk1Iq6.png"
style="display: block; margin: auto"></img>
<br/>
## Tarea 2 a realizar: Configuración de Depuración para Nexys-A7
<div style="text-align: justify">
La siguiente tarea a realizar va a consistir en crear una nueva Configuración de Depuración para **el mismo proyecto **`prac0_obdh_uart_23_24` que nos permite trabajar con la placa Nexys-A7 empleando GRMON3 como herramienta para cargar y depurar programas. Para ello, primero cerraremos TSIM2 con la orden `quit` y nos aseguraremos que la anterior depuración ha terminado (Ctrl +F2 o pulsando en el botón Terminate).
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/ByBOGyLca.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Después volveremos a la ventana *Debug Configurations* (Accesible desde el menú *Run* y también desde el botón con el icono de la cucaracha) para crear una nueva Configuración de Depuración para **el mismo proyecto **`prac0_obdh_uart_23_24`. Una vez allí, repetimos un paso que ya dimos anteriormente para crear una nueva Configuración de Depuración Hardware basada en GDB (*GDB Hardware Debugging*) eligiendo la opción del menú contextual (botón derecho) *New Configuration*.
</div>
<br/>
<img width="85%" src="https://hackmd.io/_uploads/rJwaB0S5a.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Esta nueva Configuración de Depuración la vamos a denominar `prac0_obdh_uart_23_24 Debug NEXYS A7`, tal como aparece en la siguiente figura. Los cambios con respecto a la anterior `prac0_obdh_uart_23_24 Debug TSIM2`, además de en el nombre, se localizan en la configuración de la pestaña *Debugger*, en la que, si bien determinaremos el mismo comando GDB a utilizar (`sparc-elf-gdb`) y la misma forma con la que GDB se conecta al *Remote Target* con `JTAG Device = Generig TCP/IP`, haremos un cambio en el puerto indicando *GDB Connection String = localhost:2222*. La siguiente figura muestra estas opciones necesarias para cargar y depurar programas sobre la Nexys-A7 a través de GRMON3.
</div>
<img width="85%" src="https://hackmd.io/_uploads/r1aPNyUc6.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Antes de proceder a la depuración, es necesario conectar la placa Nexys-A7 al puerto USB de la computadora, y ejecutar GRMON3 con el siguiente telecomando desde una consola.
</div>
```shell
grmon -digilent -freq 70
```
<div style="text-align: justify">
La ejecución correcta de GRMON3 mostrará los distintos IP-Cores que integra el SoC de la Nexys-A7 tal como muestra la siguiente figura:
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/ByU_NRSqp.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Dentro de la línea de comandos interna de GRMON3 es necesario calibrar las memorias ddr2 que integra mediante el siguiente comando:
```shell
grmon3> ddr2delay scan
```
Lo que provocará el siguiente report de ejecución de la calibración:
</div>
<br/>
<img width="100%" src="https://hackmd.io/_uploads/SyXj_J85p.png"
style="display: block; margin: auto"></img>
<br/>
<div style="text-align: justify">
Tras la calibración deberemos salir de GRMON3 y volver a entrar para que esa calibración se aplique. La salida la haremos con `quit`.
```shell
grmon3> quit
```
Y una vez de nuevo en la consola del terminal repetimos el comando anterior para ejecutar de nuevo GRMON3
```shell
grmon -digilent -freq 70
```
Para terminar, dentro de GRMON3 introducimos el comando gdb para que GRMON3 abra un puerto para que GDB se conecte a través de él y pueda descargar y depurar programas. Tal como vemos en la siguiente figura el puerto que abre GRMON3 es 2222, que es el que habíamos utilizado en la opción *GDB Connection String = localhost:2222* de la Configuración de Depuración.

Si bien ya sería posible depurar el programa, necesitamos una herramienta para transmitir los caracteres a la Nexys-A7 por el puerto serie y monitorizar los que la Nexys-A7 envía. Esta herramienta es Minicom, que ya tenéis instalada en vuestra máquina virtual. Para ejecutarla basta con que introduzcamos desde un terminal el comando
```shell
sudo minicom -s
```
A continuación, con Control+A Z se puede acceder a la página de ayuda:

Y desde ahí podemos utilizar el comando 'O' para configurar Minicom. Específicamente, la configuración que nos interesa es la del *Serial port* que seleccionamos del menú:

Nos aseguraremos que la configuración de Minicom utiliza como *Serial Device* `/dev/ttyUSB1` (puede ser también `/dev/ttyUSB0 o /dev/ttyUSB2`, es necesario ejecutar en consola el siguiente comando para asegurarnos de cuál es el dispositivo asociado a la UART de la Nexys-A7):
```shell
ls /dev
```
Además del *Serial Device*, debemos asegurarnos que la configuración Bps/Par/Bits es 38400 8N1 de la opción E (transmisión a 38400 bits por segundo con 8 bits de datos, sin bit de paridad y con 1 bit de parada), y que en las opciones F y G el control de flujo está deshabilitado en ambas tal como muestra la siguiente figura:

Finalmente, guardaremos la configuración como configuración por defecto para mantenerla en futuras ejecuciones.

Introduciendo mediante el teclado cualquier tipo de caracteres veremos en Minicom una salida como esta que indica que el programa se ejecuta correctamente:

## Tarea 3 a realizar: Proyecto de uso de la GPIO de Nexys-A7
<div style="text-align: justify">
La última tarea de la práctica consiste en realizar un nuevo proyecto eclipse para LEON3 en el que se usará la GPIO de la placa Nexys-A7 mediante la función main que se prorporciona a continuación y los archivos que podéis descargar de [prac0_obdh_gpio_nexys_23_24_files](https://universidaddealcala-my.sharepoint.com/:u:/g/personal/o_rodriguez_uah_es/Eai8if8H8xlMnYXR_pC9a-8BogtByVvjW9AAxvLgAgM1jw?e=7ZAiF7). La organización que debe tener el proyecto es la de la siguiente figura:

Para completarla se deberá crear una única Configuración para Depuración que emplee, en la opción de *Debugger*, la configuración del *Remote Target* del *GDB Connection String = localhost:2222*, ya que sólo desplegaremos sobre la Nexys-A7, puesto que TSIM2 no es capaz de emular de ninguna manera la GPIO de la Nexys-A7 que se utiliza en este ejemplo. Concretamente, lo que hace el programa es asociar una interrupción al pulsado de cualquiera de los 5 botones centrales de la placa, y mostrar por los displays de 7 segmentos la cuenta de las pulsaciones realizadas. Tendréis que utilizar GRMON3 para conectaros a la placa Nexys-A7, al igual que en último ejercicio del anterior apartado. Podéis utilizar también Minicom ya que el programa envía algunos mensajes a través del puerto serie que podrían seros de utilidad.
```c=
#include "leon3_ev_handling.h"
#include "leon3_hw_irqs.h"
#include "nexys_gpio_drv.h"
#include <stdio.h>
uint8_t current_led = 0;
uint8_t displays7seg_value[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
//Clear displays values
void clear_displays7segs_values(void) {
uint8_t i;
for (i = 0; i < 8; i++)
displays7seg_value[i] = 0;
}
//Define next value for displays
void next_displays7segs_values(void) {
uint8_t end = 0;
uint8_t index = 7;
while (!end) {
if (displays7seg_value[index] < 9) {
displays7seg_value[index]++;
end = 1;
} else {
displays7seg_value[index] = 0;
if (0 == index) {
clear_displays7segs_values();
end = 1;
} else {
index--;
}
}
}
}
void button_handler(void) {
current_led++;
if (10 == current_led)
current_led = 0;
next_displays7segs_values();
}
int main() {
uint8_t i;
uint8_t led = 0;
uint8_t displays7seg_local_copy[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
printf("\nInit GPIO NEXYS EXAMPLE\n");
nexys_srg_gpio_init_buttons_switches();
nexys_srg_gpio_init_leds_7segs_displays();
//Instalar como manejador del trap 0x83 la rutina
// que habilita las interrupciones
leon3_set_trap_handler(0x83, leon3_trap_handler_enable_irqs);
//Instalar el manejador del trap que 0x83 la rutina
// que deshabilita las interrupciones
leon3_set_trap_handler(0x84, leon3_trap_handler_disable_irqs);
//Deshabilitar las interrupciones
leon3_sys_call_disable_irqs();
//Enmascarar todas las interrupciones, sólo desenmascaremos aquellas que tenemos manejadas.
leon3_mask_all_irqs();
//Instalar la función button_handler como
// manejador de usuario de la interrupción de nivel 4
leon3_install_user_hw_irq_handler(4, button_handler);
//Configura los 6 botones para que interrumpan al ser pulsados
for (i = 0; i < 6; i++) {
nexys_srg_gpio_config_button_irq(i, irq_active_low, irq_edge);
nexys_srg_gpio_enable_button_irq(i);
}
//Enciende el primer LED
nexys_srg_gpio_turn_on_led(current_led);
//Desenmascarar la interrupción de nivel 4
leon3_unmask_irq(4);
//Habilitar las interrupciones
leon3_sys_call_enable_irqs();
printf("Pulsa Boton para incrementar cuenta\n");
//Sacamos por los displays un incremento
do {
int first_digit = 0;
//Valor de los displays
for (i = 0; i < 8; i++) {
if (displays7seg_local_copy[i] != 0)
first_digit = 1;
if (first_digit)
nexys_srg_gpio_set_7seg_digit(i,
displays7seg_local_copy[i]);
}
//Detecta botón pulsado
if ((led) != current_led) {
nexys_srg_gpio_turn_off_led(led);
nexys_srg_gpio_turn_on_led(current_led);
printf(".");
led = current_led;
//Inicio Sección Crítica entre IRQ 4 handler y main
leon3_mask_irq(4);
for (i = 0; i < 8; i++) {
displays7seg_local_copy[i] = displays7seg_value[i];
}
//Fin Sección Crítica entre IRQ 4 handler y main
leon3_unmask_irq(4);
}
} while (1);
return 0;
}
```
</div>