johughes2002 wrote on Monday, January 05, 2009:
I’ve been working on an str730 port for a while, based on the str750x code.
I had the scheduler running very smoothly with several tasks, etc, and started working on my actual app. Only then have I run into a very odd issue.
In my app I’m setting up an ISR in addition to the tick ISR to respond to both rising and falling edges (push button) on a GPIO port and stick a message onto a queue: http://pastebin.com/m7eb2ae2a
The messages are received by another task which processes them.
I’m setting up the hardware for the ISR as follows:
EIC_ExternalITFilterConfig( ENABLE );
Now, this runs about 80% of the time without issue. But the odd time I push the button, I get a Prefetch Abort. The most reliable way of reproducing the issue is to just hammer on the button as fast as possible.
Setting a breakpoint on the prefetch handler doesn’t help much. $lr is typically holding something like 0xe1a00000. Subtracting 4 gives me the address that was attempted to prefetch, but I have no idea which line was telling it to prefetch there.
The IRQ Handler is nearly the same as the str750 port: context is saved and restored automatically before the ISR routine is called: http://pastebin.com/m5d0de0b6
portSAVE_CONTEXT and portRESTORE_CONTEXT are verbatim the same as str750.
After trying and playing with everything I could think of for the past few days, I still haven’t come up with any really good idea for what is possibly wrong. The issue appears to be a race condition somewhere.
A hunch might be this: In the IRQHandlers "ReturnAddress" section, the IPR bits (interrupt pending) are cleared, and then portRESTORE_CONTEXT is called. Would it not be possible then that an interrupt occurs during portRESTORE_CONTEXT, or during the ReturnAddress section, and somehow corrupts the stack?
Any hits would be very helpful. I’m at a loss on this one.