ISR rules in FreeRTOS book for PIC32

Hi! The FreeRTOS book for PIC32 states that an unmodified classic ISR (i.e. with no special RTOS wrapper in assembler) can still be used with FreeRTOS as long as the ISR does not cause a task to change state. Does that simply mean that the ISR should not make any FreeRTOS API calls or are there also other catches? Another rule is that a classic unwrapped ISR used with FreeRTOS must not be interrupted. But interrupted by what?
- By the kernel? I.e. ISR should have same or higher interrupt priority as the kernel?
- By another ISR that uses API calls?
- Or also by ANY other classic or FreeRTOS-aware ISR having a higher interrupt priority than my classic ISR? Please help me to clarify things as I want to use some ready made code already having ISRs and I am not sure if I would have to modify those ISRs to be FreeRTOS-safe or not. Thank you in advance! Best regards,
Anguel

ISR rules in FreeRTOS book for PIC32

The FreeRTOS book for PIC32 states that an unmodified classic ISR (i.e. with no special RTOS wrapper in assembler) can still be used with FreeRTOS as long as the ISR does not cause a task to change state. Does that simply mean that the ISR should not make any FreeRTOS API calls or are there also other catches?
As I recall, that pretty much sums it up.  A task can only change state through an API call being made.
Another rule is that a classic unwrapped ISR used with FreeRTOS must not be interrupted. But interrupted by what?
- By the kernel? I.e. ISR should have same or higher interrupt priority as the kernel?
- By another ISR that uses API calls?
- Or also by ANY other classic or FreeRTOS-aware ISR having a higher interrupt priority than my classic ISR?
Again, as I recall, it would mean by any interrupt that will enter through the FreeRTOS wrapper code. What you refer to as ‘classic’ interrupts enter through code that is generated by the compiler.  If you declare the function as an interrupt the compiler generated different function prologue and epilogue assembly code.  Again, if my recollection is correct, you can tell the compiler whether the body of the interrupt should run with interrupt enabled or disabled.  If you tell the compiler to enable interrupts then the compiler generated prologue code will include a line to enable interrupts.  Be aware that if you have ‘classic’ interrupts then the stack you have to allocate to each task will be much larger as it will have to (potentially) hold an entire interrupt stack too. If you enter an interrupt through the FreeRTOS wrapper code, then there is a lot of ‘extra’ stuff that goes on.  For example, it keeps a note of whether interrupts are nested or not, and only re-enables interrupts that have a priority higher than the currently executing interrupt.  It also switches to a dedicated ISR stack to radically reduce the amount of RAM that has to be allocated to the stack of each task – because the task stacks will only ever have to hold the task stack, and never a (potentially nested) interrupt stack on top. Because of the extra code in the FreeRTOS wrapper (the interrupt nesting count, stack swapping, etc) you cannot mix ‘classic’ and FreeRTOS interrupts in the same nesting. You could probably have a ‘classic’ interrupt nest with an existing stack of nested ‘FreeRTOS’ interrupts, so the ‘classic’ interrupt stacks are always on top (I think the FreeRTOS demo does this with a high frequency timer, but would have to double check), but never intermingle the two or have a FreeRTOS interrupt on top of a classic interrupt. Regards.

ISR rules in FreeRTOS book for PIC32

Richard, Thank you very much for the detailed explanation! Looks like things are not that easy :) I asked about the ISRs because the Microchip USB stack for example uses ISRs and I just wondered if I will have to convert them to wrapped FreeRTOS ISRs or I could just leave them as they are. But looks like I have to understand the things in much deeper details before I can decide… BTW: On your website there is an ad for the Microchip Multimedia Expansion Board stating that there is a FreeRTOS example for it. I have this board but I did not find such an example anywhere. Do you have any details about that? Thanks! Regards,
Anguel

ISR rules in FreeRTOS book for PIC32

Try this: http://tinyurl.com/69mhwry but note it is not code I wrote myself and cannot support it myself. Regards.

ISR rules in FreeRTOS book for PIC32

Many thanks! I will try to understand how things work :) It is a lot of new stuff and Microchip does not provide very good docs for their stacks, so there is a lot of things to dig through… Also understanding an RTOS and actually managing to use it correctly seem to be two different things :)

ISR rules in FreeRTOS book for PIC32

Do you have a copy of this application note? http://tinyurl.com/5u2es4b  If not, it might help. Regards.

ISR rules in FreeRTOS book for PIC32

Yes, I have this application note already, but the USB stack is not used there. Actually, I suspect that using **polled **mode for the USB stack together with an RTOS should be better than using the **interrupt **mode, but I may be also wrong? Thank you very much again for the information and for the nice explanations in the book!

ISR rules in FreeRTOS book for PIC32

Looking at the PIC32 port information given on the FreeRTOS website I get the impression that making all ISRs use the assembler wrapper is the preferred way to program ANY interrupt when FreeRTOS is used. And therefore ALL interrupts should be changed to use the assembler wrapper. This did not become very clear to me while reading the FreeRTOS PIC32 book. Or are there possibly any drawbacks when using wrapped interrupts? Regards,
Anguel

ISR rules in FreeRTOS book for PIC32

One very minor one is that you have to write the wrapper by hand instead of just telling the compiler a function is an interrupt handler. That is very easy though, you just cut and past the wrappers supplied in the demos, and use the macros supplied in the FreeRTOS port. I suppose one other is that the wrappers give you the ability to nest interrupts and to swap to an interrupt stack, which takes a bit longer to execute than compiler generated interrupt code. The benefits greatly outweigh the extra CPU cycles though in nearly all cases. That is especially true when you consider the amount of RAM swapping stacks saves you.

ISR rules in FreeRTOS book for PIC32

Thanks for the good explanation, Dave! I tried this myself and noticed that if I create a task with a small stack it will overflow whenever my interrupt occurs. But if I use the assembler wrapper the stack watermark does not change at all. But the more I think about it, the more I wonder why the PIC32 FreeRTOS book does not point the reader to these important things. On page 5 it is mentioned briefly that the PIC32 port can use a special ISR stack but that’s it.

ISR rules in FreeRTOS book for PIC32

What I do not understand is how the size of this special interrupt stack is determined and how to watch for overflow. Is there any information on that?

ISR rules in FreeRTOS book for PIC32

configISR_STACK_SIZE in FreeRTOSConfig.h

ISR rules in FreeRTOS book for PIC32

Many thanks!