johandc wrote on Thursday, February 04, 2010:
HI,
After 6 hours of debugging i finally found out why my ARM7 was crashing: (Short version below)
Scope: Inside USART ISR:
1) Call to portENTER_CRITICAL() - Increments ulCriticalNesting to 1
2) Magic happens, data is processed
3) Call to portEXIT_CRITCIAL() - decrements ulCriticalNesting to 0
4) PortEXIT_CRITICAL() sees that nesting is 0 and calls portENABLE_INTERRUPT() <-- This is the error!
5) Interrupts are now enabled, before exiting the USART ISR: Result :
6) Nested interrupt occurs, call to PortSAVE_CONTEXT() etc….
… At this point, the system has entered an invalid state since a nested interrupt occured, and invalid information was stored on the stack… The system will never return to running state, and in fact sooner or later (a couple of milliseconds later) a PREFETCH_ABORT interrupt is thrown by the processor.
This problem also exists in several other ports, for example the AVR32.
I think it is a general problem that portEXIT_CRITICAL() want’s to enable interrupts, disregarding the calling context. If FreeRTOS does not support nested interrupts, it should never enable interrupts unless the cpu is in system mode. The result is that no calls which are protected by critical sections can be called from within an iSR, which is a bit of a pain.
Please help me, is this a bug in AVR32 + ARM7 FreeRTOS?
Temporary FIx
I solved the problem by checking the status register for the running mode of the processor. If it runs in ISR mode, it won’t enable interrupts, and now it works… However, is this a good solution?