NVIC priority vs FreeRTOS priority

Hello,

I am confused about priorities configuration and I am not sure if my configuration is good. In my project I am using LPC1767 microcontroller and set the same priority (7) for my interrupts:

  NVIC_SetPriority( UART0_IRQn, 7);
  NVIC_SetPriority( UART1_IRQn, 7);
  NVIC_SetPriority( UART2_IRQn, 7);
  NVIC_SetPriority( UART3_IRQn, 7);  
  NVIC_SetPriority( TIMER1_IRQn, 7);
  NVIC_SetPriority( TIMER3_IRQn, 7);
  NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY); //priority 5

Could you please confirm that all my NVIC interrupts have correct priority set according to configMAX_SYSCALL_INTERRUPT_PRIORITY?

If I correctly understand, all my used NVIC interrupts must have lower (higher number for NVIC_SetPriority()) priority compared to configMAX_SYSCALL_INTERRUPT_PRIORITY.

Part of my FreeRTOSConfig.h:

#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS       __NVIC_PRIO_BITS
#else
#define configPRIO_BITS       5        /* 32 priority levels */
#endif

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY     ( 31 << (8 - configPRIO_BITS) )
/* Priority 5, or 160 as only the top three bits are implemented. */
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( 5 << (8 - configPRIO_BITS) )

/* Priorities passed to NVIC_SetPriority() do not require shifting as the
function does the shifting itself.  Note these priorities need to be equal to
or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric
value needs to be equal to or greater than 5 (on the Cortex-M3 the lower the
numeric value the higher the interrupt priority). */
#define configEMAC_INTERRUPT_PRIORITY        5
#define configUSB_INTERRUPT_PRIORITY        6


/*-----------------------------------------------------------
 * Macros required to setup the timer for the run time stats.
 *-----------------------------------------------------------*/
#ifdef __ICCARM__
#include "LPC17xx.h"
extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() TIM0->TC
#endif

Looks ok to me. However, the following comment is not correct:

The LPC1767 appears to implement 5 bits (not 3), so interrupt priority 5 becomes 5 << (8-5) or 40.

Thank you for your answer. I wonder why my program hangs in vListInsert() loop. So it seems this problem does not related to my interrupt priorities.

Does the issue still occur when you correct the priority settings? An incorrect setting will break critical section handling, resulting in corruption (sometimes), which can manifest itself in any number of ways. For example, corrupting a member of a list.

Some years back I created a page that attempts (?) to explain the priority settings on Cortex-M devices because, at that time, most support requests on those devices were eventually tracked to incorrect priority settings.

If you have configASSERT() defined to something useful, and if you are running kernel v10 or newer, then configASSERT() statements in the Cortex-M3 port will tell you if you have an issue in your interrupt-priority configuration.

One common cause is forgetting to set the priority of an interrupt. By default, the priority is zero (the highest priority, and too high to make FreeRTOS API calls).

For interrupts that I use in my program (uart, timers and ethernet) I set priority to 7, which is lower than syscall 5. Priorities for these interrups are set at initialization, before NVIC_Enable. In some cases my program Disable and Enable these interrupts. Do I need to set priorities every time after I Disable interrupt? What about Watchdog and Hardfault interrupts, whose I also enabled, but priority left default and using for debugging?

No.

No worries about those handlers. They don’t call FreeRTOS APIs.

How is configASSERT() defined, and what version of the kernel are you running?

My version 9… I will think about upgrading to 10.
Strange is that my program ran without this issue for couple of years… Also I use heap 2 and I have enabled stack overflow checking, but no overflow occurs.

If configMAX_SYSCALL_INTERRUPT_PRIORITY after bits shifting result is 40, does it mean my Uart, Timer, Ethernet interrupt priorities have to be set to >=40?

No, your own interrupt priorities are “pre-shift”, as long as you set the priorities with NVIC_SetPriority(). Many FreeRTOSConfig.h files include an unshifted version of configMAX_SYSCALL_INTERRUPT_PRIORITY as a coding convenience. By convention it is called configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. In your case it would be 5.

You can try the latest version 11 too.