Problems with r5.1.2, IAR EWARM 5.30, ATSAM7S

mikej42 wrote on Thursday, March 19, 2009:

Hello all
I have a product with the Atmel ARM7 AT9SAM7S256 running using freeRTOS 5.1.2 originally using IAR EWARM 4.42, and I am trying to move it to v5.30. The product sort of runs (!) but behaves erratically and some sprintf typ eoperations don’t work as expected, particularly printing the (dramatically) wrong values.

I have started a discussion with IAR, who say the the biggest cause of this sort of problem is stack missalignment. v5 comilers need/expect 8byte allignment on the stack when entering/leaving C functions.

It seems that the freeRTOS5 attempts to match this , but I have a problem in my understanding. When creating a new task, tasks.c gets an aligned stack which I have ensured is a multiple of 8bytes in size by making sure usStackDepth is even. Then the top of stack pointer is guaranteed to be 4 byte aligned as
    pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
Then pxPortInitialiseStack adds 17 4byte registers to the stack. It seems to me that this ought to be 18 registers, and the portRESTORE_CONTEXT and portSAVE_CONTEXT macros need adjusting similarly, or am I misunderstanding it all?

Any helpful hints comments and thoughts gratefully received.

Mike N

davedoors wrote on Thursday, March 19, 2009:

Check portBYTE_ALIGNMENT is set to 8 in portmacro.h. Also check that semi-hosting is turned off in the project options.

mikej42 wrote on Thursday, March 19, 2009:

Hi Dave
Got those two bits correct, but still get different builds showing different behaviour, particularly about sprintf, but also occasional crash.

Thanks

Mike N

mikej42 wrote on Monday, March 30, 2009:

Hi again Dave
I have been looking further into my (possible) stack alignment problem, and have com across the following:

In xTaskCreate, if usStackDepth is even, pxTopOfStack will always be an odd value, representing a none-8byte aligned stack, and thus giving me my problems with some functions. If I force usStackDepth to be odd, this effectively forces pxTopOfStack to be even, so the stack starts (and will remain) 8byte aligned.

Does this make sense?

By observation, this seems to give a reliable build, with all the combinations of optimisatoins and such that I have tried, but I would like:
a)

mikej42 wrote on Monday, March 30, 2009:

had finger trouble there! Message should be:

Hi again Dave
I have been looking further into my (possible) stack alignment problem, and have com across the following:

In xTaskCreate, if usStackDepth is even, pxTopOfStack will always be an odd value, representing a none-8byte aligned stack, and thus giving me my problems with some functions. If I force usStackDepth to be odd, this effectively forces pxTopOfStack to be even, so the stack starts (and will remain) 8byte aligned. 

Does this make sense?

By observation, this seems to give a reliable build, with all the combinations of optimisatoins and such that I have tried, but I would like:
a) is this a sensible explanation of the problems I have been seeing.
b) an elegant way of fixing the underlying cause. I have just bodged in a ‘usStackDepth |= 1;’ at the start of xTaskCreate, but I guess it needs to be used if portSTACK_GROWTH is negative, portBYTE_ALIGNMENT is bigger than sizeof( portSTACK_TYPE ), but I am not aware of all the possible ramifications!

frankandersen wrote on Tuesday, March 31, 2009:

Hi Mike,

Another way to align the stack right for each task is to put this into pxPortInitialiseStack in the top of the function:

        #if (__IAR_SYSTEMS_ICC__ >= 7) /* if EW 5.x or higher */
        if (((portBASE_TYPE)pxTopOfStack) & 0x7)
        {
          pxTopOfStack = (portSTACK_TYPE *)(((portBASE_TYPE)pxTopOfStack) & ~0x7);
        }
        #endif 

I don’t think you need to set the portBYTE_ALIGNMENT to 8, I am using 4, I had the same problem with sprintf, not doing well when converting floats.

Best regards,

Frank Andersen