pico-sdk
pico-sdk copied to clipboard
Pico board gets stuck in pre-main when using PICO_CXX_ENABLE_EXCEPTIONS.
Hi. I have a weird issue. My setup is as follows:
- Windows pc with vscode and official extension.
- Pi Zero with openocd server installed.
- Pi Pico connected to Pi Zero over SWD. The board is non-stock, some purple version with additional SPI memory, a little bit different layout https://content.invisioncic.com/r322239/monthly_2023_08/image.png.e0bc5e9365fc0aa30308e0e641d12499.png
I am able to build, upload, debug, etc all programs as long as the CMakeLists parameter PICO_CXX_ENABLE_EXCEPTIONS is set to 0. When I enable it (set to 1), the board gets stuck in pre-main in:
while (!time_reached(t_before)) {
uint32_t save = spin_lock_blocking(sleep_notifier.spin_lock);
lock_internal_spin_unlock_with_wait(&sleep_notifier, save);
}
(https://github.com/raspberrypi/pico-sdk/blob/master/src/common/pico_time/time.c)
I also get this warning in vscode:
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
sleep_until (t=<optimized out>) at C:/Users/Mario/.pico-sdk/sdk/2.0.0/src/common/pico_time/time.c:401
401 uint32_t save = spin_lock_blocking(sleep_notifier.spin_lock);
And this in openocd (Pi Zero's SSH), but I don't think it's related:
Warn : Function FUNC_BOOTROM_STATE_RESET not found in RP2xxx ROM. (probably an RP2040 or an RP2350 A0)
Warn : Function FUNC_FLASH_RESET_ADDRESS_TRANS not found in RP2xxx ROM. (probably an RP2040 or an RP2350 A0)
Also, sample code that doesn't even reach main() with PICO_CXX_ENABLE_EXCEPTIONS enabled:
#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
stdio_init_all();
while (true) {
sleep_ms(1000);
}
}
And CMakeLists.txt:
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
# == DO NEVER EDIT THE NEXT LINES for Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.0.0)
set(toolchainVersion 13_3_Rel1)
set(picotoolVersion 2.0.0)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
# ====================================================================================
set(PICO_BOARD pico CACHE STRING "Board type")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
project(hello_world C CXX ASM)
set(PICO_CXX_ENABLE_EXCEPTIONS 1)
set(PICO_CXX_ENABLE_RTTI 1)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(hello_world hello_world.cpp )
pico_set_program_name(hello_world "hello_world")
pico_set_program_version(hello_world "0.1")
# Modify the below lines to enable/disable output over UART/USB
pico_enable_stdio_uart(hello_world 0)
pico_enable_stdio_usb(hello_world 0)
# Add the standard library to the build
target_link_libraries(hello_world
pico_stdlib)
# Add the standard include files to the build
target_include_directories(hello_world PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
)
pico_add_extra_outputs(hello_world)
Part of launch.json that sends and debugs the program on remote openocd:
{
"name": "Pico Debug (Cortex-Debug with external OpenOCD)",
"cwd": "${workspaceRoot}",
"executable": "${command:raspberry-pi-pico.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "external",
"gdbTarget": "192.168.1.36:3333",
"gdbPath": "${command:raspberry-pi-pico.getGDBPath}",
"device": "${command:raspberry-pi-pico.getChipUppercase}",
"svdFile": "${userHome}/.pico-sdk/sdk/2.0.0/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd",
"runToEntryPoint": "main",
// Give restart the same functionality as runToEntryPoint - main
"postRestartCommands": [
"break main",
"continue"
]
},
Any ideas what might be going on? If someone wants to investigate it, we can talk over discord or mumble. I'm out of ideas. Also asked on pico forums: https://forums.raspberrypi.com/viewtopic.php?t=377061 And reddit: https://www.reddit.com/r/raspberrypipico/comments/1fo1wo3/pico_board_gets_stuck_in_premain_when_using_pico/
Can you test a real pico?
I just tested with stock board with RPI-B1 stepping. It has the exact same behavior, identical.
Maybe this will help.
I just noticed that, according to the call stack, it's in main() however breakpoints in main() don't work.
I noticed one more thing. With set(PICO_CXX_ENABLE_EXCEPTIONS 1) the binary doesn't even seem to upload properly. I changed blink time to 1000 ms set PICO_CXX_ENABLE_EXCEPTIONS to 0, ran, debugged program (all working correctly). Then I changed it to 100 ms, did the same and reset the board. For some reason the 100ms binary didn't upload and the board still blinks with 1000ms intervals.
With some help on Discord I discovered that:
- Just sending uf2 file via usb (boot while pressing button) works fine and the code is properly sent.
- Someone tested on local openocd and it also seems to work fine.
- The issue seems to be only when using remote openocd with the parameter PICO_CXX_ENABLE_EXCEPTIONS set to 1. Binary is not updated and thus debug is freaking out and not stopping at breakpoints.
I decided to bloat the .uf2 by adding hardcoded 150KB int array to test if it's the .uf2 size issue. https://pastebin.com/raw/mxySbqV8 With PICO_CXX_ENABLE_EXCEPTIONS set to 0 it still works properly. With it set to 1, it won't upload and thus won't debug properly.
Could you try replacing
"postRestartCommands": [
"break main",
"continue"
]
with
"overrideLaunchCommands": [
"monitor reset init",
"load \"${{command:raspberry-pi-pico.launchTargetPath}}\""
],
in your launch.json configuration and see if that works any better?
In the VS Code extension we noticed some issues with the default monitor reset halt used, so use this alternative sequence for the "Pico Debug (Cortex-Debug)" configuration, but haven't updated the "Pico Debug (Cortex-Debug with external OpenOCD)" configuration yet
It gave an error:
${{command:raspberry-pi-pico.launchTargetPath}}: No such file or directory.
Failed to launch GDB: ${{command:raspberry-pi-pico.launchTargetPath}}: No such file or directory. (from interpreter-exec console "load \"${{command:raspberry-pi-pico.launchTargetPath}}\"")
So I replaced with instead:
"overrideLaunchCommands": [
"monitor reset init",
"load \"${command:raspberry-pi-pico.launchTargetPath}\""
],
But it doesn't fix the main problem. The behavior is the same as before; works with "PICO_CXX_ENABLE_EXCEPTIONS 0" but doesnt with "PICO_CXX_ENABLE_EXCEPTIONS 1"
Has this issue been fixed? I'm running into a debugger issue where it doesn't stop at main. I have a working project, and I'm comparing the differences in the .vscode and changing the .vscode on the nonworking project does not seem to help. I'm not quite sure what is causing this issue. I have been trying to use the picoboard_blinky project and it seems to load the firmware since it blinks on the board, but I cannot for the life of me get it to stop at the main function.
So, I installed brought my vs code extension Raspberry Pi Pico to 12.2.2 and now it stops at main! I'm not sure if this will solve your issue but it fixed mine. I created the blinky project from the "New Project From Examples" and now it stops at main. Something must have broken in the new vs code extension on the later versions.
UPDATE: The 13.1 version works, but anything above it has issues creating "New Project From Examples."
Closing this as it has been fixed in the extension, by using the alternative launch commands
I'm having this exact issue using the SDK 2.1.0 and Raspberrry Pi Pico VSCode Extension V 0.17.3 (both latest versions)
When PICO_CXX_ENABLE_EXCEPTIONS is set to 1, and I select debug, the program is not uploaded to the pico, and I can't get any breakpoints to work.
@will-v-pi , what do you mean about using the alternative launch commands?
and I select debug
What button are you clicking to debug - is it definitely one provided by the VS Code Extension (see the getting started guide for details)?
the program is note uploaded to the pico
What error do you get when it fails to upload the program?
@will-v-pi , what do you mean about using the alternative launch commands?
The extension now uses updated launch commands which fix the issue - you don't need to change any of your launch commands
Here's my output from DEBUG CONSOLE when I have set(PICO_CXX_ENABLE_EXCEPTIONS 1) in my cmakelists.txt
Cortex-Debug: VSCode debugger extension version 1.12.1 git(652d042). Usage info: https://github.com/Marus/cortex-debug#usage
Reading symbols from c:/users/dude/.pico-sdk/toolchain/13_3_rel1/bin/arm-none-eabi-objdump --syms -C -h -w c:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/build/KEEZI.elf
Reading symbols from c:/users/dude/.pico-sdk/toolchain/13_3_rel1/bin/arm-none-eabi-nm --defined-only -S -l -C -p c:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/build/KEEZI.elf
Launching GDB: "C:\\Users\\Dude\\.pico-sdk\\toolchain\\13_3_Rel1\\bin\\arm-none-eabi-gdb" -q --interpreter=mi2
IMPORTANT: Set "showDevDebugOutput": "raw" in "launch.json" to see verbose GDB transactions here. Very helpful to debug issues or report problems
Launching gdb-server: "C:\\Users\\Dude/.pico-sdk/openocd/0.12.0+dev/openocd.exe" -c "gdb_port 50000" -c "tcl_port 50001" -c "telnet_port 50002" -s "C:\\Users\\Dude/.pico-sdk/openocd/0.12.0+dev/scripts" -f "c:/Users/Dude/.vscode/extensions/marus25.cortex-debug-1.12.1/support/openocd-helpers.tcl" -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000"
Please check TERMINAL tab (gdb-server) for output from C:\Users\Dude/.pico-sdk/openocd/0.12.0+dev/openocd.exe
Finished reading symbols from objdump: Time: 74 ms
Finished reading symbols from nm: Time: 91 ms
Output radix now set to decimal 10, hex a, octal 12.
Input radix now set to decimal 10, hex a, octal 12.
`c:\Users\Dude\Google Drive\RAYKEYZ\Program\KEEZI\KEEZI\build\KEEZI.elf' has changed; re-reading symbols.
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
main () at C:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/KEEZI.cpp:10
warning: Source file is more recent than executable.
10 printf("Hello, world!\n");
Program stopped, probably due to a reset and/or halt issued by debugger
[rp2350.dap.core1] VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.
[rp2350.dap.core1] Set 'cortex_m reset_config sysresetreq'.
[rp2350.dap.core0] halted due to breakpoint, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.
[rp2350.dap.core1] Set 'cortex_m reset_config sysresetreq'.
[rp2350.dap.core0] halted due to breakpoint, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
warning: could not convert 'main' from the host encoding (CP1252) to UTF-32.
This normally should not happen, please file a bug report.
And here is my DEBUG CONSOLE when I remove set(PICO_CXX_ENABLE_EXCEPTIONS 1) from cmakelists.txt
Cortex-Debug: VSCode debugger extension version 1.12.1 git(652d042). Usage info: https://github.com/Marus/cortex-debug#usage
Reading symbols from c:/users/dude/.pico-sdk/toolchain/13_3_rel1/bin/arm-none-eabi-objdump --syms -C -h -w c:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/build/KEEZI.elf
Reading symbols from c:/users/dude/.pico-sdk/toolchain/13_3_rel1/bin/arm-none-eabi-nm --defined-only -S -l -C -p c:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/build/KEEZI.elf
Launching GDB: "C:\\Users\\Dude\\.pico-sdk\\toolchain\\13_3_Rel1\\bin\\arm-none-eabi-gdb" -q --interpreter=mi2
IMPORTANT: Set "showDevDebugOutput": "raw" in "launch.json" to see verbose GDB transactions here. Very helpful to debug issues or report problems
Launching gdb-server: "C:\\Users\\Dude/.pico-sdk/openocd/0.12.0+dev/openocd.exe" -c "gdb_port 50000" -c "tcl_port 50001" -c "telnet_port 50002" -s "C:\\Users\\Dude/.pico-sdk/openocd/0.12.0+dev/scripts" -f "c:/Users/Dude/.vscode/extensions/marus25.cortex-debug-1.12.1/support/openocd-helpers.tcl" -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000"
Please check TERMINAL tab (gdb-server) for output from C:\Users\Dude/.pico-sdk/openocd/0.12.0+dev/openocd.exe
Finished reading symbols from objdump: Time: 67 ms
Finished reading symbols from nm: Time: 82 ms
Output radix now set to decimal 10, hex a, octal 12.
Input radix now set to decimal 10, hex a, octal 12.
`c:\Users\Dude\Google Drive\RAYKEYZ\Program\KEEZI\KEEZI\build\KEEZI.elf' has changed; re-reading symbols.
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
0x10000cd0 in timer_time_reached (t=<optimized out>, timer=0x400b0000) at C:/Users/Dude/.pico-sdk/sdk/2.1.0/src/rp2_common/hardware_timer/include/hardware/timer.h:324
324 return (hi >= hi_target && (timer->timerawl >= (uint32_t) target || hi != hi_target));
Program stopped, probably due to a reset and/or halt issued by debugger
[rp2350.dap.core1] VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.
[rp2350.dap.core1] Set 'cortex_m reset_config sysresetreq'.
[rp2350.dap.core0] halted due to breakpoint, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.
[rp2350.dap.core1] Set 'cortex_m reset_config sysresetreq'.
[rp2350.dap.core0] halted due to breakpoint, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
[rp2350.dap.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x00000088 msp: 0xf0000000
Note: automatically using hardware breakpoints for read-only addresses.
warning: could not convert 'main' from the host encoding (CP1252) to UTF-32.
This normally should not happen, please file a bug report.
Thread 1 "rp2350.dap.core0" hit Temporary breakpoint 2, main () at C:/Users/Dude/Google Drive/RAYKEYZ/Program/KEEZI/KEEZI/KEEZI.cpp:7
warning: Source file is more recent than executable.
7 stdio_init_all();
I don't any warnings per se
And yes I'm hitting "Debug Project" from the Raspberry Pico Extension Sidebar:
Here's my full cmakelists.txt if needed (with set(PICO_CXX_ENABLE_EXCEPTIONS 1) commented out):
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.1.0)
set(toolchainVersion 13_3_Rel1)
set(picotoolVersion 2.1.0)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
# ====================================================================================
# Manually control DEBUG_MODE. Used to remove printf statements from the main .cpp binary
set(ENABLE_DEBUG_MODE ON) # Set to OFF to disable debug mode
if(ENABLE_DEBUG_MODE)
add_compile_definitions(DEBUG_MODE) # This defines DEBUG_MODE for the compiler
message("DEBUG_MODE is enabled")
else()
message("DEBUG_MODE is disabled")
endif()
#======================================================================================
#Only Set one of the board types below. Will also need to restart VS Code after changing
#set(PICO_BOARD pico CACHE STRING "Board type")
set(PICO_BOARD pico2 CACHE STRING "Board type")
# Pull in Pico SDK (must be before project)
include(pico_sdk_import.cmake)
project(KEEZI C CXX ASM)
#set(PICO_CXX_ENABLE_EXCEPTIONS 1)
set(PICO_CXX_ENABLE_RTTI 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add the executable. Default name is the project name, version 0.1
add_executable(KEEZI KEEZI.cpp Bitmap.cpp)
# Set the program name and version
#pico_set_program_name(KEEZI "KEEZI")
#pico_set_program_version(KEEZI "0.1")
# Enable stdio over UART and USB
pico_enable_stdio_uart(KEEZI 1)
pico_enable_stdio_usb(KEEZI 1)
# Link necessary libraries
target_link_libraries(KEEZI
tinyusb_host
tinyusb_board
pico_stdlib
)
#sign binary with private key and create otp.json file to load into bookey0 otp rows with picotool
#pico_sign_binary(KEEZI ${CMAKE_CURRENT_SOURCE_DIR}/ec_private_key.pem)
#pico_set_otp_key_output_file(KEEZI ${CMAKE_CURRENT_LIST_DIR}/otp.json)
# Create map/bin/hex/uf2 files
pico_add_extra_outputs(KEEZI)
Ok, I can reproduce this, but it only occurs with SDK 2.1.0 (whereas the original issue was with SDK 2.0.0).
A fix that is working for me is to delete the build folder, click "Configure CMake" to recreate it, and then when I click "Debug Project" it works. Obviously that's not ideal, but could you check if that fix works for you too?
Also, for me this line only appears when it doesn't work - when it works there is no line like this
`c:\Users\Dude\Google Drive\RAYKEYZ\Program\KEEZI\KEEZI\build\KEEZI.elf' has changed; re-reading symbols.
That method works some of the time. I'm getting really inconsistent results. I seem to have better luck using the Run and Debug start debug button than the Debug button from the pico extension. I can't really figure out anything that works 100% of the time yet. The "Flash Project (SWD)" button works consistently to load the program atleast but obviously debugging will be a bit more annoying until there's a real fix.
It also seems that if I'm in a debug session, then stop the debug, then immediately start debug again, it almost never works. If I don't make a change to my program it's less likely to work 2 times in a row. Sorry for the non concrete information but I'm gonna take a break from testing for now.
Please Reopen this...
For me, the PICO_CXX_ENABLE_EXCEPTIONS doesn't seem to make much of a difference..
I can, most of the time, debug fine if I delete the build-folder beforehand
ONCE
SDK 2.1.1
If I don't delete the build folder beforehand, the code isn't even uploaded at all...
I've also tried changing my launch commands to something like this
"overrideLaunchCommands": [
"monitor reset init",
"file \"${command:raspberry-pi-pico.launchTargetPath}\"",
"load",
],
Update
I can get somewhat reliable debugging when both
- Not having enabled CXX_Exceptions
- using
"monitor reset halt"instead of"monitor reset init"
I couldn't get my debug session to start. (PicoProbe + Pico2W)
Thanks to this thread, changed launch.json to
using "monitor reset halt" instead of "monitor reset init"
It now launches
same problem debugging freertos apps, Sometimes deleting build folder and restarting vs code helps, sometimes not... :(
A simple example seems to work out of the box repeatedly, but my actual project with USB (tinyusb usbtmc) I think runs into interrupt troubles during startup. Same project used to work flawlessly a year ago
but my actual project with USB (tinyusb usbtmc) I think runs into interrupt troubles during startup. Same project used to work flawlessly a year ago
Downgrading to an older release of pico-sdk that still works correctly with your project is always an option.
But if you want us to investigate your problem, you'll be better off creating a new issue, and providing as much info as possible.
This should still be a live issue, debug is a nightmare. Keeps loosing sync and failing to upload new builds to pico. Fed up with having to reset and rebuild to get around this