ATXMega port and interrupts

harfaspaul wrote on Wednesday, January 19, 2011:

First of all, let me congratulate the involved people on the great job done with freeRTOS.
I am using a CodeVisionAVR port of freeRTOS on an ATXMega256A3. Everything seems to be working fine. I set up a “demo” project with several of the testing tasks existent with the freeRTOS distribution (integer and floating point maths, block queues, polled queues, semaphores, coroutines) - ran for 24h+ with no problems, so I would check it as usable. The only ISR I have now is the Timer0 ISR - the tick ISR.

I have a couple of questions related to further design of the application.

1) Interrupts: The XMega has 3 interrupt priorities (low, medium, high). I am planning to use the tick interrupt from Timer0 at low level, and USART, SPI, TWI interrupts at higher levels to reduce latency in communication as much as possible. The AVR ports do not use configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY. Does the rule about not using …FromISR() API functions still apply in this case? What exactly are the dangers of using these functions from a higher-priority-than-tick ISR?

2) Higher level ISR interrupting portSAVE_CONTEXT or portRESTORE_CONTEXT: if the compiler implements its own correct context saving/restoring for ISRs, is there any problem with this? Communication ISR response might be more important than switching tasks.

Thank you for your help, and have a great day!
Paul

rtel wrote on Wednesday, January 19, 2011:

I am using a CodeVisionAVR port of freeRTOS on an ATXMega256A3.

That is not an official port.  Have you posted it to the FreeRTOS Interactive site?  If not, please do.
http://interactive.freertos.org/forums/103473-atmel

The AVR ports do not use configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY. Does the rule about not using …FromISR() API functions still apply in this case?

Yes, the rule still applies.

What exactly are the dangers of using these functions from a higher-priority-than-tick ISR?

The kernel and queue data structures can get corrupted.

2) Higher level ISR interrupting portSAVE_CONTEXT or portRESTORE_CONTEXT: if the compiler implements its own correct context saving/restoring for ISRs, is there any problem with this? Communication ISR response might be more important than switching tasks.

The compiler will ensure that CPU registers are maintained across interrupts, but not that access to structures (or any other resource for that matter) will be done in a consistent state.  This is a mutual exclusion issue as any other, its not specific to FreeRTOS, but there are ways you can ensure correct access to the FreeRTOS data. 

If the tick is accessing the kernel structures, and the tick is itself interrupted by another interrupt that then proceeds to access the same structures, you will get corruption.

If you want to implement interrupt nesting in a way that allows interrupts of different priorities to use the ‘FromISR’ API functions then you will have to implement the portSET_INTERRUPT_MASK_FROM_ISR() and portCLEAR_INTERRUPT_MASK_FROM_ISR() macros.  The ‘SET’ version takes a note of the current interrupt priority level, then sets the priority mask up to that specified by configMAX_SYSCALL_INTERRUPT_PRIORITY().  The ‘CLEAR’ version sets the priority mask down to that noted by the ‘SET’ macro.

You can use the definitions of these macros in the Source/Portable/MPLAB/PIC32/portmacro.h file as an example.  Do not use the Cortex-M3 versions of the macros as an example as these are a special case.

You will also need to change the tick interrupt to ensure that the call to vTaskIncrementTick and the call to vTaskSwitchContext are surrounded by the SET and CLEAR macros.

Regards.