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

Open
MarioPL98 opened this issue Sep 25, 2024 · 7 comments
Open

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.

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

2 participants