In PSoC® Creator™, the string that I am using does not get modified with float values when sprintf is used. What is the cause, and is there a work-around?
In the PSoC Creator 3.0 release, we switched the GNU Arm compiler from CodeSourcery to GNU Arm. The latter includes a choice of libraries: newlib and newlib-nano. Because PSoC is memory-constrained, we made the newlib-nano library the default, thereby saving flash and RAM in almost every PSoC 4 and PSoC 5LP design. However, the newlib-nano library requires that floatingpoint handling be enabled to support floating-point string formatting.
Issue: Consider the following code fragment.
char My_String ;
double My_Float = 3.14159;
sprintf (My_String, “Value of pi is: %.2f to 2dp”, My_Float);
This would return “Value of pi is: to 2dp”
The value 3.14 will not get inserted into My_String.
This is because the newlib-nano library, which is the new default C runtime library for PSoC 4 and PSoC 5LP projects using the GNU Arm compiler tool chain, requires the floating-point number support functions to be linked in order to support floating-point formatting. These functions are not linked by default.
- Enable floating-point formatting support in newlib-nano
Open the Project > Build Settings > Arm GCC 4.7.3 > Linker > Command Line. Add “-u _printf_float” in the Custom Flags field. This change will result in an increase in flash usage on the order of 10 Kbytes to 15 Kbytes and a small increase in RAM usage in your application.
- Change the whole library
The second method is to change the whole library. Open the Project > Build Settings > Arm GCC 4.7.3 > Linker > General and set “Use newlib-nano” to false. This switch in the library to newlib will enable support for all runtime library features but will result in an increase in flash usage on the order of 25 Kbytes to 35 Kbytes and an increase in RAM usage on the order of 2 Kbytes.
Work-around for sscanf: A similar issue is also present in the sscanf function. For example, consider the following code fragment.
char My_String = “Pi is 3.14”;
char My_Str1, My_Str2;
float Pi = 2.0;
sscanf (My_String, “%s %s %f”, My_Str1,My_Str2,&Pi);
This would store “Pi” in My_Str1 and “is” in My_Str2, but 2.0 would remain in Pi instead of the expected 3.14.
We can use the same work-around as described while using sprintf to handle this. However, in the case of Method 1, the additional flag is “-u _scanf_float”. When using both printf and scanf functions with Method 1, both flags must be used.
The settings are slightly different for PSoC Creator 3.1 and higher versions; we have directly provided an option to enable floating-point support with newlib-nano. See the following figure for this configuration.
Note: Make sure that the heap size required to support sprintf and sscanf is set in your project (.cydwr > System > Heap Size). The default value is 0x80, which will not be enough to support these functions. You can change it to a higher value such as 0x1000.