Cómo depurar un programa en C para AVR en GNU/Linux con avr-gdb
Para la depuración he utilizado avr-gdb y simulavr desde distintas máquinas, consiguiendo de ese modo ver en una la ejecución del programa objeto de la prueba y en otra el contenido de los registros y de la memoria del micro.
A partir de ahora, explico cómo lo he hecho todo, desde la compilación (se necesitan parámetros específicos para el enlazador) hasta la puesta en funcionamiento del simulador. Doy por sentando que se conoce el uso de gdb para depurar.
Bueno, para que podamos funcionar tan solo necesitamos simulavr y avr-gdb. En nuestro querido Debian ya sabeis:
javieralso@avalon:~$ sudo apt-get install avr-gdb simulavr
:
MCU=atmega128
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes
#—————————-
all: rs232toRS485.hex rs232toRS485.bin
#—————————-
%.hex : %.out $(OBJCOPY) -j .text -O ihex rs232toRS485.out rs232toRS485.hex%.bin : %.out $(OBJCOPY) -j .text -O binary rs232toRS485.out rs232toRS485.bin
rs232toRS485.out : main.o $(CC) $(CFLAGS) -o rs232toRS485.out -Wl,-Map,rs232toRS485.map -Wa,-gstabs main.o avr-objdump -S rs232toRS485.out > rs232toRS485.lst
%.o : %.c $(CC) $(CFLAGS) -O0 -c $^
Además de lo comentado anteriormente, también se ha marcado una regla que se encarga de la creación de una imagen binaria del código de salida. Ésta imagen es importante, ya que es la que cargará simulavr para poder llevar a cabo la simulación del micro.
NOTA: Para que se pueda ver el contenido de las variables locales dentro del entorno de simulación, es muy importante que el flag de optimización esté puesto a 0. ($(CC) $(CFLAGS) -O0 -c $^).
.
Para nuestros propósitos simulavr funcionará como un gdbserver, es decir, le dirá a avr-gdb cómo debe comportarse. Por ello tenemos que arrancarlo primero. Para ello lo lanzamos de la siguiente manera:
javieralso@avalon:~$ simulavr -d atmega128 -P simulavr-disp -g rs232toRS485.bin
¿Qué hemos hecho? pues hemos llamado a simulavr diciéndole que vamos a simular un atmega128. Como queremos ver el contenido de los registros hemos llamado tambíen a simulavr-disp ya que simulavr solo dice a avr-gdb cómo comportarse, pero no muestra información alguna. simualvr-disp es el frontend que nos permite ver el contenido de los registros internos de la máquina que estamos simulando.
Para lanzar avr-gdb crearemos antes un archivo de comandos a ejecutar para “automatizar” un poco el uso. Éste archivo tiene algo como ésto:
file rs232toRS485.out target remote localhost:1212 load break main continue
javieralso@avalon:~$ avr-gdbtui -x comandos.gdb
siendo comandos.gdb el archivo en el que guardamos los comandos anteriores.
Podremos ver como inmediatamente cambian los valores de los registros mostrados en simulavr y avr-gdb queda parado en el main de nuestro programa. Ésto sucede porque nuestro programa empieza a simularse inmediatamente después de lanzar el depurador y para en el primer breakpoint que encuentra, que se encuentra en main (breakpoint por defecto). Cómo antes de eso se tiene que ejecutar código (arranque del micro, configuración de la pila, registros de configuración iniciales, inicialización de memoria, etc….) vemos los cambios en los registros de la máquina reflejados en simulavr. Ahora ya podremos simular/depurar como se hace usualmente con gdb.
¡¡Ale, a disfrutarlo
!!