I check the code of portSET_INTERRUPT_MASK_FROM_ISR(), it seems to have disabled all interrupt… That’s an interesting question and I need to rethink about the reason.
This does not seem correct. You need to shift this value according to the number of priority bits implemented by your hardware. You can looks at this for an example -
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
Also, what interrupts do you have in your system and what are their priorities?
Yes @aggarg that seems to be the issue. For perspective, the interrupt-priority checks in the CM33 port were not present in v10.5.1. Those checks would have caught this issue.
@zexalistic For the moment I am assuming your MCU implements only 3 bits of interrupt priority. As a result, the value of 16
for configMAX_SYSCALL_INTERRUPT_PRIORITY
is effectively zero (16
is 00010000b
, and the top three bits are 000
). The value zero doesn’t mask any interrupts, so all of your critical sections throughout your application are broken. That in turn allows the exact case you described above to explain your observations.
See here for help setting configMAX_SYSCALL_INTERRUPT_PRIORITY
:
I checked stm32h563xx.h
#define __NVIC_PRIO_BITS 4U /* Number of Bits used for Priority Levels */
So this should be correct
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 16
Are there any calls to NVIC_SetPriorityGrouping()
in your codebase? If so what is the value of the parameter passed to that function? When the error occurs, what is the value in
SCB->AIRCR
? Maybe only 3 (or fewer) of the 4 bits are being used as preemption-priority bits.
16 can’t be expressed i 4 bits, but needs 5. The bottom 4 bits of 16 is 0000.
NVIC_PRIORITYGROUP_4 was passed to NVIC_SetPriorityGrouping()
#define NVIC_PRIORITYGROUP_4 0x3U /*!< 4 bits for pre-emption priority,
0 bit for subpriority */
@zexalistic this question may lead to the real solution. Do you have an interrupt that uses the default priority of zero? If so, that is the source of your issue. Zero is the highest priority, too high to make calls to the FreeRTOS API.
True, but in this case it’s the upper 4 bits that matter. So the max interrupt priority safe for API calls in this case is priority 1. Only priority zero would cause a problem.
Sorry I just saw this reply. Yes, the nvic priority of my I2C slave and spi are 0. But when I try to change the highest priority of my peripherals to 1, my I2C slave Event handler will have some problem in receiving data. Thus, I can not verify if this is the source of issue.
My solution is to manually disable taskSELECT_HIGHEST_PRIORITY_TASK… This truly works and I never met up with any problems after that… FYI.
@zexalistic Keep in mind that you must not make FreeRTOS API calls from ISRs for priority-zero interrupts. Priority zero is the highest interrupt priority, and FreeRTOS critical sections do not mask that interrupt priority. If you make FreeRTOS API calls from those ISRs, you can easily corrupt kernel data structures. The application may seem to work but it would be extremely fragile.