Open vincemulhollon opened 2 years ago
Hi @stephanosio,
This issue, marked as an Enhancement, was opened a while ago and did not get any traction. Please confirm the issue is correctly assigned and re-assign it otherwise.
Please take a moment to review if the issue is still relevant to the project. If it is, please provide feedback and direction on how to move forward. If it is not, has already been addressed, is a duplicate, or is no longer relevant, please close it with a short comment explaining the reason.
@vincemulhollon you are also encouraged to help moving this issue forward by providing additional information and confirming this request/issue is still relevant to you.
Thanks!
Is your enhancement proposal related to a problem? Please describe.
I somehow ended up with NEWLIB=y and CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=n I wanted the former, and had no idea for a couple hours that the latter existed.
I had problems printing floats in shell commands, doing I2C sensor measurements, etc, so I tried something extremely simple to isolate the problem:
float uptime = k_uptime_get() / 3600000.0; shell_print(shell, "Uptime in Hours:[%0.2f]", uptime);
Yeah I know this is basically "kernel uptime" divided by 3600 or whatever which is why I did it, to isolate if it was a logic/math/I2C problem or an output problem, and this isolated it to being an output problem. So I can't print floats, weird.
I was able to get various permutations of [%f] and so forth to print but it would never substitute/round/print floats.
I tried:
char buffer[40]; sprintf(buffer, "%0.2f", uptime); shell_print(shell, "Uptime in Hours:[%s]", buffer);
and that printed empty space. No errors logged (that I saw), just won't print floats.
This topic is apparently completely undocumented or I can't find anything describing it in two hours of searching.
I did eventually find and enable CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y and now the sprintf solution works. Its an ugly way to print floats using the shell, but its the only way I can get it to work at this time.
I find it interesting that even with float printing support enabled, this still does not work. shell_print(shell, "Uptime in Hours:[%0.2f]", uptime);
Enabling float printing did cost me 7K of firmware size, but I have plenty of space so its all good.
Describe the solution you'd like
The best solution would be if you have CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=n and you stubbornly try to printf (or sprintf, etc) a float, then some sort of error message should be generated. Either at runtime or better at compilation time. Maybe the config system could output, not an error, but a warning, like "You've disabled float printing, you sure about that?" or "You've disabled float printing but a grep -c of your code indicates you're trying to printf / sprintf / shell_print, so be careful"
A secondary solution, probably very simple, would be a stub float printer in newlib that instead of outputing a blank space when float support is disabled, would simply output a constant string for all %f format strings along the lines of "plz compile float support in, thx". Float support overall takes about 8K on a STM32 and this "print a string" would probably only cost 50 bytes or so, depending on verbosity.
A tertiary solution, not as good, would be to document the situation perhaps in the newlib docs or in shell docs where it documents shell_print or similar. I would provide a link to the documentation for Zephyr specific printf format specs but I was unable to find any documentation at all on that topic in two hours of searching, so there's that also. I considered that maybe zephyr only supports use and printing of doubles or maybe doesn't do floats at all, so I guessed that would be documented somewhere.
Describe alternatives you've considered
Well, when I couldn't print floats I tried to sprintf into a string and that didn't work either.
Additional context
None really. Best of luck to you, and I hope this results in either better error reporting or better documentation, or some positive outcome one way or another.
Have a great day!