Documentos de Académico
Documentos de Profesional
Documentos de Cultura
01/09/2018
Agenda
1 Entorno de desarrollo
Cómo desarrollamos aplicaciones
2 El hardware de la CIAA
Caracterı́sticas de la CIAA
3 Desarrollo de software
Aplicaciones para sistemas embebidos
4 Un proyecto de software
Estructura
Linker script
Rutina de inicialización
5 Depuración
Simulación y depuración
jtag
OpenOCD
En un PC las herramientas suelen estar pre configuradas para desarrollar aplicaciones de escritorio.
¿Pero en un sistema embebido?
http://www.proyecto-ciaa.com.ar/devwiki/doku.php?id=desarrollo:edu-ciaa:edu-ciaa-nxp
Software
En lo que a desarrollo de software respecta, las aplicaciones para sistemas embebidos requieren de
utilizar cross compiling.
Software
En lo que a desarrollo de software respecta, las aplicaciones para sistemas embebidos requieren de
utilizar cross compiling.
El cross compiling (o compilación cruzada) es el proceso por el cual se construyen aplicaciones
para una arquitectura de software o hardware desde una arquitectura diferente.
Software
En lo que a desarrollo de software respecta, las aplicaciones para sistemas embebidos requieren de
utilizar cross compiling.
El cross compiling (o compilación cruzada) es el proceso por el cual se construyen aplicaciones
para una arquitectura de software o hardware desde una arquitectura diferente.
Esta es una caracterı́stica particular y no todos los compiladores la soportan. En el caso particular
de GCC, permite generar aplicaciones binarias para diversos núcleos ARM (entre otros Cortex M0,
M3, M4, M7, A7, A12).
a
https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/ARM-Options.html#ARM-Options
Software
En lo que a desarrollo de software respecta, las aplicaciones para sistemas embebidos requieren de
utilizar cross compiling.
El cross compiling (o compilación cruzada) es el proceso por el cual se construyen aplicaciones
para una arquitectura de software o hardware desde una arquitectura diferente.
Esta es una caracterı́stica particular y no todos los compiladores la soportan. En el caso particular
de GCC, permite generar aplicaciones binarias para diversos núcleos ARM (entre otros Cortex M0,
M3, M4, M7, A7, A12).
Si bien muchas opciones básicas de compilación son válidas para todas las arquitecturas (-O2, -O0,
-g, -c, etc.), aparecen opciones especı́ficas para cada arquitectura. a .
a
https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/ARM-Options.html#ARM-Options
Software
En lo que a desarrollo de software respecta, las aplicaciones para sistemas embebidos requieren de
utilizar cross compiling.
El cross compiling (o compilación cruzada) es el proceso por el cual se construyen aplicaciones
para una arquitectura de software o hardware desde una arquitectura diferente.
Esta es una caracterı́stica particular y no todos los compiladores la soportan. En el caso particular
de GCC, permite generar aplicaciones binarias para diversos núcleos ARM (entre otros Cortex M0,
M3, M4, M7, A7, A12).
Si bien muchas opciones básicas de compilación son válidas para todas las arquitecturas (-O2, -O0,
-g, -c, etc.), aparecen opciones especı́ficas para cada arquitectura. a .
GCC puede ser compilado desde su código fuente como un cross compilador, estableciendo las
arquitecturas host y target, pero suele ser conveniente utilizar versiones empaquetadas para cada
arquitectura.
a
https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/ARM-Options.html#ARM-Options
La librerı́a estándard de C
El lenguaje C tiene un léxico constituido por 32 palabras claves, que a partir de su sintaxis conforman
el lenguaje.
Consideremos un programa simple:
La librerı́a estándard de C
Existen diferentes librerı́as que pueden proveer las funcionalidades de la librerı́as estándar del len-
guaje C. Entre ellas:
GNU libc : Versión incluida en GCC portada para variedad de sistemas.
dietlibc : Diseñada para ser una librerı́a de reducido tamaño para sistemas embebidos utili-
zando enlazado estático.
La librerı́a estándard de C
Existen diferentes librerı́as que pueden proveer las funcionalidades de la librerı́as estándar del len-
guaje C. Entre ellas:
GNU libc : Versión incluida en GCC portada para variedad de sistemas.
dietlibc : Diseñada para ser una librerı́a de reducido tamaño para sistemas embebidos utili-
zando enlazado estático.
µClibc: Diseñada para sistemas embebidos basados en linux utilizando enlazado dinámico.
La librerı́a estándard de C
Existen diferentes librerı́as que pueden proveer las funcionalidades de la librerı́as estándar del len-
guaje C. Entre ellas:
GNU libc : Versión incluida en GCC portada para variedad de sistemas.
dietlibc : Diseñada para ser una librerı́a de reducido tamaño para sistemas embebidos utili-
zando enlazado estático.
µClibc: Diseñada para sistemas embebidos basados en linux utilizando enlazado dinámico.
newlib: mantenida por Red Hat, es una librerı́a de enlazado estático fácilmente adaptable a
sistemas embebidos.
La librerı́a estándard de C
Existen diferentes librerı́as que pueden proveer las funcionalidades de la librerı́as estándar del len-
guaje C. Entre ellas:
GNU libc : Versión incluida en GCC portada para variedad de sistemas.
dietlibc : Diseñada para ser una librerı́a de reducido tamaño para sistemas embebidos utili-
zando enlazado estático.
µClibc: Diseñada para sistemas embebidos basados en linux utilizando enlazado dinámico.
newlib: mantenida por Red Hat, es una librerı́a de enlazado estático fácilmente adaptable a
sistemas embebidos.
Nota: el compilador debe soportar la librerı́a estándar utilizada y, en general, la librerı́a debe ser
compilada durante el proceso de construcción del compilador.
Estructura de un proyecto
La estructura de un proyecto de software para la EDU-CIAA NXP para el desarrollo de una aplicación
baremetal requiere de un conjunto de archivos para realizar tareas especı́ficas:
El código de la aplicación: dependerá del problema que se desea abordar. Es una implementa-
ción particular.
lpcOpen: drivers provistos por el fabricante para el control de los diferentes periféricos.
Estructura de un proyecto
La estructura de un proyecto de software para la EDU-CIAA NXP para el desarrollo de una aplicación
baremetal requiere de un conjunto de archivos para realizar tareas especı́ficas:
El código de la aplicación: dependerá del problema que se desea abordar. Es una implementa-
ción particular.
lpcOpen: drivers provistos por el fabricante para el control de los diferentes periféricos.
Estructura de un proyecto
La estructura de un proyecto de software para la EDU-CIAA NXP para el desarrollo de una aplicación
baremetal requiere de un conjunto de archivos para realizar tareas especı́ficas:
El código de la aplicación: dependerá del problema que se desea abordar. Es una implementa-
ción particular.
lpcOpen: drivers provistos por el fabricante para el control de los diferentes periféricos.
Estructura de un proyecto
La estructura de un proyecto de software para la EDU-CIAA NXP para el desarrollo de una aplicación
baremetal requiere de un conjunto de archivos para realizar tareas especı́ficas:
El código de la aplicación: dependerá del problema que se desea abordar. Es una implementa-
ción particular.
lpcOpen: drivers provistos por el fabricante para el control de los diferentes periféricos.
Estructura de un proyecto
La estructura de un proyecto de software para la EDU-CIAA NXP para el desarrollo de una aplicación
baremetal requiere de un conjunto de archivos para realizar tareas especı́ficas:
El código de la aplicación: dependerá del problema que se desea abordar. Es una implementa-
ción particular.
lpcOpen: drivers provistos por el fabricante para el control de los diferentes periféricos.
Linker script
Por comodidad suelen utilizarse varios archivos como linker scripts. En nuestro caso, uno es utilizado
para establecer los nombres de los segmentos y sus direcciones (mem.ld).
MEMORY
{
flash ( rx ) : ORIGIN = 0 x1a000000 , LENGTH = 0 x80000 /* 512 K bytes */
stack ( rw ) : ORIGIN = 0 x10000000 , LENGTH = 0 x8000 /* 32 K bytes */
}
Linker script
En un segundo archivo se establece la correlación entre segmentos y su área de alojamiento
(areas.ld algunas lı́neas han sido omitida por razones de espacio).
ENTRY ( ResetISR ) . text : ALIGN (4)
{
SECTIONS *(. text *)
{ *(. rodata . rodata .*)
. text : ALIGN (4) *(. constdata . constdata .*)
{ . = ALIGN (4);
FILL (0 xff ) PROVIDE ( etext = .);
PROVIDE ( stext = .); PROVIDE ( startFlashFs = .);
_ _ v e c t o r s _ st art __ = ABSOLUTE (.) ; *(. flashFs *)
KEEP (*(. isr_vector )) PROVIDE ( endFlashFs = .);
. = ALIGN (4) ; } > flash
_ _ s e c t i o n _ t a b l e _ s t a r t _ = .;
_ _ d a t a _ s e c t i o n _ t a b l e _ = .; . noinit ( NOLOAD ): ALIGN (4)
LONG ( LOADADDR (. data )); {
LONG ( ADDR (. data )); _noinit = .;
LONG ( SIZEOF (. data )); *(. noinit *)
_ _ d a t a _ s e c t i o n _ t a b l e _ e n d _ = .; _end_noinit = .;
_ _ b s s _ s e c t i o n _ t a b l e _ = .; _vStackBottom = .;
LONG ( ADDR (. bss )); } > stack
LONG ( SIZEOF (. bss ));
_ _ b s s _ s e c t i o n _ t a b l e _ e n d _ = .; _vStackTop = __top_stack ;
_ _ s e c t i o n _ t a b l e _e n d = . ; PROVIDE ( _sStack = _vStackTop );
*(. after_vectors *) PROVIDE ( _eStack = _vStackBottom );
} > flash }
Construcción: Compilación
El proceso de construcción de la aplicación se llevará adelante compilando y posteriormente en-
lazando la aplicación. A modo informativo, las opciones de compilación utilizadas para construir
aplicaciones para Cortex-M4 son:
CFLAGS = - Wall - fdata - sections - ffunction - sections \
- mcpu = cortex - m4 - mthumb - mfpu = fpv4 - sp - d16 - mfloat - abi = softfp \
- DCORE_M4 - Dchip_lpc43xx - DNO_BOARD_LIB - D__USE_LPCOPEN \
- D__LPC43XX__ - D__CODE_RED - D_GNU_SOURCE - I$ ( BASEPATH )/ inc \
- I$ ( INCBASEDIR ) - I$ ( BASEPATH )/ cortex - m4 / inc \
- I$ ( BASEPATH )/ lpc / config_43xx - I$ ( BASEPATH )/ lpc / inc
Nota: La opción -D permite definir una constante simbólica desde la lı́nea de invocación al compi-
lador.
Compilación: enlazado
El proceso de enlazado puede realizarse de dos maneras: invocando directamente al enlazador de
GNU (arm-none-eabi-ld) o, invocándolo indirectamente a través de GCC.
export LDFLAGS = - static -fno - builtin - mcpu = cortex - m4 \
- mthumb - mfpu = fpv4 - sp - d16 - mfloat - abi = softfp \
-Wl , - gc - sections - Xlinker - Tld / libs . ld - Tld / mem . ld \
- Tld / areas . ld - L$ ( OUTDIR )/ lib
A partir de esto tendremos un archivo binario, ejecutable, ‘elf’. Según las herramientas utilizadas
puede ser necesario convertir a otros formatos, por ejemplo binario (imagen plana) o intel hex. Para
esto es posible utilizar la herramienta objcopy:
arm - none - eabi - objcopy -O binary $ ( OUTDIR )/ firmware . elf $ ( OUTDIR )/ firmware . bin
arm - none - eabi - objcopy -O ihex $ ( OUTDIR )/ firmware . elf $ ( OUTDIR )/ firmware . hex
Simulación y Depuración
¿Cuando ejecutamos una aplicación paso a paso? Estamos simulando la ejecución de la
aplicación?
¿Es posible simular un sistema embebido?
Existe la posibilidad de simular un sistema embebido, pero requiere la construcción de la es-
tructura del dispositivo de interés. Uno de los simuladores más utilizados para este fin es QEmu
(https://www.qemu.org/).
Dependiendo del fabricante del dispositivo utilizado es la forma en la que se produce la interconexión
electrónica entre el software de depuración y el dispositivo embebido.
Más allá de la tecnologı́a utilizada, el proceso de depuración incluye la programación del firmware
en el microcontrolador y la ejecución controlada del mismo desde una interfaz de desarrollo.
Cuando se trabaja con interfaces de hardware comerciales, se diseñan para un dispositivo particular
(microcontrolador, FPGA, etc.) y un software de desarrollo.
OpenOCD es una desarrollo realizado por Dominic Rath, como tesis de diplomatura y tiene como
objetivo ser una interfase de software a diferentes tipos de adaptadores jtag para realizar tareas de
programación y depuración de sistemas embebidos.
Originalmente tuvo por objetivo los núcleos ARM7 y ARM9 pero desde el 2005, ha incorporado
otros dispositivos.
FT2232 en la EDU-CIAA
FT2232 en la EDU-CIAA
Utilizando OpenOCD
OpenOCD utiliza un archivo de configuración donde se describen diferentes caracterı́sticas del sis-
tema embebido. Entre ellas, la cadena de identificación del dispositivo y la distribución de memoria.
interface ftdi
ftdi_vid_pid 0 x0403 0 x6010
ftdi_channel 0
ft d i _ l ay o u t _ i n it 0 x0708 0 xFFFB
adapter_khz 2000
set _CHIPNAME lpc4337
set _M4_JTAG _TAPID 0 x4ba00477
set _M0_JTAG _TAPID 0 x0ba01477
jtag newtap $_CHIPNAME m4 - irlen 4 - ircapture 0 x1 - irmask 0 xf - expected - id $_M4_JTAG_TAPID
jtag newtap $_CHIPNAME m0 - irlen 4 - ircapture 0 x1 - irmask 0 xf - expected - id $_M0_JTAG_TAPID
target create $_CHIPNAME . m4 cortex_m - chain - position $_CHIPNAME . m4
target create $_CHIPNAME . m0 cortex_m - chain - position $_CHIPNAME . m0
set _WORKAREASIZE 0 x8000
$_CHIPNAME . m4 configure - work - area - phys 0 x10000000 - work - area - size $_WORKAREASIZE
set _FLASHNAME $_CHIPNAME . flash
flash bank $_FLASHNAME lpc2000 0 x1a000000 0 x80000 0 0 $_CHIPNAME . m4 \
lpc4300 96000 calc_checksum
set _FLASHNAMEB $_CHIPNAME . flashb
flash bank $_FLASHNAMEB lpc2000 0 x1b000000 0 x80000 0 0 $_CHIPNAME . m4 \
lpc4300 96000 calc_checksum
reset_config none
cortex_m reset_config vectreset
targets $_CHIPNAME . m4
Extraı́do del proyecto CIAA, realizado por Juan Cecconi
Utilizando OpenOCD
Al invocar a OpenOCD debe indicarse el archivo de configuración a utilizar y es posible ejecutar
comandos que interactúan directamente con el sistema embebido. A saber:
init: inicializa la interfaz jtag.
halt: detiene en procesador.
flash write image: escribe un firmware dado como argumento en la dirección de memoria
indicada.
flash erase sector: borra los sectores de memoria indicados.
reset: reinicia el sistema embebido
shutdown: libera la interfaz jtag y el sistema embebido.
A partir de esto, es posible programar la CIAA utilizando un comando como:
openocd -f openocd / lpc4337 . cfg \
-c " init " \
-c " halt 0 " \
-c " flash write_image erase unlock out / firmware . bin 0 x1A000000 bin " \
-c " reset run " -c " shutdown "
Utilizando OpenOCD
Otra alternativa de uso de OpenOCD es que se inicie como servicio. En este modo de funciona-
miento, una vez iniciada la aplicación queda a la espera de conexiones tcp a diferentes puertos:
Puerto 4444: comunicación a través de telnet. En este modo es posible interactuar con
OpenOCD enviándole directivas para controlar la ejecución de la aplicación en el sistema
embebido o acceder a variables y direcciones de memoria.
Puerto 3333: la interacción en este caso se da a través del depurador utilizado, en nuestro
caso arm-none-eabi-gdb. Cuando se depuran aplicaciones desde Eclipse, este invoca a gdb y
éste a OpenOCD.
Puerto 5555: interfaz de máquina a través de un intérprete TCL.
Utilizando OpenOCD
Otra alternativa de uso de OpenOCD es que se inicie como servicio. En este modo de funciona-
miento, una vez iniciada la aplicación queda a la espera de conexiones tcp a diferentes puertos:
Puerto 4444: comunicación a través de telnet. En este modo es posible interactuar con
OpenOCD enviándole directivas para controlar la ejecución de la aplicación en el sistema
embebido o acceder a variables y direcciones de memoria.
Puerto 3333: la interacción en este caso se da a través del depurador utilizado, en nuestro
caso arm-none-eabi-gdb. Cuando se depuran aplicaciones desde Eclipse, este invoca a gdb y
éste a OpenOCD.
Puerto 5555: interfaz de máquina a través de un intérprete TCL.
Y ahora...
A programar!