Cortex-M JTAG Debugging
The goal of this article is to show how to use JTAG on Cortex-M for code debugging using J-Link hardware from Segger. Toradex Hardwares supported are:
- Apalis iMX8 with Apalis Evaluation Board.
- Colibri iMX7 and Colibri iMX8X with Colibri Evaluation Board.
- Verdin iMX8M Mini and Verdin iMX8M Plus with Verdin Devlopment Board or Dahlia carrier board.
Follow all the steps to set up the SDK and toolchain described in Setting Up MCUXpresso SDK and Toolchain for Cortex-M development.
- Toradex Evaluation Board (Colibri or Apalis), Development Board or Dahlia Board (Verdin).
- J-Link hardware from Segger. This guide uses hardware version v10.1.
Download the JLinkGDBServer from Segger website: J-Link Software and Documentation Pack
For this guide, we used the Linux 64-bit DEB installer version. Other HOST OSs were not tested.
Install necessary packages by running:
If you can't find the libpython3.6-dev package in your OS, check the steps below to compile it manually.
$ sudo apt-get install libncursesw5 libpython3.6-dev
Install JLinkGDBServer by running the command below. Replace PACKET_VERSION with the version downloaded.
$ sudo apt install ./JLink_Linux_<PACKET_VERSION>.deb
Install the GCC Toolchain as described in Setting Up MCUXpresso SDK and Toolchain for Cortex-M development.
The steps below are required only for Ubuntu 22.04 and distros based on it.
arm-none-gdb server requires a library from Python 3.6 which is not available in 22.04 anymore. Select a folder to install this library or create one (~/python3.6/, for example) and install it by running:
$ cd ~
$ export PREFIX=/home/$USER/python3.6
$ wget https://www.python.org/ftp/python/3.6.14/Python-3.6.14.tgz
$ tar xf Python-3.6.14.tgz
$ mkdir -p $PREFIX && cd $PREFIX
$ ~/Python-3.6.14/configure --prefix=$PREFIX --enable-shared
$ make -j$(nproc)
$ make install
Run the command below to check if the shared library was compiled successfully:
$ find . -name libpython3.6m.so.1.0
Now run the command below before running arm-none-gdb to tell GDB where to look for shared libraries.
$ export LD_LIBRARY_PATH=/home/$USER/python3.6/lib
JTAG Debug for Cortex-M
In this guide, the Hello World project will be compiled for debugging with the Cortex-M. Any other project from the SDK folder will work as well.
Check this guide How to Run a Hello World on the Cortex-M for more information about the Hello World with the Cortex-M.
Export your toolchain as shown in Setting Up MCUXpresso SDK and Toolchain for Cortex-M development.
$ export ARMGCC_DIR=~/cortex-m/toolchain/<GCC_TOOLCHAIN_FOLDER>
This command will create two files inside the debug folder:
hello_world.elf. For debugging purposes, the
.elf binary should always be used with the GDB server instead of the
Open the serial communication with the Linux terminal and Cortex-M terminal (using picocom, for example) just as described in the How to Run a Hello World on the Cortex-M.
Boot up your module and stop at the u-boot terminal, pressing the space bar multiple times after powering up the module.
Running the Debugger
Connect the J-Link to your board using the JTAG connector. Check what connector to use in the table below.
|Apalis Evaluation Board||X33|
|Colibri Evaluation Board||X13|
|Verdin Development Board||X56|
|Dahlia Carrier Board||X8|
If an external JTAG debugger is used with a Verdin Development Board, jumpers X67A – X67F should be removed. Simultaneous use of the on-board and external JTAG Debugger is not allowed. Violating this requirement may damage the Debuggers or the Verdin Development Board. For more information, check the Verdin Development Board Datasheet section 2.20.
If an external JTAG debugger is used with a Dahlia Carrier Board, jumper JP6 should be removed. Simultaneous use of the on-board and external JTAG Debugger is not allowed. Violating this requirement may damage the Debuggers or the Dahlia Carrier Board. For more information, check the Dahlia Datasheet section 2.17.
Open your terminal and type, for Apalis iMX8 and Verdin iMX8M modules:
$ JLinkGDBServer -if JTAG -device <DEVICE>
For Colibri iMX8X:
$ JLinkGDBServer -if JTAG -device MIMX8QX6_M4 -vd -xc mekmimx8qx_gdbsrv.cfg
The mekmimx8qx_gdbsrv.cfg file is inside <SDK_FOLDER_PATH>/boards/mekmimx8qx/demo_apps/hello_world/armgcc/. Go to this folder to execute the command above or set the full path to this file.
Where DEVICE should be replaced with one of the above:
|Apalis iMX8||MIMX8QM6_M4_0 (Core 0) or MIMX8QM6_M4_1 (Core 1)|
|Colibri iMX7||Follow the guide FreeRTOS on the Cortex-M4 of a Colibri iMX7|
|Verdin iMX8M Mini||MIMX8MM6_M4|
|Verdin iMX8M Plus||MIMX8ML8_M7|
After successfully initializing JLinkGDBServer, go to the folder of the .elf debug file. For the hello-world example, it will be inside:
$ cd <SDK_FOLDER_PATH>/boards/<BOARD_NAME>/demo_apps/hello_world/armgcc/debug/
Run the arm-none-eabi-gdb downloaded with the toolchain. To do that, export the toolchain folder to the Linux PATH:
$ export PATH=/home/$USER/cortex-m/toolchain/<TOOLCHAIN_FOLDER_EXTRACTED>/bin:$PATH
And load the hello_wolrd.elf:
$ arm-none-eabi-gdb hello_world.elf
If you are using Ubuntu 22.04 or distros based on that, don't forget to export the LD_LIBRARY_PATH as mentioned in Software Requirements.
The output should be as follow:
GNU gdb (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 184.108.40.20620202-git
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from hello_world.elf...
Now, run these commands below for Apalis iMX8 and Verdin iMX8M:
(gdb) target remote localhost:2331
(gdb) monitor reset
(gdb) monitor halt
For Colibri iMX8X:
(gdb) target remote localhost:2331
(gdb) load hello_world.elf
The application is now downloaded and halted at the reset vector. Execute the monitor go command to start the demo application. Or run the firmware step by step using the command step.
(gdb) monitor go
The "Hello World!" message will appear on the Cortex-M debug terminal.
If you want to run it inside Visual Studio Code, follow the guide Cortex-M Development Using VSCode.