Bienvenido: Ingresar
location: LabElectronica / DebugWigglerOpenOCDGNUARM

Debugging con Wiggler, !OpenOCD y Toolchain GNUARM:

Hardware:

Esquema de la interconexión de los dispositivos:

<table align="center" border="0"><tbody><tr><td><img src=%ATTACHURL%/EsquemaDebug.png /> </td></tr></tbody></table>

JTAG:

JTAG, the Joint Test Access Group, se fundó en 1985 para crear estándares de prueba de PCB y circuitos integrados. La ùltima versiòn de este propòsito fue aprobada por IEEE como IEEE Std. 1149.1-2001 [IEEE1149], IEEE Standard Test Access Port and Boundary-Scan Architecture.

Usualmente, el tèrmino JTAG refiere al antes mesionado IEEE standard, antes que a el grupo que creò este. Como consecuencia, JTAG debería hacer referencia a IEEE Std. 1149.1.

Usos

Según lo dicho anteriormente JTAG ha sido adoptado con otros propósitos. Los usos comunes incluyen:

Un sitema típico para cualquier propósito incluyendo JTAG consiste en un sistema host (generalmente una PC), uan interface de hardware, y un sistema target.

Interfaces de hardware JTAG

El hardware depende de la tarea que vayamos a realizar, y demás recursos disponibles como por ejemplo recursos.

Referencias

IEEE Std. 1149.1-2001

Wiggler clone:

El Wiggler clone es un programador/debbuger utilizado para la programación de microcontroladores ARM. Utiliza la interfase JTAG de los mismos y el puerto paralelo de nuestra PC.

El puerto paralelo debe estar configurado en EPP en la configuración de la BIOS.

Circuito:

Placa y distribución de los componentes:

Software

!OpenOCD:

Está disponible en los mirrors Debian. Para más información al respecto la página oficial del proyecto es:

<a target="top" href="http://openfacts.berlios.de/index-en.phtml?title=Open''On-Chip_Debugger">http://openfacts.berlios.de/index-en.phtml?title=Open_On-Chip_Debugger</a>

Compilando !OpenOCD desde la SVN:

Como se ha detectado un bug para los micros LPC en las versiones de !OpenOCD que se encuentran en los repositorios Debian se hace una pequeña reseña de como compilar el proyecto desde sus fuentes.

Bajamos el ultimo repositorio desde la SVN como usuario con:

*$ svn checkout svn://svn.berlios.de/openocd/trunk*

luego usamos automake y autoconf con el script que trae el proyecto:

*$ ./bootstrap*

ahora usamos configure con los flags necesarios:

*$ ./configure --prefix /home/usuario/ --enable-parport --enable-parport_ppdev*

lo cual va a depender de el jtag que tengamos.

ahora solo resta realizar make

*$ make*

y luego agregar al .bashrc de nuestro usuario el proyecto:

PATH=~/trunk/src/:${PATH}

Hay que reiniciar el modo gráfico para que el bash comienze a funcionar, además se desintaló el openocd de Debian antes de realizar todo.

Comandos generales:

Daemon
sleep <msec>

Espera por n milisegundos de retornar la ejecución. Util en conexiones con archivos script(comandos 'script' y configuraciones 'target_script').

shutdown
Cierra el !OpenOCD daemon, desconectando todos los clientes (GDB, Telnet).
debug_level [n]

Muestra o ajusta el nivel de debug a n <0-3>

log_output <file>: Redirecciona el logeo a <file> (default
stderr)
script <file>

Ejecuta comando desde <file>

Manejador de estado del Target:
poll ['on'||'off']
Hace polling sobre el target para saber su estado. Si el target esta en modo debug, muestra información específica de la arquitectura acerca del estado actual. Un parámetro opcional permite habilitar o desabilitar el polling contínuo.
halt
Envía un requerimiento de parada al target. El debugger señala el requerimiento de debug, y espera al target para entrar en el debug mode.
resume [address]
Retorna el target a su actual posición en el código, o a otra dirección opcional.
step [address]
Ejecuta un solo paso en el target en su actual posición, o a otra dirección opcional.
reset ['run'||'halt'||'init'||'run_and_halt'||'run_and_init']
Realiza un hard-reset. Los parámetros opcionales especifican que debe pasar después del reset. Estos parámetros opcionales sobreescriben las especificaciones en el archivo de configuración, disponiendo un nuevo comportamiento para el comando 'reset' por defecto.
  • run: Pone a correr al target.
  • halt: Inmediatamente detiene el target (trabaja solo baja ciertas configuraciones).
  • init: Inmediatamente detiene el target, y ejecuta el reset script (trabaja solo baja ciertas configuraciones).
  • run_and_halt: Hace correr el target por un cierto período de tiempo, después realiza una parada.
  • run_and_init: Hace correr el target por un cierto período de tiempo, después realiza una parada. Ejecuta el reset script una vez que el target entra en modo debug.

Comandos de acceso a memoria:
  • Estos comandos permiten acceder a un sector específico de la memoria del sistema:
  • mdw <addr> [count]
    muestra memory words
    mdh <addr> [count]
    muestra memory half-words
    mdb <addr> [count]
    muestra memory bytes
    mww <addr> <value>
    escribe memory word
    mwh <addr> <value>
    escribe memory half-word
    mwb <addr> <value>
    escribe memory byte

$ load_image <file> ['bin'||'ihex'||'elf'] Load image <file> to target memory at dump_image <file> <size> Dump <size> bytes of target memory starting at to a (binary) <file>. load_binary <file> [DEPRECATED] Load binary <file> to target memory at dump_binary <file> <size> [DEPRECATED] Dump <size> bytes of target memory starting at to a (binary) <file>.:

Comandos para la memoria Flash:
flash banks
Lista los bancos flash configurados
flash info <num>

Muestra información acerca de los bancos flash <num>

flash probe <num>
Identifica la flash, o valida los parámetros de la flash configurada. La operación depende del tipo de flash.
flash erase_check <num>

Chequea el estado de borrado de los sectores en banco flash <num>. Esta es la única operación que actualiza la información de estado de borrado mostrada por 'flash info'. Esto significa que se tiene que ejecutar un comando 'erase_check' despues de borrar o programar el dispositivo para tener información actualizada.

flash protect_check <num>

Chequea el estado de protección de los sectores en un banco flash <num>.

flash erase <num> <first> <last>

Borra sectores en el banco<num>, empezando en el sector <first> hasta e incluyendo <last>. La numeración de los sectores empieza de 0. Dependiendo del tipo de flash, el borrado puede requerir protección para ser deshabilitado primero (e.g. Intel Advanced Bootblock flash using the CFI driver).

flash write <num> <file> <offset> [DEPRECATED]

Escribe el binario<file> al banco flash <num>, espezando en <offset> bytes desde el comienzo del banco. Este comando fue reemplazado por el nuevo comando 'flash write_binary' usando la misma sintaxis.

flash write_binary <num> <file> <offset>

Escribe el binario<file> al banco flash <num>, espezando en <offset> bytes desde el comienzo del banco.

flash write_image <file> [offset] [type]

Escribe la imágen <file> al/los actual/es banco/s flash del target. Una relocación[offset] puede ser especificada y el archivo[type] puede ser especificado explicitamente como 'bin' (binary), 'ihex' (Intel hex), 'elf' (ELF file) o 's19' (Motorola s19).

flash protect <num> <first> <last> <'on'||'off'>

Habilita ('on') o deshabilita ('off') la protección a sectores flash <first> hasta <last> del banco flash <num>.

flash auto_erase
Habilita ('on') para borrar bancos flash priorizando para escribir el uso del comando flash write_image solamente. Por defecto es ('off'), los bancos flash tienen que ser borrados usando el comando flash erase.

Comandos específicos ARM7/9

Estos comandos son específicos para ARM7 y ARM9, como !ARM7TDMI, ARM720t, ARM920t o !ARM926EJ-S.

arm7_9 sw_bkpts <'enable'||'disable'>
Enable/disable uso de software breakpoints. En sistemas ARMv4, esto reserva uno de los registros watchpoint para implementar breakpoints por software. Desabilitando SW Bkpts libera el registro.
arm7_9 force_hw_bkpts <'enable'||'disable'>
Cuando force_hw_bkpts está habilitado, el sw_bkpts support está desabilitado, y todos los breakpoints son transformados en hardware breakpoints.
arm7_9 dbgrq <'enable'||'disable'>
Habilita el uso de el DBGRQ bit para forzar la entrada en modo debug. Esto debe ser seguro para todos pero no lo es para núcleos !ARM7TDMI-S (como Philips LPC).
arm7_9 fast_writes <'enable'||'disable'>
DEPRECATED. Mirar "arm7_9 fast_memory_access" en este caso.
arm7_9 fast_memory_access <'enable'||'disable'>
Habilita al !OpenOCD a leer y escribir memoria sin chequear que la operación se haya completado. Esto provee una gran incremento de la velocidad, especialmente con cables USB JTAG (FT2232), pero puede ser inseguro si es usado en dispositivos a muy baja velocidad, como el reloj de 32kHz del !AT91RM9200.
arm7_9 dcc_downloads <'enable'||'disable'>

Habilita el uso del canal de comunicación de debug (DCC) para escribir grandes cantidades de memoria (>128 byte). Las descargas DCC ofrecen un incremento grande de la velocidad, pero pueden ser potencialmente inseguras, especialmente con dispositivos corriendo a baja velocidad. Este comando fue introducido con OpenOCD rev. 60.

Uso de !OpenOCD:

Archivo de configuración para ARM7 LPC2114 y Wiggler:

#daemon configuration
telnet_port 4444
gdb_port 3333

# tell gdb our flash memory map
# and enable flash programming
gdb_memory_map enable
gdb_flash_program enable

#interface
interface parport
parport_port /dev/parport0
parport_cable wiggler
jtag_speed 3

#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst srst_pulls_trst

#jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 4 0x1 0xf 0xe

#target configuration
target create target0 arm7tdmi -endian little -chain-position 0 -variant arm7tdmi-s_r4
working_area 0 0x40000000 0x4000 nobackup
#[new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup false

#flash bank lpc2000 <base> <size> 0 0 <target#> <variant>
flash bank lpc2000 0x0 0x20000 0 0 0 lpc2000_v2 14765 calc_checksum

# For more information about the configuration files, take a look at:
# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger

#init
#reset halt

Consideraciones puerto paralelo y usuarios:

Para el correcto funcionamiento del !OpenOCD con nuestra interfaz Wiggler debemos tener los permisos como usuario para acceder al mismo.

Para agregar el usuario a dialout como root tipeamos:

# gpasswd -a suusuario dialout

Además damos los permisos pertinentes de la siguiente forma:

$ su
# rmmod lp
# modprobe ppdev
# chmod 666 /dev/parport0
# exit
$

Conectando el Wiggler con !OpenOCD:

Aqui vemos que debe mostrarnos openocd al correrlo. Lo hacemos desde la carpeta donde esta nuestro archivo de configuración (en mi caso en donde a la vez se encuentra mi proyecto). La opción debug nos muestra toda la información de lo que va haciendo el programa y file linkea nuestro archivo de configuración con !OpenOCD.

usuario@dominio:~/Desktop/Debug$ openocd --file wiggler.cfg --debug 0
Open On-Chip Debugger 1.0 (2008-11-21-19:57) svn:1181


BUGS? Read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS


$URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
Debug:    1. 0 configuration.c:88 find_file(): found wiggler.cfg
Debug:    1. 0 command.c:91 script_command(): script_command - telnet_port
Debug:    1. 0 command.c:108 script_command(): script_command - telnet_port, argv[0]=ocd_telnet_port
Debug:    1. 0 command.c:108 script_command(): script_command - telnet_port, argv[1]=4444
Debug:   11 0 command.c:91 script_command(): script_command - gdb_port
Debug:   12 0 command.c:108 script_command(): script_command - gdb_port, argv[0]=ocd_gdb_port
Debug:   13 0 command.c:108 script_command(): script_command - gdb_port, argv[1]=3333
Debug:   15 0 command.c:91 script_command(): script_command - gdb_memory_map
Debug:   16 0 command.c:108 script_command(): script_command - gdb_memory_map, argv[0]=ocd_gdb_memory_map
Debug:   17 0 command.c:108 script_command(): script_command - gdb_memory_map, argv[1]=enable
Debug:   19 0 command.c:91 script_command(): script_command - gdb_flash_program
Debug:   20 0 command.c:108 script_command(): script_command - gdb_flash_program, argv[0]=ocd_gdb_flash_program
Debug:   21 0 command.c:108 script_command(): script_command - gdb_flash_program, argv[1]=enable
Debug:   23 0 command.c:91 script_command(): script_command - interface
Debug:   24 0 command.c:108 script_command(): script_command - interface, argv[0]=ocd_interface
Debug:   25 0 command.c:108 script_command(): script_command - interface, argv[1]=parport
Debug:   27 1 command.c:91 script_command(): script_command - parport_port
Debug:   28 1 command.c:108 script_command(): script_command - parport_port, argv[0]=ocd_parport_port
Debug:   29 1 command.c:108 script_command(): script_command - parport_port, argv[1]=/dev/parport0
Debug:   31 1 command.c:91 script_command(): script_command - parport_cable
Debug:   32 1 command.c:108 script_command(): script_command - parport_cable, argv[0]=ocd_parport_cable
Debug:   33 1 command.c:108 script_command(): script_command - parport_cable, argv[1]=wiggler
Debug:   35 1 command.c:91 script_command(): script_command - jtag_speed
Debug:   36 1 command.c:108 script_command(): script_command - jtag_speed, argv[0]=ocd_jtag_speed
Debug:   37 1 command.c:108 script_command(): script_command - jtag_speed, argv[1]=3
Debug:   38 1 jtag.c:1965 handle_jtag_speed_command(): handle jtag speed
User:    39 1 command.c:372 command_print(): jtag_speed: 3
Debug:   41 1 command.c:91 script_command(): script_command - reset_config
Debug:   42 1 command.c:108 script_command(): script_command - reset_config, argv[0]=ocd_reset_config
Debug:   43 1 command.c:108 script_command(): script_command - reset_config, argv[1]=trst_and_srst
Debug:   44 1 command.c:108 script_command(): script_command - reset_config, argv[2]=srst_pulls_trst
Debug:   46 1 command.c:91 script_command(): script_command - jtag_device
Debug:   47 1 command.c:108 script_command(): script_command - jtag_device, argv[0]=ocd_jtag_device
Debug:   48 1 command.c:108 script_command(): script_command - jtag_device, argv[1]=4
Debug:   49 1 command.c:108 script_command(): script_command - jtag_device, argv[2]=0x1
Debug:   50 1 command.c:108 script_command(): script_command - jtag_device, argv[3]=0xf
Debug:   51 1 command.c:108 script_command(): script_command - jtag_device, argv[4]=0xe
Debug:   52 1 target.c:3993 jim_target(): Target command params:
Debug:   53 1 target.c:3994 jim_target(): target create target0 arm7tdmi -endian little -chain-position 0 -variant arm7tdmi-s_r4 
Debug:   55 1 command.c:91 script_command(): script_command - working_area
Debug:   56 1 command.c:108 script_command(): script_command - working_area, argv[0]=ocd_working_area
Debug:   57 1 command.c:108 script_command(): script_command - working_area, argv[1]=0
Debug:   58 1 command.c:108 script_command(): script_command - working_area, argv[2]=0x40000000
Debug:   59 1 command.c:108 script_command(): script_command - working_area, argv[3]=0x4000
Debug:   60 1 command.c:108 script_command(): script_command - working_area, argv[4]=nobackup
Debug:   62 2 command.c:91 script_command(): script_command - bank
Debug:   63 2 command.c:108 script_command(): script_command - bank, argv[0]=ocd_flash_bank
Debug:   64 2 command.c:108 script_command(): script_command - bank, argv[1]=lpc2000
Debug:   65 2 command.c:108 script_command(): script_command - bank, argv[2]=0x0
Debug:   66 2 command.c:108 script_command(): script_command - bank, argv[3]=0x20000
Debug:   67 2 command.c:108 script_command(): script_command - bank, argv[4]=0
Debug:   68 2 command.c:108 script_command(): script_command - bank, argv[5]=0
Debug:   69 2 command.c:108 script_command(): script_command - bank, argv[6]=0
Debug:   70 2 command.c:108 script_command(): script_command - bank, argv[7]=lpc2000_v2
Debug:   71 2 command.c:108 script_command(): script_command - bank, argv[8]=14765
Debug:   72 2 command.c:108 script_command(): script_command - bank, argv[9]=calc_checksum
Debug:   74 2 command.c:91 script_command(): script_command - init
Debug:   75 2 command.c:108 script_command(): script_command - init, argv[0]=ocd_init
Debug:   76 2 openocd.c:143 handle_init_command(): target init complete
Debug:   77 2 parport.c:353 parport_init(): opening /dev/parport0...
Debug:   78 2 parport.c:365 parport_init(): ...open
Debug:   79 41 parport.c:237 parport_reset(): trst: 0, srst: 0
Debug:   80 41 openocd.c:150 handle_init_command(): jtag interface init complete
Debug:   81 41 jtag.c:1625 jtag_init_inner(): Init JTAG chain
Debug:   82 41 jtag.c:327 jtag_call_event_callbacks(): jtag event: JTAG controller reset (TLR or TRST)
Debug:   83 41 jtag.c:1305 jtag_reset_callback(): -
Debug:   84 41 jtag.c:327 jtag_call_event_callbacks(): jtag event: JTAG controller reset (TLR or TRST)
Debug:   85 41 jtag.c:1305 jtag_reset_callback(): -
Info:    86 52 jtag.c:1414 jtag_examine_chain(): JTAG device found: 0x4f1f0f0f (Manufacturer: 0x787, Part: 0xf1f0, Version: 0x4)
Debug:   87 52 jtag.c:327 jtag_call_event_callbacks(): jtag event: JTAG controller reset (TLR or TRST)
Debug:   88 52 jtag.c:1305 jtag_reset_callback(): -
Debug:   89 52 openocd.c:156 handle_init_command(): jtag init complete
Debug:   90 56 embeddedice.c:401 embeddedice_write_reg(): 0: 0x00000005
Debug:   91 60 embeddedice.c:401 embeddedice_write_reg(): 12: 0x00000000
Debug:   92 60 embeddedice.c:401 embeddedice_write_reg(): 20: 0x00000000
Debug:   93 62 openocd.c:159 handle_init_command(): jtag examine complete
Debug:   94 62 openocd.c:165 handle_init_command(): flash init complete
Debug:   95 62 openocd.c:169 handle_init_command(): mflash init complete
Debug:   96 62 openocd.c:173 handle_init_command(): NAND init complete
Debug:   97 62 openocd.c:177 handle_init_command(): pld init complete
Debug:   98 63 gdb_server.c:2205 gdb_init(): gdb service for target arm7tdmi at port 3333
Warning: 99 63 tcl_server.c:178 tcl_init(): no tcl port specified, using default port 6666
Warning: 100 110 arm7_9_common.c:744 arm7_9_poll(): DBGACK set while target was in unknown state. Reset or initialize target.
Debug:   101 110 embeddedice.c:401 embeddedice_write_reg(): 0: 0x00000005
Debug:   102 110 embeddedice.c:401 embeddedice_write_reg(): 12: 0x00000000
Debug:   103 113 arm7_9_common.c:1164 arm7_9_debug_entry(): target entered debug from ARM state
Debug:   104 148 arm7_9_common.c:1196 arm7_9_debug_entry(): target entered debug state in System mode
Debug:   105 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r0: 0x2000001f
Debug:   106 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r1: 0xe3a03000
Debug:   107 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r2: 0x00aa0000
Debug:   108 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r3: 0xe0028014
Debug:   109 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r4: 0xe002c000
Debug:   110 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r5: 0x7ffffe3c
Debug:   111 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r6: 0x4000012c
Debug:   112 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r7: 0x00000000
Debug:   113 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r8: 0xffffffff
Debug:   114 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r9: 0xffffffff
Debug:   115 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r10: 0xffffffff
Debug:   116 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r11: 0x40003ef4
Debug:   117 151 arm7_9_common.c:1227 arm7_9_debug_entry(): r12: 0x40003ef8
Debug:   118 152 arm7_9_common.c:1227 arm7_9_debug_entry(): r13: 0x40003ee4
Debug:   119 152 arm7_9_common.c:1227 arm7_9_debug_entry(): r14: 0x4000022c
Debug:   120 152 arm7_9_common.c:1227 arm7_9_debug_entry(): r15: 0x4000039c
Debug:   121 152 arm7_9_common.c:1233 arm7_9_debug_entry(): entered debug state at PC 0x4000039c
Debug:   122 152 target.c:717 target_call_event_callbacks(): target event 4 (early-halted)
Debug:   123 152 target.c:3125 target_handle_event(): event: 4 early-halted - no action
Debug:   124 152 target.c:717 target_call_event_callbacks(): target event 5 (halted)
Debug:   125 152 target.c:3125 target_handle_event(): event: 5 halted - no action
User:    126 152 target.c:973 target_arch_state(): target state: halted
User:    127 152 armv4_5.c:317 armv4_5_arch_state(): target halted in ARM state due to breakpoint, current mode: System
cpsr: 0x2000001f pc: 0x4000039c

Y ya tenemos nuestro Wiggler conectado, en este caso en el puerto 3333 del localhost.

Uso básico con programa alojado en RAM usando arm-elf-insight:

Una vez que se tiene conectado !OpenOCD desde la consola, procedemos a ejecutar arm-elf-insight en otra consola entrando:

usuario@dominio:~/Desktop/Debug$ arm-elf-insight 

Target Settings configuramos:

Le ponemos que "no" a cada una de las sugerencias:

Download y nos tiene que dar el mensaje de que la descarga fue exitosa en la parte inferior de la pantalla.

Desde alli procedemos a operar el Debugger teniendo las siguientes opciones:

De izquierda a derecha:

Consideraciones linker script:

El linker script que usamos debe alojar todos los sectores de nuestro programa en la memoria RAM, de modo de que la aplicación se aloje alli.

Esto se logra modificando el linker script, cambiando ROM o FLASH por RAM como sector destinado.

Consideraciones placa de desarrollo ARM:

En nuestra placa de desarrollo se debe conectar el puente que se encuentra dispuesto a tal fin. El mismo conecta Los pines RTCK con el TCK de la interface JTAG.

El circuito sincroniza por TCK al ARM cores internal clock, generando la entrada DBGTCKEN requerida por el ARM core y provee un clock de realimentación (RTCK) que habilita el debugger a usar velocidades de clock adaptables.

Ejemplos:

Blink-Led en C corriendo en RAM:

Ejemplo Blink Led

Estado Actual del Proyecto:

Se plantea como próximas actividades:

None: LabElectronica/DebugWigglerOpenOCDGNUARM (última edición 2010-06-07 22:15:57 efectuada por GonzaloPerezPaina)