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.

  1. 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…”)
  2. 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.
  3. Connect to the SSH frontend of Grenoble
    ssh <login>
  4. If you didn’t authenticate using iotlab-auth, do it now:
    <login>@grenoble:~$ iotlab-auth -u login
  5. 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”);
  6. Start OpenOCD debugger mode on one of the experiment M3 node
    <login>@grenoble:~$ iotlab-node --debug-start -l grenoble,m3,<id1>
     "0": [
  7. Open a terminal and read node serial port
    <login>@grenoble:~$ nc m3-<id1> 20000
  8. 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)
    Copyright (C) 2013 Free Software Foundation, Inc.
    Reading symbols from tutorial_m3.elf...done.
  9. Sending command to see registers list
    (gdb) monitor reg
    ===== arm v7m registers
    (0) r0 (/32)
  10. 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
  11. Perform a hard  reset
    (gdb) monitor reset halt
  12. Flash the firmware file
    (gdb) load tutorial_m3.elf
  13. 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
  14. List your breakpoints
    (gdb) info break
  15.  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
  16. 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
  17. 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 {
  18. Print ten lines main.c source code file and continue execution
    (gdb) list
    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;
    116	    printf("\nradio > ");
    (gdb) continue
  19. View on m3-<id1> serial port the packet received
     cmd > 
    radio > Got packet from 9884. Len: 16 Rssi: -76: 'Hello World!: 0'