nobody wrote on Wednesday, October 26, 2005:
Hey all,
I’m trying to migrate from IAR to Rowley tools, which use GCC.
It is important to note that everything below should be read knowing that the exact same code (save for GCC/IAR extension differences) has been working fine under IAR.
I’m compiling the project under THUMB release with no optimizations. portISR.c is compiled under ARM, and of course Interworking is enabled.
As no Rowley SAM7S port is available, I’ve decided to do something based on the GCC SAM7 port (found under Source\portable\GCC\ARM7_AT91SAM7S).
My program lives (peripherals initializing well, etc), but when it gets to starting the scheduler, bad things happen.
It goes to xPortStartScheduler() (from the generic scheduler init code), after tasks have been created successfully.
From there, it goes to vPortISRStartFirstTask(), which is located under portISR.c. GCC Interworking does it’s magic, the processor is under ARM mode.
Now what happens in vPortISRStartFirstTask() is that the Scheduler attempts to restore the idle task context and start running from there, using the portRESTORE_CONTEXT() macro (defined in portmacro.h). While in this macro, the system hangs (jumps to data abort vector).
From what I understand, the culpruit lies in these three lines:
========================
/* Restore all system mode registers for the task. */
asm volatile ( "LDMFD LR, {R0-R14}^" );
asm volatile ( "NOP" );
/* Restore the return address. */
asm volatile ( "LDR LR, [LR, #+60]" );
What happens is that LR is loaded with the default TCB stack initialization data (from port.c/pxPortInitialiseStack()), in this case that equals to 0xaaaaaaaa.
Needless to mention, LDR LR, [LR, #+60] yields an alignment error (and the resulting data abort exception).
In the IAR port case (SAM7_IAR), with different synatx yet nearly identical assembly (in ISR_Support.h>, the above lines seem to load everything BUT R13 and R14, despite being 100% identical!
What did I miss?