Cortex-M hello_world example for Verdin iMX8M-Plus strange behavior

Hi @vix,

This is not disabled in TorizonCore, it should work normally.

I tested here on my side, following the article Cortex-M JTAG Debugging | Toradex Developer Center and the JTAG debug works. Let me show you here step by step so you can also test on your side to check if it works. Then, we can also improve our documentation if something is missing.

First of all, I’ve installed the latest nightly of TorizonCore 6 on my Verdin Plus. In my case, I used the nightly from 15.05.23.

Next, I rebooted my module and stopped at the u-boot terminal (pressing the space bar connected to /dev/ttyUSB3 on my computer).

U-Boot 2022.04-6.3.0-devel+git.09985651db17 (Jan 01 1970 - 00:00:00 +0000)

CPU:   i.MX8MP[8] rev1.1 1600 MHz (running at 1200 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 39C
Reset cause: POR
DRAM:  4 GiB
Core:  89 devices, 23 uclasses, devicetree: separate
WDT:   Started watchdog@30280000 with servicing (60s timeout)
MMC:   FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... OK
In:    serial@30880000
Out:   serial@30880000
Err:   serial@30880000
Model: Toradex 0058 Verdin iMX8M Plus Quad 4GB WB IT V1.0B
Serial#: 06817298
Carrier: Toradex Verdin Development Board V1.1B, Serial# 10893479
SEC0:  RNG instantiated

 BuildInfo:
  - ATF 3c1583b

Setting variant to wifi
Net:   eth1: ethernet@30be0000, eth0: ethernet@30bf0000 [PRIME]
Normal Boot
Hit any key to stop autoboot:  0 
Verdin iMX8MP # 

After compiling the debug version of the hello_world from NXP

$ ./build_debug.sh

I started my JlinkGDBServer. By the way, I downloaded it from the Segger website, which I believe is the latest one (I download it today):

SEGGER J-Link GDB Server V7.88b Command Line Version

JLinkARM.dll V7.88b (DLL compiled May 10 2023 14:13:03)

Here is my launch command:

>> JLinkGDBServer -if JTAG -device MIMX8ML8_M7
SEGGER J-Link GDB Server V7.88b Command Line Version

JLinkARM.dll V7.88b (DLL compiled May 10 2023 14:13:03)

Command line: -if JTAG -device MIMX8ML8_M7
-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      yes
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               off
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 MIMX8ML8_M7
Target device parameters:      none
Target interface:              JTAG
Target interface speed:        4000kHz
Target endian:                 little

Connecting to J-Link...
J-Link is connected.
Firmware: J-Link V10 compiled Jan 30 2023 11:28:07
Hardware: V10.10
S/N: 50109804
Feature(s): GDB
Checking target voltage...
Target voltage: 1.78 V
Listening on TCP/IP port 2331
Connecting to target...

J-Link found 1 JTAG device, Total IRLen = 4
JTAG ID: 0x5BA00477 (Cortex-M7)
Halting core...
Halting target device failed. Trying again with reset
Connected to target
Waiting for GDB connection...

After that, I opened a new terminal and went to the armgcc/debug/folder to start my hello_world.elf file.

Here are the commands:

  • Exported the arm toolchain.
>> export PATH=/home/hiago/Workdir/cortex-m/toolchain/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin:$PATH
  • Launched the GDB with the necessary Python library.
>> LD_LIBRARY_PATH=/home/hiago/Workdir/cortex-m/python3.6/lib/ arm-none-eabi-gdb hello_world.elf 
GNU gdb (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 11.2.90.20220202-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:
<https://bugs.linaro.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from hello_world.elf...
(gdb)
  • Finally, I ran the GDB commands.
(gdb) target remote localhost:2331
Remote debugging using localhost:2331
0x00000008 in __isr_vector ()
(gdb) monitor reset
Resetting target
(gdb) monitor halt
(gdb) load
Loading section .interrupts, size 0x2a8 lma 0x0
Loading section .resource_table, size 0x10 lma 0x400
Loading section .text, size 0x44b4 lma 0x410
Loading section .ARM, size 0x8 lma 0x48c4
Loading section .init_array, size 0x4 lma 0x48cc
Loading section .fini_array, size 0x4 lma 0x48d0
Loading section .data, size 0x64 lma 0x48d4
Start address 0x0000048c, load size 18400
Transfer rate: 289 KB/sec, 2300 bytes/write.
(gdb) monitor go

After connecting to the JLink GDB Server, I can see these messages being printed on the first terminal:

J-Link found 1 JTAG device, Total IRLen = 4
JTAG ID: 0x5BA00477 (Cortex-M7)
Halting core...
Halting target device failed. Trying again with reset
Connected to target
Waiting for GDB connection...^[[D^[[AConnected to 0000:0000:0000:0000:0000:0000:0000:0001
GDB client (conn. 11) requested target.xml from GDB Server
Reading common registers: Read register 'r0' (4 bytes) from hardware: 0x00000000
Read register 'r1' (4 bytes) from hardware: 0x00000000
Read register 'r2' (4 bytes) from hardware: 0x00000000
Read register 'r3' (4 bytes) from hardware: 0x00000000
Read register 'r4' (4 bytes) from hardware: 0x00000000
Read register 'r5' (4 bytes) from hardware: 0x00000000
Read register 'r6' (4 bytes) from hardware: 0x00000000
Read register 'r7' (4 bytes) from hardware: 0x00000000
Read register 'r8' (4 bytes) from hardware: 0x00000000
Read register 'r9' (4 bytes) from hardware: 0x00000000
Read register 'r10' (4 bytes) from hardware: 0x00000000
Read register 'r11' (4 bytes) from hardware: 0x00000000
Read register 'r12' (4 bytes) from hardware: 0x00000000
Read register 'sp' (4 bytes) from hardware: 0x00000220
Read register 'lr' (4 bytes) from hardware: 0xFFFFFFFF
Read register 'pc' (4 bytes) from hardware: 0x08000000
Read register 'xpsr' (4 bytes) from hardware: 0x00000001
Read 4 bytes @ address 0x00000008 (Data = 0xE7FEE7FE)
WARNING: Unsupported remote command "resource_table"
Received monitor command: reset
Resetting target
Received monitor command: halt
Halting target CPU...
...Target halted (PC = 0x00000008)
Downloading 680 bytes @ address 0x00000000
Downloading 16 bytes @ address 0x00000400
Downloading 16128 bytes @ address 0x00000410
Downloading 1460 bytes @ address 0x00004310
Downloading 8 bytes @ address 0x000048C4
Downloading 4 bytes @ address 0x000048CC
Downloading 4 bytes @ address 0x000048D0
Downloading 100 bytes @ address 0x000048D4
Writing register 'pc' = 0x0000048C
Received monitor command: go
Starting target CPU...

After the monitor go command, I can see the hello world being printed on my debug serial /dev/ttyUSB2.

Can you please check if the same works for you? My host computer is Linux Debian 12, but I don’t think that matters here.

Best Regards,
Hiago.

Hi @hfranco.tx
I’m going to test your steps, but I need a couple of preliminary informations:

  • do you use a J-Link Plus debug probe with USB connection to PC and with this adapter?
  • at which step do you connect the J-Link Plus to the PC and to X56 of Verdin Development Board?

Hi @vix,

Sure,

  • I’ve used a J-Link Base Probe from Segger, version 10.1.
  • It was the first step, actually. I connected everything first, then booted up the module and started the whole process. I’m my case, I’ve used the Development Board and connected my jumper wires to the X67 connector because I don’t have here a connector for X56. Basically, I removed all 6 jumpers on the X67 and manually added wires for each pin on the J-Link probe, following this pinout:

My connections:

JTAG Development Board (x67) J-Link Probe (pinout)
JTAG_TCK TCK
JTAG_TDI TDI
JTAG_TDO TDO
JTAG_TMS TMS
JTAG_TRST# nTRST
JTAG_VREF VTref

Let me know if you have any questions about my setup.

Best Regards,
Hiago.

I don’t know if J-Link Base is different from the Plus, but in my case, it holds the MCU in reset after is plugged.
I see it because the LED becomes RED.
In this case, the boot won’t start after I press the ON/OFF button.
This is the reason for the steps I posted.
Do you know why my J_link keeps RESET active while plugged, and you doesn’t?

I need a deeper investigation, but it seems that if:

  1. I leave the J-Link unplugged
  2. I power on the board
  3. I stop the boot inside U-Boot
  4. only at this point I plug the J_link
    everything works.
    But I need other investigation.

Hi @vix,

Unfortunately I don’t know exactly the difference between them and why in your probe it doesn’t work. Did you check your JLinkGDBServer version?

Best Regards,
Hiago.

I also couldn’t to connect the CortexM when Linux run. I cannot even load kernel if JLink is connected to the Verdin Devboard - at some stage i get “random: crng init done”. If disconnect Jlink from JTAG connector - everything loading OK. And I don’t have a RED led on my JLink - so it doesn’t hold RESET signal at this moment. What can be the reason in this case?

Only if I stop CortexA loading in U-boot I can connect and debug CortexM.

Good day.
Are there any update of this issue?

Hi @Stan88,

Unfortunately no updates on this topic. We still need something from Segger or NXP to try to solve this issue, all the test that I’ve done is all documented on this topic, but no news since then.

Best Regards,
Hiago.

Hi @hfranco.tx
I’ve reproduced all your steps - it works the same.

But I don’t see your Linux startup stage. Everything that is described in the documentation works, but there they always stop the bootloader by pressing the keys and then do the debugging. And I need everything to work the same when Linux is running on CortexA, in order to debug messages and data for CortexM coming from the application in CortexA.

And when, after the above your steps, I continue to boot Linux with the “boot” command, Linux does not boot, giving an error - “random: crng init done”.

Did you boot Linux later and debug the CortexM firmware with a working Linux?

Regards.

Hi.
I figured out the current problem in my case.

If I run IMX8MP together with JTAG connected to the board, this blocks the launch of the MMU module, which further leads to incorrect handling of sections and a critical error. To avoid this, I disconnect the JTAG from the board, get to the U-Boot stop, reset it by pressing any key, connect the JTAG (by this moment the MMU has already been initialized), continue loading with command “boot” - and after loading Linux, I can debug the CortexM7 firmware while running in parallel CortexA53 with Linux services.

When the system is rebooted, the described steps have to be repeated again, but this does not happen often, so this option is still quite working. Maybe I missed something and this situation is easily fixed?)