heinbali01 wrote on Sunday, April 09, 2017:
My freeRTOS file config has these values (the default).
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
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
Correction, that should have been:
Indeed 16 different priorities,
15 being the lowest,
0 the highest. Priority 0 can not be masked.
configMAX_SYSCALL_INTERRUPT_PRIORITY will take priority greater than 16
The value of these macro’s will be used to write NVIC registers.
configLIBRARYxxx macro’s have a number between 0 and 15, and can be used to call
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 HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Ethernet RX-Complete callback function, elsewhere declared as weak. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Wakeup the prvEMACHandlerTask. */
if( xEMACTaskHandle != NULL )
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
More text in this post