Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pico board gets stuck in pre-main when using PICO_CXX_ENABLE_EXCEPTIONS. #1952

Closed
MarioPL98 opened this issue Sep 25, 2024 · 12 comments
Closed
Assignees
Milestone

Comments

@MarioPL98
Copy link

MarioPL98 commented Sep 25, 2024

Hi. I have a weird issue. My setup is as follows:

  1. Windows pc with vscode and official extension.
  2. Pi Zero with openocd server installed.
  3. 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/

@peterharperuk
Copy link
Contributor

Can you test a real pico?

@MarioPL98
Copy link
Author

MarioPL98 commented Sep 25, 2024

I just tested with stock board with RPI-B1 stepping. It has the exact same behavior, identical.

@MarioPL98
Copy link
Author

image
Maybe this will help.

@MarioPL98
Copy link
Author

I just noticed that, according to the call stack, it's in main() however breakpoints in main() don't work.

@MarioPL98
Copy link
Author

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.

@MarioPL98
Copy link
Author

With some help on Discord I discovered that:

  1. Just sending uf2 file via usb (boot while pressing button) works fine and the code is properly sent.
  2. Someone tested on local openocd and it also seems to work fine.
  3. 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.

@MarioPL98
Copy link
Author

MarioPL98 commented Sep 25, 2024

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.

@will-v-pi
Copy link

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

@MarioPL98
Copy link
Author

MarioPL98 commented Sep 27, 2024

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"

@shinta4ever
Copy link

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.

@shinta4ever
Copy link

shinta4ever commented Oct 9, 2024

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."

@kilograham kilograham added this to the 2.1.0 milestone Nov 11, 2024
@will-v-pi
Copy link

Closing this as it has been fixed in the extension, by using the alternative launch commands

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants