More questions on configMAX_SYSCALL_INTERRUPT

cmp1104 wrote on Thursday, September 06, 2012:

I am using FreeRTOS v7.02 with an Energy Micro microcontroller (Cortex M-3 port).  I have already made a version of my application and it works, so I have a baseline.  Now I am overhauling the code.  The application is very much interrupt driven and I am using the “built-in” EFM32 interrupts and their priorities as defined in the startup file:
DCD GPIO_EVEN_IRQHandler  ; 1: GPIO_EVEN Interrupt
DCD TIMER0_IRQHandler  ; 2: TIMER0 Interrupt
DCD USART0_RX_IRQHandler  ; 3: USART0_RX Interrupt
etc.

Originally I created identical code for the GPIO_EVEN_IRQHandler and GPIO_ODD_IRQHandler functions.  However I now want these functions to call a single function to perform basic interrupt handling duties before it gives a semaphore to unblock a task.

My question is this:
1. In reading through all the information on interrupts and FreeRTOS, I saw that configMAX_SYSCALL_INTERRUPT_PRIORITY defines “the highest interrupt priority from which FreeRTOS API functions can be called”.  My config file defines configMAX_SYSCALL_INTERRUPT_PRIORITY as 191 (equivalent to priority 5).  However the GPIO_EVEN Interrupt has a priority of 1 and I was able to use _FROMISR functions in this interrupt handler with no problem (that I could tell).  Was this a time bomb of a problem waiting to happen?  (The GPIO interrupts are always interrupting the Idle Task so the risk of corrupting data is minimal.  I also understand that ARM uC do their priorities so that the lower the interrupt priority number, the higher the priority.)

Thanks.

Thanks.

davedoors wrote on Thursday, September 06, 2012:

Was this a time bomb of a problem waiting to happen?

In a word “yes”.

There is nothing to stop you calling API functions from interrupts with a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY, but there is also nothing but luck stopping those interrupts from causing damage because they can nest with interrupts that are accessing the same RTOS data structures (including the RTOS tick).

cmp1104 wrote on Thursday, September 06, 2012:

Okay, I think this is starting to become a little clearer. 

Is this description correct:  My GPIO_EVEN interrupt has a priority of 1 and GPIO_ODD interrupt has a priority of 9 (i.e. EVEN has a higher priority than ODD).  The RTOS kernal has a priority of 255 (lowest possible priority).  In terms of FreeRTOS task execution, tt does not matter if I get an interrupt on EVEN or ODD, the task will be immediately suspended while the interrupt is handled.  However, if the ODD handler is executing and accessing an RTOS data structure such as a queue, and a GPIO_EVEN interrupt occurs, the EVEN handler will take over and there is nothing protecting the queue and it can be corrupted. In the reverse situation, where the EVEN handler is accessing a queue first  and a GPIO_ODD interrupt occurs, the queue is protected.  Or if we were dealing with a situation in which all interrupts had a priorites < configMAX_SYSCALL_INTERRUPT_PRIORITY, the queue would be protected.

Is this basically correct?

davedoors wrote on Thursday, September 06, 2012:

I think you are making this more complicated than it is. The rule is quite simple, and already stated in your previous post. Any interrupt that uses the FreeRTOS API must have a priority at or below configMAX_SYSCALL_INTERRUPT_PRIORITY.  Therefore -

In the reverse situation, where the EVEN handler is accessing a queue first  and a GPIO_ODD interrupt occurs, the queue is protected.

no. That is still dangerous.

The tick interrupt protects critical sections by raising the interrupt mask. If an interrupt has a priority above the masked value (higher than configMAX_SYSCALL_INTERRUPT_PRIORITY) it can execute while the tick interrupt is accessing critical code. If the interrupt uses a queue, and that queue changes the state of a task while the tick interrupt is simultaneously trying to change the state of a task, then you have potential trouble.

cmp1104 wrote on Thursday, September 06, 2012:

I am not completely familar with the tick interrupt (I’m still learning the details of FreeRTOS) but from looking through the code it looks like the tick interrupt is what is used to organize task execution based on what happened in between tick interrupts. 

I don’t have parts of my code identified as critical but found parts of the RTOS that are.  So in the example I had above, with GPIO_EVEN having a priority of 1 and configMAX_SYSCALL_INTERRUPT_PRIORITY having a priority of 5, the GPIO_EVEN interrupt handler could change a semaphore (or queue) value and prevent the tick interrupt handler from properly managing the tasks.  Is this about right?