I'm trying to use sprintf() to print floating point values to a string on a K64F in KDS 3.1 and the sprintf() call with %3.2f causes a bus error. The project is a Kinetis SDK 1.x project.
I have Float ABI set to Library (soft) and "Use float with nano printf" checked. As soon as the sprintf() executes, it causes a bus error in _dtoa_r, which is called from deep within the sprintf() library function. I traced the code and _dtoa_r calls malloc, which returns a null pointer, which _dtoa_r doesn't bother to check before using it. It's _dtoa_r's use of the null pointer that it gets back from malloc that causes the bus error.
What is the fix for this? I tried increasing the heap and the stack sizes to values that should be sufficient (32K and 16K respectively), but this didn't help.
Numerous examples from Freescale/NXP set up heap incorrectly for newlib.
Examples for FreeRTOS also do not configure FreeRTOS correctly (if you are using anything requiring heap, for example printf using floating point).
Please see the following for detailed explanation, plus code and link file that actually work for FreeRTOS:
How to safely use newlib with FreeRTOS
Hope that helps!
Best Regards, Dave
Hi Jerry,
I think you run into the problem that the standard malloc() tries to check against the stack pointer and the stack memory. So you might either move your stack, or what I did is providing my own _sbrk() routine, see Using Kinetis Design Studio V3.0.0 with the Launchpad 4.9-2015-q2 Release | MCU on Eclipse and FreeRTOS, malloc() and SP check with GNU Tools | MCU on Eclipse .
I hope this helps,
Erich
Hi Erich,
Thanks for the reply. I think our experience with this issue is similar, but not quite the same. In one of the linked articles you said "The interesting part is at line 12 where it checks against the current stack pointer. That check is fine in normal environment, but as our tasks (and stack pointer) is inside the heap, that test most likely will fail". In my case, my tasks and their stack pointer are not inside the heap, but are allocated statically in a completely different section (m_data, not m_data_2 where the heap lives). I'll try your _sbrk change and see if that helps, but in my case the failure is happening in _dtoa_r, not in malloc. I need to do more digging to get to the bottom of this.
I have used floating point in sprintf with other development environments that used newlib-nano (such as Atollic) and didn't have this problem, so what I'll try next is running the same code in Atollic TrueStudio and step through the sprintf call and see what it does differently.
Hi Jerry,
Attached is project created using KDS_3.x+KSDK_1.3 for the frdm-k64. Look in main.c for example code.
I pulled in the platform drivers, hal, other stuff for interrupts and clocking, and also utilities which has if own printf (debug_printf) and associated scanf too.
To enable floating for the debug_printf | scanf the added "PRINTF_FLOAT_ENABLE" and "SCANF_FLOAT_ENABLE" to the Cross ARM C Cpompiler Preprocessor "Defined symbols (-D)". So this is using embedded code for printf/scanf and not gcc library.
Now to get sprintf working which is using the gcc library, I had to check the boxes for the in the Cross ARM C++ Linker0>Miscellaneous setting that are labeled "Use float with nano printf (-u _printf_float)" and "Use float with nano scanf (-u _scanf_float)" to get the sprintf to work with float and also the formatting.
Here is terminal output:
Just a test...here is 314.16
Hello World!
PI = 3.141590
Enter floating point number <followed by Enter> to multiple by PI:
You entered 1.000000............The answer is 3.14
PI = 3.141590
Enter floating point number <followed by Enter> to multiple by PI:
You entered 10.000000............The answer is 31.42
PI = 3.141590
Enter floating point number <followed by Enter> to multiple by PI:
You entered 100.000000............The answer is 314.16
PI = 3.141590
Enter floating point number <followed by Enter> to multiple by PI:
You entered 1000.000000............The answer is 3141.59
Regards,
David