Debugging with M3 nodes
Difficulty: Medium
Duration: 45 minutes
Prerequisites: Configure SSH Access / Submit an experiment with M3 nodes using the web portal / Get and compile a M3 firmware code
Description: We use Open On-Chip Debugger (OpenOCD) on the Gateway node for programming and debugging M3 embedded target devices. OpenOCD complies with the remote gdbserver protocol and, as such, can be used to debug remote targets. The aim of this tutorial is to learn how debugging the firmware running on your experiment M3 nodes with a gdb console.
- Submit a new experiment
- 45 minutes and starting “as soon as possible”
- Choose your node by type
- archi = m3:at86rf231
- site = grenoble
- number = 2
- Node associations: leave empty (no associations)
- click “Submit”, then click “yes” at the warning message (“Do you really want to…”)
- Click on the experiment in the list and wait for the experiment to become running. Make a note of the ids (eg. m3-<id>) of your nodes.
- Connect to the SSH frontend of Grenoble
ssh <login>@grenoble.iot-lab.info
- If you didn’t authenticate using iotlab-auth, do it now:
<login>@grenoble:~$ iotlab-auth -u login
- Ensure that you have compiled the M3 tutorial firmware and copy it in your root homedir path.
<login>@grenoble:~$ cp iot-lab/parts/openlab/build.m3/bin/tutorial_m3.elf .
When you want to use JTAG debugging it is recommanded to desactivate power save mode and the WFI (Wait For Interrupt) processor instruction. You can comment it in openlab platform.c file (line 81) before compiling your tutorial firmware.
80 // Enter SLEEP mode
81 // asm volatile(“wfi”); - Start OpenOCD debugger mode on one of the experiment M3 node
<login>@grenoble:~$ iotlab-node --debug-start -l grenoble,m3,<id1> { "0": [ "m3-<id1>.grenoble.iot-lab.info" ] }
- Open a terminal and read node serial port
<login>@grenoble:~$ nc m3-<id1> 20000
- Start GDB console with your binary firmare file and connect to OpenOCD which listens for GDB connections on port 3333
<login>@grenoble:~$ arm-none-eabi-gdb -ex "target remote m3-<id1>:3333" tutorial_m3.elf GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20140228-cvs Copyright (C) 2013 Free Software Foundation, Inc. ... Reading symbols from tutorial_m3.elf...done. (gdb)
- Sending command to see registers list
(gdb) monitor reg ===== arm v7m registers (0) r0 (/32) ...
- Send query to see if we can find the flash module and report the proper address. It responds that it found the flash at address 0x08000000. We also check the FLASH_WRPR register at address 0x40022020 to confirm that your device’s write-protection has been disabled (0xffffffff means all pages have their write protection disable).
(gdb) monitor flash probe 0 flash 'stm32f1x' found at 0x08000000 (gdb) monitor mdw 0x40022020 0x40022020: ffffffff
- Perform a hard reset
(gdb) monitor reset halt
- Flash the firmware file
(gdb) load tutorial_m3.elf
- Set a breakpoint in the code with mac_csma_data_received function (main.c line 112) for stopping the code when we received a radio packet
(gdb) break mac_csma_data_received
- List your breakpoints
(gdb) info break
- Perform a hard reset with init script and continue the code execution. You must see on m3-<id1> serial port the print usage execution (type “Enter”)
(gdb) monitor reset init (gdb) continue
- Open a terminal and flash the tutoriel firmware on the m3-<id2> node. After read the serial port and send a radio packet
<login>@grenoble:~$ iotlab-node -up tutorial_m3.elf -l grenoble,m3,<id2> <login>@grenoble:~$ nc m3-<id2> 20000 cmd > s radio > Packet sent
- View in gdb console your breakpoint received
Breakpoint 1, mac_csma_data_received (src_addr=39044, data=0x20000615 <mac+53> "Hello World!: 0", length=16 '\020', rssi=-76 '\264', lqi=lqi@entry=255 '\377') at /senslab/users/saintmar/iot-lab/parts/openlab/appli/iotlab_examples/tutorial/main.c:112 112 {
- Print ten lines main.c source code file and continue execution
(gdb) list 107 108 109 /* Reception of a radio message */ 110 void mac_csma_data_received(uint16_t src_addr, 111 const uint8_t *data, uint8_t length, int8_t rssi, uint8_t lqi) 112 { 113 // disable help message after receiving one packet 114 print_help = 0; 115 116 printf("\nradio > "); (gdb) continue
- View on m3-<id1> serial port the packet received
cmd > radio > Got packet from 9884. Len: 16 Rssi: -76: 'Hello World!: 0'