Hello, I am playing with a system based on LPC2368 and I gave the FreeRTOS a try. Everything worked well, but when I go to sending data into a queue from within an interrupt (with the intention to wake up specific tasks) my code began unstable. The offending command seems to be xQueueSendToBackFromISR(). There is nothing (yet) on the other side of the queue and once I put xQueueSendToBackFromISR into the ISR routine, the code crashes after some seconds. I use GCC/ARM7_LPC2368 port, modified a little bit around the system tick (I use Timer 1). The xQueueSendToBackFromISR() I call from a ISR for transitions on some GPIO inputs. The interrupt routine itself seems to work fine. I use GCC arm-elf, with arm-none-eabi I’m not getting a working code. I would appreciate if someone had suggestions what could I check or how to debug it. Thank you, Pawel.
When you wrote your interrupt routine, did you follow the instructions on the freeRTOS site? You need a wrapper function in assembler.
No, I didn’t, I followed the way the system timer tick was written in the ARM7_LPC23xx port and it seemed to work fine.
Please give me a pointer to those instructions, I can’t find them right away.
I think it is mentioned on a lot of pages, but here is one to start with: http://www.freertos.org/portlpc2106.html Read the “Interrupt Service Routines” section, where it talks about an assembly wrapper. Depending on your version of GCC, you may find that the call to the C function from the assembly wrapper also needs to be done using an asm statement.
Well, it did help, thank you very much !
The comments say that the wrapper around the interrupt service is needed when the interrupt routine switches the context.
My routine does not switch the context (yet…) but it calls RTOS routines - thus you need the wrapper is cuh case already.
Thank you again.
I have a question here: if an interrupt routine does not engage system calls and/or a context switch every time - could one optimize it and save/restore context not every time ? For example am I2C ISR would most of the time only serve the hardware and like at the end of the transfer might want to release z MUTEX and/or wake a tak. Does one need to do the context overhead every time it is called ?
If you can predict in advance, without using any CPU registers, whether a context switch is needed, then you don’t need to save the context first - but of course that is impossible. If it is not really critical that you switch context in the ISR then you don’t need to save and restore at all for that particular ISR (if the ISR wakes a higher priority task, then the task will be selected at the next tick interrupt anyway, whether your application can tolerate that depends on your own personal real time requirements) - but different versions of GCC have very different bugs in their interrupt entry and exit code for the ARM7 core, so you are still better off writing your own assembly code entry routine.
Do you mean that because of those bugs in GCC you should save/restore context explicitly for every interrupt routine regardless of whether it switches the context or not ?
I’m saying that there are very few, if any, versions of GCC for the ARM7 where the __attribute__((IRQ)) syntax will generate correct code in all cases - therefore it is always safest to define your own interrupt entry prologue, regardless of what the interrupt is doing. If the interrupt is performing a context switch, then use the macros provided by FreeRTOS, if the interrupt is not performing a context switch, then you can probably save fewer registers.