Skip to content

[BUG] RP2350 ARM_NTZ port: pre-scheduler taskEXIT_CRITICAL leaves BASEPRI raised #1401

@romain145

Description

@romain145

Describe the bug
On the RP2350 ARM_NTZ port, any FreeRTOS API that uses taskENTER_CRITICAL / taskEXIT_CRITICAL before vTaskStartScheduler() leaves BASEPRI set to configMAX_SYSCALL_INTERRUPT_PRIORITY instead of restoring its previous value (0). This silently masks all interrupts at or below that priority for the remainder of the pre-scheduler init phase.

Target

  • Development board: Raspberry Pi Pico 2 (RP2350)
  • Instruction Set Architecture: ARMv8-M (Cortex-M33, non-TrustZone)
  • Port: portable/ThirdParty/GCC/RP2350_ARM_NTZ
  • Kernel version: V11.3.0
  • SDK: pico-sdk 2.2.0
  • Toolchain: arm-none-eabi-gcc

Host

  • Host OS: Windows

To Reproduce
In main(), before vTaskStartScheduler(), call any FreeRTOS create API and read BASEPRI before and after:

static inline uint32_t read_basepri(void) {
    uint32_t v; __asm volatile ("mrs %0, basepri" : "=r" (v));
    return v;
}

int main(void) {
    stdio_init_all();

    uint32_t bp_pre = read_basepri();              // 0x00

    static StaticSemaphore_t buf;
    SemaphoreHandle_t m = xSemaphoreCreateMutexStatic(&buf);

    uint32_t bp_post = read_basepri();             // 0x10
}

Observed: bp_pre = 0x00, bp_post = 0x10 (= configMAX_SYSCALL_INTERRUPT_PRIORITY). The same occurs with xQueueCreate, xSemaphoreCreateBinary, and any other API that internally enters a critical section.

The practical consequence in my project: pico_stdio_usb output hangs during init because USBCTRL_IRQ (priority 0x40) is masked, TinyUSB never sees transfer-complete events, and the CDC TX FIFO never drains. printf blocks until PICO_STDIO_USB_STDOUT_TIMEOUT_US expires and silently drops bytes.

Expected behavior
After a taskENTER_CRITICAL / taskEXIT_CRITICAL pair called before the scheduler is running, BASEPRI should be restored to its previous value (0), not set to configMAX_SYSCALL_INTERRUPT_PRIORITY.

Additional context

Relevant config:

  • configMAX_SYSCALL_INTERRUPT_PRIORITY = 16
  • configSUPPORT_STATIC_ALLOCATION = 1
  • configSUPPORT_PICO_SYNC_INTEROP = 1
  • configNUMBER_OF_CORES = 2 (SMP)
  • configRUN_FREERTOS_SECURE_ONLY = 1

Workaround: save and restore BASEPRI manually around pre-scheduler FreeRTOS calls, or defer all FreeRTOS object creation to a task that runs after vTaskStartScheduler().

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions