Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

sprintf and migration to IAR EWARM 5

Posted by Frank Andersen on March 27, 2008
Hi,

I have a problem with using sprintf after the migration from v4 to v5, I think it is something with the new calling convention used by IAR EAWARM v5. When converting float to strings, it just outputs eg. 0.0

I have tried to set the portBYTE_ALIGNMENT to 8, and that did fix the problem for a while, until I discovered that I have forgotten to reserve room for the IRQ stack. I reserved 512 bytes for the IRQ and it is aligned with 8.


I am working on STR710.

From the Migration Guide:
Calling convention
The calling convention used by the compiler has changed. In version 4.x, the stack is by
default aligned to 4, but it is possible to align the stack to 8 according to the Advanced
RISC Machines Ltd Arm/Thumb Procedure Call Standard (ATPCS). In version 5.x, the
compiler instead follows the ARM Architecture Procedure Call Standard (AAPCS).
This means that the stack is now aligned to 8 bytes.

Does anyone has an idea or has the same problem?

Best regards,

Frank Andersen

RE: sprintf and migration to IAR EWARM 5

Posted by Ricky on March 27, 2008
I had the same problem. It's much worse than you've been seeing. The problem occurs when any 8 byte variable gets passed to a function. This includes doubles, long longs, and even floats (which are converted to doubles automatically in printf and sprintf).

It appears to be an alignment problem, not on the stack but in the registers used to pass arguments to functions. The first few arguments are sent in registers and the overflow (if any) is sent on the stack.

Here's an example function:

void TestPrintf (void) {
float FTest;

FTest = 41235.7;
printf ("%f", FTest);
}

When you run the code in the debugger, you will see that the double going into printf is sent in registers R4:R5. But if you debug the printf function, you'll see that it expects the variables in registers R3:R4. You were lucky because you used a value that ended up being 0. If you use 41235.7, the value you get is 26815622342248577624559400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 which crashes the processor miserably because the stack just got blown to the moon!

IAR gives you the ability to align the stack to either 4 or 8 in version 4 but took away that capability in version 5. So the stack is stuck at 8. Rebuilding the C Runtime Library didn't help anything.

I sent a bug report to IAR on the issue but their tech support person sent back a very inane reply: "I am having no problems doing this with EWARM version 5.11A. This is also full printf formatter. Please see my screenshot. Thank you." Included was a 5 MB bitmap showing that it worked on his machine (ever heard of jpeg? Sheesh!). What the heck??? My company is paying good money for tech support and I get a response like that?

After further communications with someone higher up at IAR, I couldn't get a resolution to the problem. So I regressed to version 4. I suggest you do the same and avoid some big headaches.

My specs:

Processor: STR750 w/128K RAM
Current IAR version: 4.42a
Stack alignment: 4 bytes

RE: sprintf and migration to IAR EWARM 5

Posted by Frank Andersen on March 28, 2008
Hi Ricky,

Thx, but I would really like to use the IAR 5.xx as we paid for this.

The thing I do not understand is why, it works when called from one task, but not from another. As I would think that the parameters always would end up in the registers?

Best regards,

Frank Andersen

RE: sprintf and migration to IAR EWARM 5

Posted by Ricky on March 28, 2008
The parameters don't always end up in registers. If you do an sprintf (Buffer, "%d %f", Integer, Float), the buffer, format string, and integer end up in registers but the float gets passed on the stack. The float has to be the first argument after the format string in order for it to be passed in registers. So if your float is far enough down the line, it shouldn't be affected because it isn't in a register pair.

If you get a resolution to this problem, please post it. I'd like to get it resolved too, but I don't have the time to wrangle with a bunch of brainless tech people.

RE: sprintf and migration to IAR EWARM 5

Posted by Enrico Dalla Mariga on July 7, 2008
Hi,
I had same problems with IAR 5.xx and sprintf of float/double. I solved my problem patching "pxPortInitialiseStack" function in my port.c file of FreeRTOS source as follow:

...

portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
#if (__IAR_SYSTEMS_ICC__ >= 6) /* if EW 5.x or higher */
if (((portBASE_TYPE)pxTopOfStack) & 0x7)
{
pxTopOfStack = (portSTACK_TYPE *)(((portBASE_TYPE)pxTopOfStack) & ~0x7);
}
#endif
pxOriginalTOS = pxTopOfStack;

/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */

/* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--;

...
So I'm sure that task's stack will be 8 bytes aligned as required from IAR EW 5.x
I hope this modification will be soon available in some new ports for IAR EW 5.x + ARM

I'm using a NXP LPC2478 with IAR EW 5.11
Bye
Enrico Dalla Mariga

RE: sprintf and migration to IAR EWARM 5

Posted by Dave on July 7, 2008
Would simply setting portBYTE_ALIGNMENT to 8 in portmacro.h fix this?

RE: sprintf and migration to IAR EWARM 5

Posted by Enrico Dalla Mariga on July 8, 2008
No, as portBYTE_ALIGNMENT is not used in IAR-LPC2000 demo sources. In addition, i'm using heap_3.c as dynamic allocation so any changes to portBYTE_ALIGNMENT has no effect for me.
As you can see, with these changes, my sources will be portable for IAR EW < 5.x and I have not to remember to change macro if I use another compiler version...

RE: sprintf and migration to IAR EWARM 5

Posted by zltigo on July 8, 2008

#if (__IAR_SYSTEMS_ICC__ >= 6) /* if EW 5.x or higher */
__________________________^^^ Mistake in IAR C Development Guide :(.

#if (__IAR_SYSTEMS_ICC__ >= 7) /* if EW 5.x or higher */




RE: sprintf and migration to IAR EWARM 5

Posted by Enrico Dalla Mariga on July 9, 2008
That's right, thank you very much!

RE: sprintf and migration to IAR EWARM 5

Posted by Frank Andersen on July 15, 2008
Hi Enrico,

Thank you very much, it seems to have curred by problem also.

Best regards,

Frank Andersen

RE: sprintf and migration to IAR EWARM 5

Posted by Vinay Verma on July 22, 2008
Hi,

This may be resolved by changing the printf formatter option to "full" :

"project options->General Options->Library Options->printf formatter"

regards,
vinay


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS