I'm just starting out porting some code I have developed for controlling a robot into FreeRTOS. We got away with a fair amount of complexity with ground-up coding, but it's at the level now where a real RTOS will help manage current and future system complexity. And it's a good learning exercise. This is all for an academic research application, too.
I'm a little uncertain what to do about interrupts that "need" to stay in the code, like for example, the _DMA0Interrupt that is being used to copy values from DMA RAM to some named variables, to be accessed by other code with getter function. This is done to have high-speed ADC sampling (triggered automatically by the PWM hardware generator), and thus give a zeroth-order-hold of the sampled sources to other code modules.
The current interrupt code is simple: http://pastebin.com/8n9sH1gR
So, the code doesn't call any FreeRTOS functions, so nothing will be blocking waiting on the result of this function. If I understand correctly, this means that it can not cause a context switch?
What I'm not sure of it, do I have to worry about other hardware interrupts potentially firing during this interrupt? A higher priority interrupt, like the radio pin interrupt, might fire at any time and cause a complex task that would involved OS API functions and task blocking/unblocking to happen.
Similarly, will the existence on non-API-using hardware interrupts like this have a bearing on how I will need to design the ISR's that do use API functions, and their dependent tasks?
Any input on this topic would be greatly appreciated.
On the dsPic (based on your subject), all interrupts that interact with FreeRTOS are on a single level, normally the lowest, so you can avoid your ISR which doesn't interact with FreeRTOS from being blocked by one of those by just putting it on a higher level. It also means that since it doesn't interact with FreeRTOS in can't unblock a task.
If it needs to unblock a task, that requries placing it on the same level as the other ISRs, and thus possibly delayed by them, or having it trigger some other interrupt (possibly from an unused device) that is at the lower level to do the interaction.
Having an interrupt at this higher level shouldn't affect your other ISR's as long as it doesn't manipulate something that those other interrupts need to manipulate without interruption.
Ah, great, thanks Richard, that helps clear things up. Yes, this is on dsPIC33F. I suppose that means that I can juggle the interaction of non-API interrupts in the higher CPU interrupt priority levels.
This is a little daunting, since it seems there are several mechanisms for concurrency of different sorts, and I need to figure out which type to use for each part of the code, like multiple SPI and I2C buses.
I had a follow-up question on the same topic: for the hardware ISR's that will make API calls, like the radio-data-ready external interrupt, will I still need an assembly file wrapper as described in the PIC32 version of the documentation? I don't think I see any examples of this in the dsPIC example code, such as in serial.c for the _U2*XInterrupt's .
The PIC24/dsPIC are a different beast than the PIC32, and their port layer does not use a wrapper, just write them as normal interrupt functions. The only major requirement is that the test if taskWoken and calling of vPortYIELD do need to be the very last part of the ISR, as any code after that might get delayed executing if a task switch occurs (the task switch is written so that it can be the leaving from an ISR, and the remainder of the ISR won't be executed until the switched from task gets to execute again.