sprintf does not format a float when called from an interrupt. Result always "0.0"

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
The following sprintf call works correctly when called from main() but the result is always "0.0" when called from an interrupt (in my case a SYSTM001 interrupt)...

sprintf( pStr, "%5.1f,", 69.9 );

The following sprintf with conversion to an integer does work in the interrupt...

sprintf( pStr, "%4i,", (uint16_t)69.9 );

I have read a few posts on this problem on other ARM-GCC forums which suggest problems with stack initialization and stack size.

Any help and advice would be greatly appreciated.

Best regards
Aaron
0 Likes
5 Replies
Not applicable
Another observation.

The compliler / linker do not complain if the sprintf header file is not included in the source file. This is very strange.
0 Likes
Not applicable
Hi Aaron,

I'm interest to know where did you output the data? Is it in console window? How did you make it?

Best regards,
Zain
0 Likes
Not applicable
Hi Zain,

The output goes to a USB port. I have Windows Hyperterminal monitoring the data which was always "0.0".

So I checked the output using the DAVE/Tasking debuger 'Variables' tab which also shows the string buffer to be "0.0".

Best regards
Aaron
0 Likes
Not applicable
My stack size is currently 2048 (listed in project .ld file). Is it possible to increase this ?

Many ARM forums also state the stack must be 8 byte aligned. Is it possible to check / set this ?

Thanks
Aaron
0 Likes
Prakash
Employee
Employee
Hi Aaron.

I suspect while introducing a workaround for a silicon bug, we (Infineon) may have broken the ARM calling convention.

1. Kindly open the assembly startup file of the device (e.g. startup_XMC4500.s) available in the startup folder of your project.
2. Replace the Veneer macro definition with the following snippet .

/* And then define a veneer that will branch to the final excp handler */
.weak \Handler_Func\()_Veneer
.type \Handler_Func\()_Veneer, %function
\Handler_Func\()_Veneer:
LDR R0, =\Handler_Func
PUSH {LR} /* Breaks AAPCS */
SUB SP,#4 /* Restores AAPCS */
BLX R0
ADD SP,#4
POP {PC}
.size \Handler_Func\()_Veneer, . - \Handler_Func\()_Veneer
.endm

The PUSH breaks the 8 Byte boundary while the SUB instruction re-aligns the SP to a 8 byte boundary.

Regards
Prakash Kalanjeri Balasubramanian
0 Likes