The documentation says that interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY are not delayed by the kernel. (Among other places, in the FreeRTOS customization page’s configKERNEL_INTERRUPT_PRIORITY section: “Interrupts with priority above configMAX_SYSCALL_INTERRUPT_PRIORITY are never delayed by the RTOS kernel activity.”
However, the Cortex-M MPU ports don’t meet that promise as of kernel 11.3.0. xPortStartScheduler() writes SHPR2 = 0, making SVCall the highest-priority exception in the system. With the v2 MPU wrappers, every FreeRTOS API call made by an unprivileged task enters and exits the kernel through SVC. While those handlers run at priority 0, every interrupt is blocked — including application interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY whose timing the kernel promises not to affect.
I was able to fix this on my system (STM32H7A3, Cortex-M7 r1p1 @ 280 MHz, GCC, mpu_wrappers_v2, 16 MPU regions, all tasks unprivileged, 4 priority bits,configMAX_SYSCALL_INTERRUPT_PRIORITY at NVIC level 5, configSVCALL_INTERRUPT_PRIORITY at level 4) by making the SVCall priority configurable: a new configSVCALL_INTERRUPT_PRIORITY, written to SHPR2 in place of the hardcoded 0. I placed this below my time-critical ISR band, so that those ISRs now preempt SVC dispatch. The SVCall priority has to be numerically lower than configMAX_SYSCALL_INTERRUPT_PRIORITY so that the scheduler startup works.
I’m curious to see what everyone thinks of this and if I’ve missed anything.