How to change the priority of an ISR?

joe0x7f wrote on Sunday, December 30, 2012:

On page 155 of the “Using The FreeRTOS Real Time Kernel, NXP LPC17xx Edition” 2nd edition book, it says, “Do not use any <FreeRTOS> API functions from an interrupt <ISR> that has been assigned  an interrupt priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.”

My question is how can I violate this rule?
If I am reading/understanding this correctly, how can I change the priority of an ISR?  Is there more than one way to change this priority?

Thanks!

rtel wrote on Monday, December 31, 2012:

All the (non exception) interrupt priorities can be configured directly by writing to the NVIC (Nested Vectored Interrupt Controller) registers, which are part of the Cortex-M3 core.  Working out how to do this directly is however somewhat difficult and required reading the Cortex-M technical reference manuals from ARM (to get the register addresses) and the datasheet from the microcontroller manufacturer (to find which peripheral interrupts map to which NVIC interrupts).  Therefore, these days at least, it is extremely rare to try and do this yourself.  Instead there are library functions that make the task much easier.

If you are using CMSIS libraries then you can use the NVIC_SetPriority() function.  For example on the LPC17xx you can call NVIC_SetPriority(TIMER0_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY); to give an interrupt priority the maximum value allowable if it uses a FreeRTOS API function .

Other manufacturers use different API functions, but the CMSIS version is normally available too.

There are two things that complicate it further (interrupts on the Cortex-M are generally more complex than other CPUs):

1) Different microcontrollers implement a different number priority bits.  Again if you are using CMSIS you should have __NVIC_PRIO_BITS defined which tells you how many there are.  On the LPC17xx I think it is 4, so priorities can go from 0 (the highest) to 0x0f (the lowest).

2) The priority bits are sub-divided into preemption priority and sub priority.  You want all the bits to be assigned to be preemption priority bits, and that is the default in the NXP libraries so you need not worry about that (generally in my experience the libraries from ST are the only ones where this is not the case.

Further reading on the subject if you are feeling brave:
http://www.freertos.org/RTOS-Cortex-M3-M4.html

Regards.

joe0x7f wrote on Monday, December 31, 2012:

Thanks Richard!

How do we tell what priority an ISR has relative to the other tasks?

rtel wrote on Monday, December 31, 2012:

Don’t confuse interrupt priorities with task priorities. 

Interrupt priorities are purely a hardware thing.  Task priorities are purely a software thing.  Tasks have the ability to mask out interrupts, but if interrupts are not masked they will always interrupt a task - even if it is the lowest priority interrupt that is interrupting the highest priority task.

Regards.

joe0x7f wrote on Monday, December 31, 2012:

So FreeRTOS can mask interrupts with this:

taskENTER_CRITICAL() and taskEXIT_CRITICAL() sections of code.

Are there other FreeRTOS ways of doing this?

Thanks!

rtel wrote on Monday, December 31, 2012:

It is intended that taskENTER_CRITICAL() and taskEXIT_CRITICAL() is the only method used as these count the call nesting depth.  For example, if you call ENTER_CRITICAL() twice you also have to call EXIT_CRITICAL() twice before interrupts are unmasked again.

Regards.