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
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().
Describe the bug
On the RP2350 ARM_NTZ port, any FreeRTOS API that uses
taskENTER_CRITICAL/taskEXIT_CRITICALbeforevTaskStartScheduler()leavesBASEPRIset toconfigMAX_SYSCALL_INTERRUPT_PRIORITYinstead 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
portable/ThirdParty/GCC/RP2350_ARM_NTZHost
To Reproduce
In
main(), beforevTaskStartScheduler(), call any FreeRTOS create API and readBASEPRIbefore and after:Observed:
bp_pre = 0x00,bp_post = 0x10(=configMAX_SYSCALL_INTERRUPT_PRIORITY). The same occurs withxQueueCreate,xSemaphoreCreateBinary, and any other API that internally enters a critical section.The practical consequence in my project:
pico_stdio_usboutput hangs during init becauseUSBCTRL_IRQ(priority0x40) is masked, TinyUSB never sees transfer-complete events, and the CDC TX FIFO never drains.printfblocks untilPICO_STDIO_USB_STDOUT_TIMEOUT_USexpires and silently drops bytes.Expected behavior
After a
taskENTER_CRITICAL/taskEXIT_CRITICALpair called before the scheduler is running,BASEPRIshould be restored to its previous value (0), not set toconfigMAX_SYSCALL_INTERRUPT_PRIORITY.Additional context
Relevant config:
configMAX_SYSCALL_INTERRUPT_PRIORITY = 16configSUPPORT_STATIC_ALLOCATION = 1configSUPPORT_PICO_SYNC_INTEROP = 1configNUMBER_OF_CORES = 2(SMP)configRUN_FREERTOS_SECURE_ONLY = 1Workaround: save and restore
BASEPRImanually around pre-scheduler FreeRTOS calls, or defer all FreeRTOS object creation to a task that runs aftervTaskStartScheduler().