STM32F4 Interrupt Priority Issue Calling xQueueReceiveFromISR

Hello, I am using STM32F4 with FreeRTOS. I have read through all the documentation multiple times and believe I have the interrupt priorities set correctly in my FreeRTOSConfig.h but am still getting an assert failure on priorities when calling xQueueReceiveFromISR in a CAN Rx ISR on rare occassions. The following is my FreeRTOSConfig.h snippet:

#define configPRIO_BITS 4

The PriorityGrouping is set to NVIC_PRIORITYGROUP_4 as advised. The CAN Rx ISR priority is set to 5 at bootup before the scheduler is started and the following is what the ISR looks like:

void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* hcan) {
  can_frame_t message;
  if (xQueueReceiveFromISR(can_rx_queue, &message, NULL) == pdPASS) {
    (CAN_transmit_frame(hcan1, message.header.StdId,, message.header.DLC);

Sometimes I will get a fault due to an assert hitting from the function: portASSERT_IF_INTERRUPT_PRIORITY_INVALID() in queue.c which then calls configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); in port.c

Can you see in the debugger what is the value of ulMaxPRIGROUPValue when the assertion fails? I’m guessing that field is corrupted or not yet established by FreeRTOS startup code.

Also, can you check the value of current priority grouping in addition to ulMaxPRIGROUPValue in the debugger? You can update the code to the following to get the current priority grouping:

volatile uint32_t ulCurrentInterruptGrouping;
ulCurrentInterruptGrouping = ( portAIRCR_REG & portPRIORITY_GROUP_MASK );
configASSERT( ulCurrentInterruptGrouping <= ulMaxPRIGROUPValue );


I was able to recreate and you are correct, it looks like ulMaxPRIGROUPValue is corrupted and set to 0 in this case.
Do you have any idea how/why this would happen? There are definitely interrupts triggering before the tasks are created and scheduler is started, could this be contributing?

Yes, I think you’re onto it there. If your ISRs make API calls to FreeRTOS, best to make sure FreeRTOS is up and running before enabling those interrupts.

That was it! I was able to move the interrupt enable after the scheduler was started and this fixed it.
Root cause was that this interrupt was firing before ulMaxPRIGROUPValue could get set to a non-zero value and was causing an assert.
Takeaway - Any ISR that has an RTOS function call with FromISR must be enabled after the scheduler has been started.
Thanks for the help!