- Silicon Labs Community
- Welcome and Announcements
- Silicon Labs Knowledge Base
- 8-bit MCU
- 32-bit MCU
- Bluetooth / Wi-Fi
- Other Products Category
- Optical/RH/Temp Sensor
- Other Products
- Hardware and Software Tools
- Simplicity Studio and Software
- General Discussions and Suggestions
- Chinese Forum
- Software Libraries
- Development Kits
- Reference Designs
- Third Party Tools
- White Papers
- Official Blog of Silicon Labs
- Chinese Blog
04-19-2017 08:52 AM
Hi, I've tried running a bluetooth sdk example (temperature sensor) on a BGM121 evaluation board. Everything works fine except that temperature values that are shown on the LCD is garbage.
I did some debugging and problem seems to be with the "snprintf" function that is used to format the "float" values into string. Looking at some of the similar postings here, I've tried selecting the newlib C library and enabling the float printf support from the linker options . But none of the options worked.
I've also tried giving some constant float values to the snprintf function. For example when I give it "0.0" it's formatted correctly as "0.0". But no other number is formatted correctly. Small numbers (<10.0 exp.) are formatted as "0.0", bigger numbers (~20.0) produce garbage numbers like "23242985423423". This leads me to believe that it understand the float format specifier. Could this be caused by stack overflow/corruption?
Relevant line from the example project:
/* Temp in C and F should both appear on LCD display */ snprintf(tempString, HTM_TEMP_VALUE_TEXT_SIZE, HTM_TEMP_VALUE_TEXT, tempC, tempC * 1.8 + 32.0);
I'm using GCC ARM compiler.
04-19-2017 02:34 PM
I believe Bluetooth stack code still needs to be compiled with IAR as GCC support is forthcoming later this year.
This being the case, the example probably does not work because there are differences in how stdio functions are compiled/linked between IAR and GCC.
Try building the code with IAR (you may need the eval license if you do not already have an IAR license) and see what happens as that is what we used for development and testing.
You might want to check out our Getting Start Guide for more details.
04-19-2017 02:45 PM
@JohnBThanks for your response. I'm working on linux, unfortunately IAR is not an option for me. Everything else, except this printf, worked fine with GCC. I can connect to bluetooth and see the temperature values via the smartphone app. I hope you can support gcc sooner.
04-19-2017 02:49 PM
Since you've gotten that far, don't let this stop you!
There are command line flags necessary for GCC to support floats in stdio accordingly to one of my co-workers. It would be worth doing some searching on Google to see what they might be and then adding them to the project properties.
Alternatively, consider converting the values to integers (e.g. milli deg C) and trying different variations of printf/sprintf to see what happens.
I suspect everything underlying the example is working and that you are mostly just falling prey to different implementations of stdio functions in IAR vs. GCC.
04-19-2017 03:59 PM
When printing floats with newlib nano which is used with armgcc you can provide the linker option "-u _printf_float"
I found some documentation on this option here:
Do you see a difference in your map file when you add that linker option?
04-19-2017 04:02 PM
04-19-2017 04:11 PM
04-20-2017 01:50 AM
@kjostera I've checked the MAP file and indeed there is some difference. It seem to me that library with float support is correctly linked. I've uploaded the map files here: https://gist.github.com/hyOzd/9b29597b09248c30e070
When float support is disabled nothing is formatted though. Output is simply missing any numbers.
By the way I've also tried integer formatting and it works as expected.
04-20-2017 02:10 AM
I'll try to dig into the newlib code to see what is going on. Do you get the same errors if you use printf with floats as when you do snprintf with floats?
04-20-2017 03:14 AM
If you are using our WSTK or STK's then I find that the easiest way to add stdio output support is to use the Virtual COM port on the kit together with our retargeting drivers. Just add retargetio.c and retargetserial.c to your project and add a the RETARGET_VCOM macro to your project (-DRETARGET_VCOM). Then you can initialize it like this:
After that all the printf output will end up on VCOM. We also have retargeting drivers for SWO and the memory lcd if you want to use that.
04-20-2017 03:38 AM
I can see the printf output in IDE. But "printf" also doesn't work. Here is some example output.
Temperature: -0.0 C / -2681562227551784801548418481788911629429637817095
43191727268382542213877256345948358017621060184794 26810052073085056013214570526728581580914868722291 703808.0 F Temperature: -0.0 C / -2681562227551784801548418481788911629429637817095 43191727268382542213877256345948358017621060184794 26810052073085056013214570526728581580914868722291 703808.0 F Temperature: -0.0 C / 28550748487129169780345858535230986572141749001646 13150605790838303661320840434456495228433091753560 96705818810077151792017724734036361727868300991439 00475404727139765874579467004255439234955097596271 46321823477410305738264234037958725584988972655626 251844462905375940653756189543235584.0 F Temperature: -2.0 C / 0.0 F Temperature: -0.0 C / -2681562227551784801548418481788911629429637817095 43191727268382542213877256345948358017621060184794 26810052073085056013214570526728581580914868722291 703808.0 F Temperature: -2.0 C / 0.0 F Temperature: -2.0 C / -0.0 F Temperature: -2.0 C / -0.0 F
PS: Actually I've sent a reply an hour ago but I don't see it now.
04-20-2017 05:52 PM
Don't bother. Float support of all printf() variants in newlib (C library shipped with GCC) is broken, because it would need a working heap (read: malloc).
You will need to work around that by either printing just integers in a clever way or search for another open source (s)printf() implementation that works with float and double.
04-21-2017 11:13 AM
Huh.. I understand.
But this example project defines a "heap" in the startup file (with below line), if not for "malloc" what is it for? I'm not interested in a formatter that requires dynamic memory allocation, I'm just curious.
static uint8_t heap[__HEAP_SIZE] __attribute__ ((aligned(8), used, section(".heap")));
04-22-2017 05:48 AM
@vanmierloIf I remember correctly it was 0x300 (3072) by default. I've tried increasing it a bit (to 0xD00) but nothing changed.
I've also tried to utilize "malloc" function to see if it works. But code got optimized away without warnings.
04-22-2017 09:21 PM
@ChrisM might be able to comment here about malloc(). It popped up in a conversation at one point, and I'm either thinking he said it was broken (?) or maybe am just conflating his comments with someone else's