Signal Handler called during passive idle task

I am using FreeRTOS with portSUPPORT_SMP 1 and configNUMBER_OF_CORES 2 on the RP2040 target and include the PICO SDK 1.5.1.

I have the following code:

void flash_nvm_get_unique(uint8_t pUnique[8])
    flash_get_unique_id((uint8_t *)pUnique);

which contains a call to the SDK which runs from RAM and accesses the Flash which also holds my code.

If I comment out the call to flash_get_unique_id then there is no issue. If I include this line then core 0 signal handler is called with 0xFFFFFFFD and this always seems to happen in the passive idle task.

I have been wondering if the taskENTER_CRITICAL is enough to disable interrupts on both cores and prevent unwanted access to the Flash during my call to read the unique id. I am not sure how these things are related but for cause and effect.

I have also been looking into the configuration and note my config contains

#define configUSE_PASSIVE_IDLE_HOOK             0
#define configUSE_MINIMAL_IDLE_HOOK             0

So I am struggling to see why the passive idle task would throw an exception.

Any help much appreciated.

Are you able to call this function without FreeRTOS? May be try calling it from main. Also, can you try to find which fault is triggering and the faulting instruction. This page has some useful details about finding the faulting instruction - Debugging and diagnosing hard faults on ARM Cortex-M CPUs.

Hello, @iambendgcustomerfirst

I can see your query I give you my best, please see below and follow information…

The taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros are designed to create critical sections by disabling interrupts. However, in an SMP (Symmetric Multi-Processing) system, these macros may not suffice for synchronizing both cores, especially if the FreeRTOS port you’re using does not utilize the configMAX_SYSCALL_INTERRUPT_PRIORITY configuration constant.
The flash_get_unique_id function, which accesses the flash memory, could be causing a hard fault if it’s being called while the flash memory is being accessed or modified by another process or core. This is because the RP2040’s flash memory, where the code resides, cannot be accessed for reading while being written to or erased.

You could consider:

  1. Ensure that the flash_get_unique_id function is not being called from an interrupt service routine (ISR) or that it’s not interrupting any flash operation.
  2. Verify that the configMAX_SYSCALL_INTERRUPT_PRIORITY is set appropriately for your system, which could help in managing interrupt priorities correctly.
  3. Consider using taskENTER_CRITICAL_FROM_ISR() and taskEXIT_CRITICAL_FROM_ISR() if you’re dealing with ISRs.
  4. Review the SMP-specific APIs and configuration options provided by FreeRTOS for multi-core systems.
  5. Check if there’s a need to map certain functions to SRAM to avoid executing from flash during flash operations, as indicated by issues faced in similar environments.

If you have any query please tell me.

Best Regard,

The RP2040 SMP port uses spin locks to ensure that only one core enters critical section at a time:

The Cortex-M0 does not support selectively disabling interrupts as it does not have BASEPRI. Interrupts are disabled globally on this port - FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/include/portmacro.h at main · FreeRTOS/FreeRTOS-Kernel · GitHub. Therefore, configMAX_SYSCALL_INTERRUPT_PRIORITY is not relevant to RP2040 port.