This is quite a long post – but in summary I think you are probably trying to fix a problem that does not exist – but I’m happy to be proven wrong….
n order to achieve this, it seems that FreeRTOS has a define called: portBYTE_ALIGNMENT. FreeRTOS then has a mechanism inside heap_1.c and heap_2.c that ensures that they return blocks aligned according to portBYTE_ALIGNMENT. However there is no guarantee that heap_3.c will return an 8 byte aligned block, but experience with newlib has shown that it does. So far so good. But…
Relying on this alone does not guarantee the correct alignment because the alignment requirement is greater than sizeof( portSTACK_TYPE) .
Subtracting 1 from the pointer now makes it aligned to only 4 bytes. And this breaks floating point compatibility with all the latest GCC compilers using the EABI. (Such as Codesourcery G++ and Yagarto).
If you have a correctly aligned buffer to start with, then add an even number of sizeof( portSTACK_TYPE ) bytes (usStackSize is an even number), you will end up on a four byte boundary once the 1 has been subtracted. On the other hand, if you start with a correctly aligned buffer to start with, then add an odd number of sizeof( portSTACK_TYPE ) bytes (usStackSize is an odd number) you will end up on an eight byte boundary once the 1 has been subtracted.
The fix can be done either by subtracting 2 from the pointer in task.c
The situation you describe cannot be fixed by doing this, you just switch around whether it works with an odd or even usStackSize.
or as it was done for the Cortex-M3 port between version 6.0.0 to 6.0.1, an offset can be added in portMacro.h
Fell into that trap myself once – the fix for the cortex and the ARM7 are unfortunately not the same – the processors behave differently regarding the stack pointer on start up.
As shown above, also the usStackDepth is affecting the alignment of a pointer.
Exactly, hence what you do above that (how the buffer is aligned to start with) does not make that much difference.
This means that the stack depth must always be dividable with 2 in order for 8 byte alignment to work. A more secure solution would be to check the portBYTE_ALIGNMENT at runtime and subtract from the pointer until it is properly aligned.
while ((portSTACK_TYPE) pxTopOfStack % 8)
pxTopOfStack-;
My reasoning is that the line:
pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) );
Corrects the alignment (assuming the stack grows down) once all the calculations have been complete – hence I don’t know why you would be seeing a problem. Are you seeing a problem?
The problem with the alignment correction code at the moment is that where sizeof( portSTACK_TYPE * ) is less than sizeof( unsigned long) by rights the compiler should output a warning. Remember this code has to work on all combinations of sizeof( portSTACK_TYPE * ) , big endian, little endian, 8 bit, 16 bit and 32 bit devices. Its quite tricky.
Regards.