Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem



Posted by alsaleem on April 9, 2017

I have an application on STM32F4 that has many interrupts. some have high priority and others have low priority.

My freeRTOS file config has these values (the default).



The controller has 4 priotity bits (#define _NVICPRIOBITS 4U). This results in 16 levels. Both configKERNELINTERRUPTPRIORITY & configMAXSYSCALLINTERRUPTPRIORITY will take priority greater than 16

(1) Is my conclusion correct? (2) How to modify these to allow to categorize interrupts with priorities higher or lower than sysTick? SysTick interrupt calls HAL_IncTick/osSystickHandler.

(2) Knowing that interrupt should be short and processing should be done later, my application can not wait the task (the task that does processing) to take its "turn" to do processing. Is there a way to force scheduler to switch to a specific task from ISR?



Posted by heinbali01 on April 9, 2017

My freeRTOS file config has these values (the default).



That all looks OK to me.

The controller has 4 priority bits (#define __NVIC_PRIO_BITS 4U). This results in 16 levels.

Level 0 is the normal (non-interrupt) level, so 15 levels remain, from 15 (low) to 1 (high). Correction, that should have been: Indeed 16 different priorities, 15 being the lowest, 0 the highest. Priority 0 can not be masked.

Both configKERNEL_INTERRUPT_PRIORITY & configMAX_SYSCALL_INTERRUPT_PRIORITY will take priority greater than 16


The value of these macro's will be used to write NVIC registers. The configLIBRARYxxx macro's have a number between 0 and 15, and can be used to call NVIC_SetPriority().

Consider configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY as a bit-mask of the form "pppp....", that can be used to set an NVIC register.

Knowing that interrupt should be short and processing should be done later, my application can not wait the task (the task that does processing) to take its "turn" to do processing. Is there a way to force scheduler to switch to a specific task from ISR?

Yes of course, the best ways is to have the task block on ulTaskNotifyTake() and wake it up from an interrupt by calling vTaskNotifyGiveFromISR() with a handle to that task. That task will be come active immediately, provided that it has the highest priority of all runnable tasks at that moment. Once your application is debugged, remember to switch off options for stack checking, to disable configASSERT(), and enable compiler optimisations.

An example from FreeRTOS+TCP is:

~~~ void HALETHRxCpltCallback( ETHHandleTypeDef *heth ) { BaseTypet xHigherPriorityTaskWoken = pdFALSE;

/* Ethernet RX-Complete callback function, elsewhere declared as weak. */
/* Wakeup the prvEMACHandlerTask. */
if( xEMACTaskHandle != NULL )
	vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

} ~~~

More text in this post



Posted by hs2sf on April 9, 2017

(1) Your conclusion is correct but remember these are low-level HW values. You should also have as look here for further details.

(2) What's the purpose for interrupt priorities lower than SysTick interrupt prio ? SysTick interrupt usually has the lowest prio to avoid interferences with any other interrupt used.

I've added a tiny helper macro in FreeRTOSConfig.h to help myself dealing with logical rather than HW interrupt priorities. So the logical prio order is the same as the FreeRTOS task prio order.

// helper macro for logical -> real Cortex-M interrupt priorities ~~~ // logical [0 .. IntPrio] => real [configLIBRARYLOWESTINTERRUPTPRIORITY .. configMAXSYSCALLINTERRUPTPRIORITY]

define uxPortIntPrio(p) ( UBaseTypet(configLIBRARYLOWESTINTERRUPTPRIORITY) - p )


and I'm using when calling the NVIC CMSIS interface:

NVIC_SetPriority( IrqNumber, uxPortIntPrio( IntPrio ) );

with a used prio range low..high = 1..N i.e. intentionally above SysTick interrupt prio 0

(3) Your priority scheme should ensure that the priority driven scheduler runs the desired task(s). So if you want to run a certain post-processing task signalled by its 'coupled' ISR you should consider them as an corresponding pair. E.g. if you have a very latency sensitive HW interface you should give the interrupt and its associated handler task the highest prio. Obviously the prios selected should match your overall application requirements i.e. taking into account your other HW interfaces/ISRs and tasks. Also keep in mind that FreeRTOS task (software) priorities are are not directly related to HW interrupt priorities.

Good luck, HS2


Posted by rtel on April 9, 2017

Normally SysTick and PendSV should be the lowest priority interrupts in the system. Therefore it is not possible have an interrupt hat has a priority lower than them.

STM32 is an exception to this IF you are using the drivers generated by the STM32 Cube. PendSV MUST still be given the lowest interrupt priority, but unfortunately due to the way the STM32 drivers are implemented SysTick will need to be the highest interrutp priority. That is because the implementation of the drivers busy wait inside interrupts for the tick count to change (yes!), and that will cause a deadlock if the SysTick has a priority lower than the busy waiting interrupt. Please do not take that as an example of best practice!

Note priority 0 is a valid interrupt priority, and in fact is the highest priority possible, and the default priority for any interrupt. That is why interrupts that use the FreeRTOS API must not use the default priority assigned to the interrupt. The confusion comes because priority 0 cannot be masked, and writing 0 into the mask register (BasePRI) unmasks all interrupts.

Interrupt priorities on ARM Cortex-M are complex, which is why we have this page to try and explain it: http://www.freertos.org/RTOS-Cortex-M3-M4.html and the newer the version of FreeRTOS you have the more configASSERT() statements have been included to automatically catch misconfigurations.


Posted by alsaleem on April 9, 2017

Thank ALL for this thorough explanation. I realized that I missed diffrentiating priorities when creating tasks.

I appreciate your help.

[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


FreeRTOS and other embedded software careers at AWS.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers


STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner