Utilizzando il JTAG è possibile condurre sessioni di debug sul kernel di Linux, vediamo come in questo articolo della Rubrica Firmware Reload, all'interno della quale potrete leggere articoli tecnici della passata rivista cartacea Firmware, inerenti argomenti che riscuotono ancora molto interesse tra professionisti e appassionati di elettronica.
CONFIGURARE L’EMULATORE
Una delle attività da fare è quella, una volta compilato il kernel, di configurare in modo appropriato il nostro JTAG. Di solito, il costruttore di un adattatore fornisce il file di configurazione. Per scrivere una nostra configurazione, o per modificarne una già esistente, sarà necessario leggere la documentazione offerta dal produttore. Nel nostro caso, il Listato 1 presenta un esempio per configurare il PEEDI.
[DEBUGGER] PROTOCOL = gdb_remote ; gdb remote REMOTE_PORT = 2000 ; TCP/IP port GDB_READ_INGNORE_TIME = 3000 [TARGET] PLATFORM = ARM ; platform is ARM [PLATFORM_ARM] JTAG_CHAIN = 4 ; list of IR length of all ; TAP controller in JTAG chain JTAG_CLOCK = 5, 4000 ; JTAG Clock in [kHz] - 10kHz ; JTAG clock for init operations and ; 10MHz for normal work TRST_TYPE = PUSHPULL ; type of TRST output: OPENDRAIN ; or PUSHPULL ;WAKEUP_TIME = 200 ; time between releasing the reset and ; starting the jtag communication RESET_TIME = 20 ; length of RESET pulse in ms; 0 means ; no RESET CORE0 = ARM7TDMI ; TAP is ARM7TDMI CPU CORE0_STARTUP_MODE = RESET ; Let the core enable the JTAG port CORE0_BREAK_PATTERN = 0xDFFFDFFF ; software breakpoint pattern CORE0_BREAKMODE = soft ; breakpoint mode: ; soft - use software breakpoints ; hard - use hardware breakpoints CORE0_INIT = INIT_MC13224 ; init section CORE0_FLASH = FLASH_SPI25 ; FLASH section parameters CORE0_ENDIAN = LITTLE ; MC13224 works in BIG endian CORE0_WORKSPACE = 0x00400000, 0x1A00 ; workspace for flash CORE0_FILE = “myfile.bin”, BIN, 0x00400000 ; default file CORE0_PATH = “tftp://192.168.1.1” ; default path [INIT_MC13224] mem or 0x80003048 0x00000080 ; enable flash power [FLASH_SPI25] CHIP = SPI25_FLASH CPU = MC1322X SPI_DIV = 0 FILE = “myfile.bin”, BIN, 0 ; file to program AUTO_ERASE = NO ; erase before program [SERIAL] ; serial port configuration BAUD = 115200 STOP_BITS = 1 PARITY = NONE TCP_PORT = 0 ; enable CLI over RS232 ;TCP_PORT = 2023 ; enable serial over TCP/IP [TELNET] PROMPT = “mc13224> “ ; telnet prompt ;BACKSPACE = 127 ; comment out for autodetect [DISPLAY] BRIGHTNESS = 20 ; LED indicator brightness VOLUME = 25 ; beeper volume [ACTIONS] ; user defined scripts ;AUTORUN = 2 ; executed on every target connect 1 = erase 2 = prog 3 = dump_ram 4 = dump_flash [erase] ; erase flash flash erase [prog] ; program flash flash prog flash verify [dump_ram] ; dump part of RAM memory dump 0x40000000 0x1000 tftp://192.168.1.1/ram.bin [dump_flash] ; dump part of FLASH memory dump 0x00000000 0x1000 tftp://192.168.1.1/flash.bin
| Listato 1: PEEDI configuration file Freescale MC13224 |
MINIMAL DEBUGGING ARM LINUX
Questa è una soluzione minimale a basso costo; in effetti, non si ha la necessità di utilizzare una strumentazione esterna e complessa ma il tutto si basa su una classica interfaccia con costi estremamente contenuti. Esistono diversi strumenti disponibili in rete ma, in base all’esperienza personale, si potrebbe optare per la proposta di casa Macraigor su porta parallela o ricorrendo alla semplice interfaccia hardware di Olimex utilizzando OCD attraverso una porta USB o seriale. In questo caso, con ARM-USB-OCD è possibile eseguire il debug delle schede ARM, completo di porta RS232 virtuale con tutti i segnali modem presenti con la presa di alimentazione che può fornire tre valori di tensione 5V - 9V - 12V intervenendo sui jumper di selezione. In alternativa, è anche possibile ricorrere a ARM-JTAG, una soluzione inferiore, con interfaccia JTAG/Parallela. In questo caso, tutto quello che abbiamo bisogno è, oltre all’interfaccia realizzata da Olimex, l’openOCD e Putty. Il tutto si basa su GDB, il debugger GNU, accluso in qualsiasi distribuzione: a questo riguardo possiamo utilizzare la sua modalità testuale o grafica magari ricorrendo al tool DDD (Data Display Debugger) o a Insight. Una volta stabilite correttamente le connessioni è necessario inizializzare la nostra sessione di lavoro così come riportato al Listato 2.
@echo off echo Connect to a “Wiggler” - type CTRL-c / Strg-c to cancel rem ** speed ** set SPEED=3 rem ** device-address: 1 for lpt1, 2 for lpt2, same for 3,4 ** set DEVAD=1 rem ** path to ocdremote.exe ** rem set OCDRPATH=C:\WinARM\examples\wiggler_tests\mc set OCDRPATH=C:\cygwin\usr\local\bin rem ** CPU-Type ** set CPU=ARM7TDMI-S rem ** tcp/ip port (default 8888) set PORT=8888 :restart %OCDRPATH%\ocdremote.exe -c %CPU% -s %SPEED% -a %DEVAD% -p %PORT% -d WIGGLER goto restart
| Listato 2: Set-up connessione |
La Figura 1 mostra l’esito positivo con il nostro target, mentre la Figura 2 mostra l’inizio della nostra sessione di debug. Una tipica sessione di lavoro con openOCD inizia con il mount dell’usbfs con il comando sudo mount -t usbfs none /proc/bus/usb e con sudo bin/openocd -f flyswatter.cfg -f lpc3250.cfg; si lancia il nostro programma per la gestione dell’interfaccia JTAG. A questo punto possiamo mettere in esecuzione il debugger con il comando:
arm-unknown-linux-gnueabi-insight vmlinux
all’interno del quale è necessario impostare i parametri di comunicazione con il target hostname e port. In questo caso, stiamo utilizzando la variante grafica di GBD di Insight (Figura 3). Oppure, possiamo anche pensare di lavorare con STM32/ARM Cortex-M3 in ambiente Ubuntu seguendo una procedura seguente ricorrendo a openOCD.
cd ~/stm32/stm32-example/projects/ stm_h103/ make clean make wget http://fun-tech.se/stm32/OpenOCD/ openocd.cfg
A questo punto, ci colleghiamo al nostro target a facciamo partire il nostro server OpenOCD:
xterm -e “openocd -f openocd.cfg” & Attraverso una connessione Telnet …. xterm -e “telnet localhost 4444” &
… possiamo anche mettere in flash il nostro sistema di test, così:
reset halt flash probe 0 stm32x mass_erase 0 flash write_bank 0 main.bin 0 reset halt
A questo punto, dobbiamo far partire il nostro debugger scegliendo la modalità testuale o grafica. In effetti, con:
arm-none-eabi-gdbtui —evalcommand=” target remote localhost: 3333” main.out
si fa partire la sessione testuale, mentre con:
arm-none-eabi-insight —evalcommand=” target remote localhost: 3333” main.out
si fa partire la scelta grafica basata su Insight. Per utilizzare openOCD è necessario scrivere un file di configurazione, uno script file che si prende in carico di inizializzare l’hardware e definire l’ambiente di lavoro da utilizzare. Con la prima parte si intende configurare l’OpenOCD server negli aspetti di ricezione e invio dei comandi verso il debug residente su host. Il primo comando “telnet_port 4444” specifica la porta sulla quale si intende ascoltare le connessioni telnet in entrata. Con gdb_port si instaurano le comunicazioni a livello GDB con il sistema sotto test. Nella sezione Interface si definiscono i parametri utilizzati dall’interfaccia per il test: in questo caso si utilizza il driver ft2232. Questa parte è utilizzata per inizializzare il driver prima di utilizzare il JTAG. È anche possibile definire la memoria target attraverso il comando memory space che identifica l’indirizzo di partenza della porzione di memoria e la sua dimensione. Il lavoro per configurare openOCD deve essere fatto con particolare cura perché deve rispecchiare l’esatta configurazione fisica del nostro target.

Figura 1: Connessione stabilita

Figura 2: Avvio di una sessione di debug

Figura 3: Insight con GDB
Leggi la puntata precedente: Debugging Linux via JTAG – Puntata 1 | Elettronica Open Source



