Marus / cortex-debug

Visual Studio Code extension for enhancing debug capabilities for Cortex-M Microcontrollers
MIT License
1.01k stars 240 forks source link

[Solved] Application does not run when debugging a program from RAM #891

Closed thedigitaledge closed 1 year ago

thedigitaledge commented 1 year ago

Please make you search through our existing issues (both open and closed)

Describe the bug Application does not run as expected when debugging a program from RAM.

The NXP MCIMX7ULP-EVK which is a multi-core chip that can be configured to run only it's Cortex-M4 chip. This requires the system to execute it's boot-loader and read configuration pins then it halt the device. When its stop the debugger can upload a program to ram RAM which has to also sets the PC and other registers to enable the program to correctly run from the RAM.

I've run through the commands from the debug console window and I have found that skipping the '13-interpreter-exec console "monitor reset" ' makes the application run correct as expected.

I've tried to work out where in the system this instruction comes from but I've gotten lost in the code. I can't work out if there's either a configuration option to override it or one of the debug attributes overloads this call.

I've seen a few other issues that refer to running from RAM but nothing that's gotten down the function call that's causing it to fail.

Thanks, Chris

To Reproduce Setup a basic application using Jlink and GDB on an NXP MCIMX7ULP-EVK development board with runToEntryPoint set to "main"

  1. Start debug session System does not halt or run correctly.

Expected behavior

Program will halt at the main function call.

Screenshots

[comment]: <> If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

[comment]: <> Whenever possible, please make sure you are using the latest versions of VSCode and our extension

Please include launch.json

Note: We are unlikely to look at the issue if you do not supply this

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            // Debug
            "name": "Example Cortex-Debug",
            "type": "cortex-debug",
            "request": "launch",
            "showDevDebugOutput": "raw",
            "showDevDebugTimestamps": true,
            // Jlink
            "servertype": "jlink",
            "serverpath": "/opt/SEGGER/JLink/JLinkGDBServerCLExe",
            "interface": "swd",
            "device": "MCIMX7U5_M4",
            "serialNumber": "821006040",
            "jlinkscript":"${workspaceRoot}/support/NXP_iMX7ULP_CortexM4.JLinkScript",
            // GDB
            "executable": "${workspaceRoot}/scratch-pad/hello_world.elf",
            "toolchainPrefix": "arm-zephyr-eabi",
            "armToolchainPath": "${env:HOME}/bin/zephyr-sdk-latest/arm-zephyr-eabi/bin",
            "gdbPath": "${env:HOME}/bin/zephyr-sdk-latest/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb",
            "runToEntryPoint": "main"
        }
    ]
}

Attach text from Debug Console

Please enable debug output in your launch.json ("showDevDebugOutput": "raw"). It this is too large, please attach it as a file

Cortex-Debug: VSCode debugger extension version 1.10.0 git(cf1c296). Usage info: https://github.com/Marus/cortex-debug#usage
Reading symbols from ~/bin/zephyr-sdk-latest/arm-zephyr-eabi/bin/arm-zephyr-eabi-objdump --syms -C -h -w ~/firmware/mcu/app/scratch-pad/hello_world.elf
Reading symbols from ~/bin/zephyr-sdk-latest/arm-zephyr-eabi/bin/arm-zephyr-eabi-nm --defined-only -S -l -C -p ~/firmware/mcu/app/scratch-pad/hello_world.elf
Launching GDB: ~/bin/zephyr-sdk-latest/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb -q --interpreter=mi2
1-gdb-version
Launching gdb-server: /opt/SEGGER/JLink/JLinkGDBServerCLExe -singlerun -nogui -if swd -port 50003 -swoport 50004 -telnetport 50005 -device MCIMX7U5_M4 -select usb=821006040 -jlinkscriptfile ~/firmware/mcu/app/support/NXP_iMX7ULP_CortexM4.JLinkScript
    Please check TERMINAL tab (gdb-server) for output from /opt/SEGGER/JLink/JLinkGDBServerCLExe
Finished reading symbols from objdump: Time: 99 ms
Finished reading symbols from nm: Time: 129 ms
-> =thread-group-added,id="i1"
-> ~"GNU gdb (Zephyr SDK 0.16.1) 12.1\n"
-> ~"Copyright (C) 2022 Free Software Foundation, Inc.\n"
-> ~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law."
-> ~"\nType \"show copying\" and \"show warranty\" for details.\n"
-> ~"This GDB was configured as \"--host=x86_64-build_pc-linux-gnu --target=arm-zephyr-eabi\".\n"
-> ~"Type \"show configuration\" for configuration details.\n"
-> ~"For bug reporting instructions, please see:\n"
-> ~"<https://github.com/zephyrproject-rtos/sdk-ng/issues>.\n"
-> ~"Find the GDB manual and other documentation resources online at:\n    <http://www.gnu.org/software/gdb/documentation/>."
-> ~"\n\n"
-> ~"For help, type \"help\".\n"
-> ~"Type \"apropos word\" to search for commands related to \"word\".\n"
-> 1^done
2-gdb-set mi-async on
-> 2^done
3-interpreter-exec console "set print demangle on"
-> 3^done
4-interpreter-exec console "set print asm-demangle on"
-> =cmd-param-changed,param="print asm-demangle",value="on"
-> 4^done
5-enable-pretty-printing
-> 5^done
6-interpreter-exec console "source ~/.vscode/extensions/marus25.cortex-debug-1.10.0/support/gdbsupport.init"
-> 6^done
7-interpreter-exec console "source ~/.vscode/extensions/marus25.cortex-debug-1.10.0/support/gdb-swo.init"
-> =cmd-param-changed,param="language",value="c"
-> =cmd-param-changed,param="language",value="auto"
-> 7^done
8-file-exec-and-symbols "~/firmware/mcu/app/scratch-pad/hello_world.elf"
-> 8^done
9-target-select extended-remote localhost:50003
-> =thread-group-started,id="i1",pid="42000"
-> =thread-created,id="1",group-id="i1"
-> ~"LPUART_ReadBlocking (base=0x4103a000, data=0x2000ffe7 \"\", length=0) at ~/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/devices/MCIMX7U5/drivers/fsl_lpuart.c:1054\n"
LPUART_ReadBlocking (base=0x4103a000, data=0x2000ffe7 "", length=0) at ~/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/devices/MCIMX7U5/drivers/fsl_lpuart.c:1054
-> ~"1054\t            statusFlag = LPUART_GetStatusFlags(base);\n"
1054                statusFlag = LPUART_GetStatusFlags(base);
-> *stopped,frame={addr="0x1ffd590a",func="LPUART_ReadBlocking",args=[{name="base",value="0x4103a000"},{name="data",value="0x2000ffe7 \"\""},{name="length",value="0"}],file="~/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/devices/MCIMX7U5/drivers/fsl_lpuart.c",fullname="~/TDE/projects/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/devices/MCIMX7U5/drivers/fsl_lpuart.c",line="1054",arch="armv7e-m"},thread-id="1",stopped-threads="all"
mi2.status = stopped
Program stopped, probably due to a reset and/or halt issued by debugger
-> 9^connected
10-interpreter-exec console "monitor halt"
-> 10^done
11-interpreter-exec console "monitor reset"
-> @"Resetting target\r\n"
Resetting target
-> 11^done
12-target-download
-> 12+download,{section=".interrupts",section-size="576",total-size="135535"}
-> 12+download,{section=".interrupts",section-sent="576",section-size="576",total-sent="576",total-size="135535"}
-> 12+download,{section=".resource_table",section-size="16",total-size="135535"}
-> 12+download,{section=".text",section-size="17264",total-size="135535"}
-> 12+download,{section="CodeQuickAccess",section-size="186",total-size="135535"}
-> 12+download,{section=".ARM",section-size="8",total-size="135535"}
-> 12+download,{section=".init_array",section-size="4",total-size="135535"}
-> 12+download,{section=".fini_array",section-size="4",total-size="135535"}
-> 12+download,{section=".data",section-size="100",total-size="135535"}
-> 12^done,address="0x1ffd230c",load-size="18158",transfer-rate="2075200",write-rate="2017"
13-interpreter-exec console "monitor reset"
-> @"Resetting target\r\n"
Resetting target
-> 13^done
Returning dummy thread-id to workaround VSCode issue with pause button not working
14-data-list-register-names
-> 14^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","sp","lr","pc","","","","","","","","","","xpsr","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","msp","psp","primask","basepri","faultmask","control","apsr","epsr","ipsr","iapsr","eapsr","iepsr","fpscr","s0","s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","s12","s13","s14","s15","s16","s17","s18","s19","s20","s21","s22","s23","s24","s25","s26","s27","s28","s29","s30","s31","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14","d15"]
Returning dummy stack frame to workaround VSCode issue with pause button not working: {"threadId":1,"startFrame":0,"levels":20}
15-break-insert -t --function main
-> 15^done,bkpt={number="1",type="breakpoint",disp="del",enabled="y",addr="0x1ffd283e",func="main",file="~/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/boards/evkmcimx7ulp/demo_apps/hello_world/hello_world.c",fullname="~/TDE/projects/reference/nxp_EVK-MCIMX7ULP/SDK_2_13_0_EVK-MCIMX7ULP/boards/evkmcimx7ulp/demo_apps/hello_world/hello_world.c",line="35",thread-groups=["i1"],times="0",original-location="-function main"}
16-exec-continue --all
-> 16^running
-> *running,thread-id="all"
mi2.status = running

Additional context Add any other context about the problem here.

haneefdm commented 1 year ago

We do not and cannot control how your processor boots and how many layers of bootloaders it runs through. As you can see, we did

  1. load the program -- 12-target-download
  2. reset the chip (this should stop at the reset vector) -- 13-interpreter-exec console "monitor reset"
  3. Set a breakpoint where requested -- 15-break-insert -t --function main
  4. Let the program continue -- 16-exec-continue --all

Now, the rest is in your FW's hand and if the program (PC) ever arrives at the specified function your processor should halt.

Now, if your bootloader does another FULL reset, the breakpoint is lost. It all depends on your FW which includes the bootloader.

If you need custom start sequence, there are a slew of options for you. Without knowing a lot of details, I cannot tell you what will work for you.

thedigitaledge commented 1 year ago

By the looks of it I haven't gotten the my head around how the system boots and I've confused the issue.

I think the question I should have asked is can I disable the reset call at 13 as without it I can get the application to run by manually entering all the previous and subsequent commands.

haneefdm commented 1 year ago

https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md

See above. Tons of options to override/add to what we do. In this case look for anything that starts with override, pre and post

Also read how our debug process works (applies to most debuggers)

https://github.com/Marus/cortex-debug/wiki/Cortex-Debug-Under-the-hood

haneefdm commented 1 year ago

You can always attach instead of a launch if that works better. Without a proper reset, launch will not work properly.

thedigitaledge commented 1 year ago

https://github.com/Marus/cortex-debug/wiki/Cortex-Debug-Under-the-hood I missed that thank you.

To answer my own problem;

To run the program from RAM I used the following command to stop the PC, etc from being reset.

"overrideLaunchCommands": [ "monitor halt", "monitor reset", "load" ]