nkopp 0 Posted December 26, 2016 Share Posted December 26, 2016 I have a large sketch in Energia for the CC3200 LaunchXL. Sometimes sprintf does weird things. For example,this code... char buffer[500]; sprintf(buffer, "%f, %f, %f, %d", 1.0, 2.0, 3.0, 4); Serial.println(buffer); sometimes produces this result: 0.000000, 0.000000, 0.000000, 536966100 This looks incorrect to me. There seems to be a pretty significant bug in the Energia+CC3200 implementation of sprintf. It seems that the size of global variables or maybe the stack might be an influencing factor, but I really can't figure it out. Any ideas for how to fix this? (Note: cross-posted here: https://e2e.ti.com/support/wireless_connectivity/simplelink_wifi_cc31xx_cc32xx/f/968/t/563841) Quote Link to post Share on other sites
yyrkoon 250 Posted December 26, 2016 Share Posted December 26, 2016 I have a large sketch in Energia for the CC3200 LaunchXL. Sometimes sprintf does weird things. For example,this code... char buffer[500]; sprintf(buffer, "%f, %f, %f, %d", 1.0, 2.0, 3.0, 4); Serial.println(buffer); sometimes produces this result: 0.000000, 0.000000, 0.000000, 536966100 This looks incorrect to me. There seems to be a pretty significant bug in the Energia+CC3200 implementation of sprintf. It seems that the size of global variables or maybe the stack might be an influencing factor, but I really can't figure it out. Any ideas for how to fix this? (Note: cross-posted here: https://e2e.ti.com/support/wireless_connectivity/simplelink_wifi_cc31xx_cc32xx/f/968/t/563841) Hello . . . So first thing off. Your buffer is too large. This isn't Windows, or even Linux. This is an embedded device where memory is at a premium. Now, perhaps 500 chars( or bytes ) may not be too much, but still far from necessary. reduce its size to ~100. Second off, you should zero out your buffer before you use it. Use memset() or at initialization assign the value of {0} like so: char buffer[100] = {0}; Thirdly, don't use sprintf(), use snprintf() if available. It's much safer. However if you're dead set on using sprintf(). Check the return value. You're not checking the return value in your code, so for all intents, and purposes. Your code will fail silently. Lastly, float types can sometimes behave very oddly if you're not careful how they're initialized, or used. Sometimes even just adding an 'f' at the end of a value can help. Post-fixing the type, but that's not strictly speaking, necessary. energia 1 Quote Link to post Share on other sites
yyrkoon 250 Posted December 27, 2016 Share Posted December 27, 2016 Ok, sorry, was a bit busy( multitasking ) so left out some information. So, what I mentioned above may, or may not solve your problem. But it would help mitigate problems. It may very well be that sprintf() is not implemented correctly in Energia. With that in mind, do realize that Energia is based on Arduino's wiring, which also makes heavy use of C++. So it may be prudent that "we" use C++ strings, which can be much safer when used. EDIT: Additionally to what I mentioned above. It may be a good thing if you posted all your code so we can see exactly what you're doing. Quote Link to post Share on other sites
nkopp 0 Posted December 27, 2016 Author Share Posted December 27, 2016 Thanks for the reply. I have tried all of the following things: Use smaller buffer - I've tried various sizes. The original "real" code was using a longer string with more numbers, but even this shorter version showed the problem. Initialize to zeros - I think this shouldn't be necessary for sprintf or snprintf, but it didn't help. Use snprintf - Actually, I was using snprintf originally, but I changed back to sprintf to simplify the description of the problem. Using Strings instead of sprintf or snprintf sometimes this produces better results, but sometimes it produces very similar results. Below is an example of the code modified to use Strings. At the moment I can't post all of my code, because it contains proprietary IP and I don't have a version that replicates the results in a clean environment. I'm not sure what causes the problem. I think it might be related to memory (heap or stack space) because I'm using WiFi and SLFS, but I'd expect some sort of error instead of strange results. I guess my next step will be to try optimizing the code to reduce memory usage and see if that helps. Anyway, here's a code snippet that shows what I get if I use String instead of snprintf. Note that this same snippet of code works fine when it is part of a smaller sketch. Code: float a = 1.0f; float b = 2.0f; float c = 3.0f; int d = 4; Serial.println(a); Serial.println(b ); Serial.println(c ); Serial.println(d); String s = String("______________") + String(a) + "______:" + String(b ) + "______" + String(c ) + "______" + String(d) + "______" + String(a) + "______" + String(d) + "______\r\n\r\n"; Serial.println(s); Output: 1.00 2.00 3.00 4 ______________0.00______0.00______0.00______4______0.00______4______ Quote Link to post Share on other sites
nkopp 0 Posted December 27, 2016 Author Share Posted December 27, 2016 I refactored my code to reduce global memory usage significantly, and I'm still getting weird results from snprintf (and sprintf) as well as the String class. Sometimes the numbers it prints are "0" and sometimes they contain garbage values. Even though these code snippets that show the problem exist in the context of other (proprietary) code, I don't see how the other code could cause problems, other then maybe by using too much memory. This system isn't multi-threaded, so I don't think there's any way for other code to modify memory between statements. Quote Link to post Share on other sites
yyrkoon 250 Posted December 28, 2016 Share Posted December 28, 2016 I refactored my code to reduce global memory usage significantly, and I'm still getting weird results from snprintf (and sprintf) as well as the String class. Sometimes the numbers it prints are "0" and sometimes they contain garbage values. Even though these code snippets that show the problem exist in the context of other (proprietary) code, I don't see how the other code could cause problems, other then maybe by using too much memory. This system isn't multi-threaded, so I don't think there's any way for other code to modify memory between statements. Sounds like println() has gone wonky. Can you override the numerical base value ? e.g. Serial.println(value, 10); To make sure it prints the values in base 10 format ? EDIT: Actually, the second parameter for the float / double type override is number of digits it seems. So . . . base type is irrelevant. But anyway, you could try using a double instead of a float, but they both look to use identical functions. Quote Link to post Share on other sites
yyrkoon 250 Posted December 28, 2016 Share Posted December 28, 2016 One thing I found rather interesting is that there is a difference between print.cpp for the MSP430, versus the CC3200 processor cores. print.cpp for the cc3200 is 52 lines longer. I honestly have no idea of the differences between these two processors where the serial interface is concerned but this line count differences bothers me for two reasons. At least off the top of my head. print.cpp in my mind should not contain any hardware specific implementation, That should be done in some sort of hardware abstraction library. It should just be standard number to string manipulation, so why the difference period ? EDIT: https://github.com/energia/Energia/blob/master/hardware/msp430/cores/msp430/Print.cpp versus https://github.com/energia/Energia/blob/master/hardware/cc3200/cores/cc3200/Print.cpp Quote Link to post Share on other sites
yyrkoon 250 Posted December 28, 2016 Share Posted December 28, 2016 Running diff between the two versions of print.cpp outputs a ton of differences. Nearly 500 lines. EDIT: Ah, my text editor messed up on the first pastebin, so the second one is closer to real. I did modify the MSP430 file a little to remove a couple of linefeeds in the beginning of the file. So the comment "header", and includes didn't throw off the whole diff process. http://pastebin.com/Rw1e3yW6 http://pastebin.com/ss8TcHpp Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.