IAR EWARM version 5 stack alignment
Posted by Ricky
on September 29, 2009
2009-09-29 10:53:24 EST
I've been having an issue with IAR's EWARM version 5 where functions that take 8 byte arguments (double, long long) would have the argument misaligned on the stack. This was most noticeable in the printf and sprintf functions where a buffer overflow would occur as the misaligned double would try to format a number of over 200 digits.
After numerous tech support emails to IAR and an accidental discovery in one of their manuals, I discovered that the version 5 compiler requires the stack pointer to be 8 byte aligned when a function call is made.
Now as far as I know, FreeRTOS may already align the task stacks to 8 bytes. But I made modifications to the TCB where the registers would be stored there instead of on the task stack when a task switch was made. Apparently these modifications caused the stack to misalign and wreak havoc when I tried to upgrade to version 5.
I've noticed occasional emails to this forum describing a similar problem, so this post may be a solution.
I added the following line to tasks.c in the xTaskCreate function, between where pxTopOfStack is defined and pxPortInitialiseStack is called:
pxTopOfStack = (portSTACK_TYPE *) ((unsigned portLONG) pxTopOfStack & (~(8 - 1)));
The line insures that the stack will be 8-byte aligned when the task starts.
RE: IAR EWARM version 5 stack alignment
Posted by Richard
on September 29, 2009
Thanks for taking the time to report that here.
As far as I know the only time this makes a difference (now, also with Keil) is when using 8 byte types, as you say. Also as you say the time people tend to notice this is in sprintf() type calls.
The Virtex5 port was added recently and supports a double precision floating point unit. For that reason I had to release that port with 8 byte alignment, and in turn to get that working correctly actually had to update xTaskCreate() slightly which now contains the line:
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ) - ( ( usStackDepth - 1 ) % portBYTE_ALIGNMENT );
Not the most elegant solution, but the one that produces the fewest compiler warnings on the most number of compilers!
Version 6 of FreeRTOS actually moves the portBYTE_ALIGNMENT_MASK macros into the common portable.h header file instead of the individual portmacro.h files. I suppose I should really change all the ARM7 and ARM9 configurations to use 8 byte alignment by default. For now, this can be done simply by changing portBYTE_ALGINMENT, provided you are using the latest release version.
Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd..
See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.