2014-01-11 01:28 PM
Guys,
Why suddenly sprintf doesn't work ? It was working yesterday, I shut down the power supply now, it's not giving me a good response code : uint32_t /*Tmp,*/THH,TMM,TSS,WEEKDAY,DATE,MONTH,YEAR; unsigned char date[10],day[10],month[10],year[10],hour[10],min[10],sec[10]; struct tm *utcTimeSnapshot; Tmp = RTC_GetCounter(); TSS = utcTimeSnapshot->tm_sec; sprintf(sec,''%02d'',TSS); lcd_string(sec); If I commented out sprintf, now it's running properly, I can see RTC on USART, but if I use sprintf, it's running 2 seconds and freeze......any ideas ? Thanks #learn-to-code2014-01-11 02:27 PM
Hi h.rick
The variable TSS is not initialized to any value. It means that it will get any value represented on the stack. This can be whatever value, but lets say the value will take up 10 chars in decimal representation, same amount that sec[] can store. However, the sprintf is also adding a null character if I remember correctly. That will then be 11 characters and you will probably overwrite one byte of data in the following struct ''tm''. Perhaps this can make your system freeze?I don't think that the 02 is working as precision in sprintf, perhaps it should be .2 or something?Regards,/rygelxvi2014-01-11 02:27 PM
Hi h.rick
The variable TSS is not initialized to any value. It means that it will get any value represented on the stack. This can be whatever value, but lets say the value will take up 10 chars in decimal representation, same amount that sec[] can store. However, the sprintf is also adding a null character if I remember correctly. That will then be 11 characters and you will probably overwrite one byte of data in the following struct ''tm''. Perhaps this can make your system freeze?I don't think that the 02 is working as precision in sprintf, perhaps it should be .2 or something?Regards,/rygelxvi2014-01-11 04:25 PM
Rick, can you stop starting threads about materially the same topic.
sprintf() is failing how? It doesn't print what you want? Or malfunctioning? If it prints unexpected values, your problem continues to be a failure to properly initialize structures, suggest you use memset() to zero out variables, that way at least you won't get large random numbers if the time or RTC routines don't fill out things properly. If things crash, or get stuck, stating so is not particularly helpful for debugging. You need to identify WHERE things are stuck or broken, and if things are Hard Faulting identify where and under what conditions that is occurring. If the debugger itself isn't helpful consider outputting check-point strings or characters to you can visualize flow, or identify loops that get stuck. Understand your stack size, and utilization. Both printf(), and scanf() are large stack hogs. Doing a ''%02d'' on a 32-bit integer can exceed 10 characters for large integers + a NUL terminator. I'd allocate at least 16 bytes to such strings, plenty of space, and has good stack alignment. If you overrun local/auto variables all sorts of weird side-effects short of crashing can occur.2014-01-11 05:16 PM
TSS is not initialized to any value,
Do you mean, I do TSS = 0 for the first time or ? Could you please tell me ? Because I take TSS from RTC, it mean TCC must be a global variable then ?2014-01-11 05:20 PM
Sorry about that,
I tried to debug with USART, since my skill for debugging on Keil is not fluent yet, abit confuse how to stop / simulate it.... It stopped when ( blank LCD ) when all the sprintf running, but now it's running, when I commented out weekday and second..... How can I set the stack for sprintf ? unsigned char date[10],day[10],month[10],year[10],hour[10],min[10],sec[10]; is that what you mean ? make it bigger for example unsigned char date[20],day[20],month[20],year[20],hour[20],min[20],sec[20]; ? I commented out , those are not working, //sprintf(day,''%02d'',WEEKDAY); sprintf(date,''%.2d'',DATE); //sprintf(month,''%02d'',MONTH); sprintf(year,''%.2d'',YEAR); sprintf(hour,''%.2d'',THH); //convert integer to string sprintf(min,''%.2d'',TMM); //convert integer to string //sprintf(sec,''%02d'',TSS); //convert integer to string Please have a look on debugging screen, how can I see my error ? if I have put a breakpoint on it ?? I don't understand why ?? it was working yesterday untill I turned it off and back on Thank you ________________ Attachments : debugging_screen.jpg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I1Kn&d=%2Fa%2F0X0000000blR%2F5OTH1j8unXv8cqyWTik0GzaUPfmgs_jr9dlbn8tE4xQ&asPdf=false2014-01-11 06:36 PM
The screen shot show very little useful.
I'll observe that the Keil stacks are usually set up in startup_stm32f1xx.s, and are usually very small. For those I'd probably shoot for 4KB. You however are using an RTOS, and explicitly setting up per task stacks. You could check the size of those from your definitions. You might want to evaluate their utilization, ie fill with some marker, and identify a low water mark for them. Be conscious that auto/local variables that are not initialized will contain random junk left on the stack. char string[10] is insufficient for ''%d'', char string[16] would be more robust, and well aligned. My point with printf/scanf is they also use there own stack allocations, which can often exceed your expectations.2014-01-11 08:49 PM
can you give me example on how to initialized variable ?
I tried with TS[20], still no luck..... strangely it's not working on weekday, month and second, other variables are working, I don't get it why ??2014-01-12 02:04 AM
why can't I get the exact value of the weekday on this variable ?
char *weekday_label[]={''Sun'',''Mon'',''Tue'',''Wed'',''Thr'',''Fri'',''Sat''}; WEEKDAY = utcTimeSnapshot->tm_wday sprintf(day,''%.2d'',WEEKDAY); lcd_string(weekday_label[WEEKDAY]);lcd_string('',''); Any clues ? thanks2014-01-12 02:32 AM
Hi,
Sorry I actually missed one row! TSS is actually set to a value before:TSS = utcTimeSnapshot->tm_sec;However, it seems to me that you are using the pointer ''tm'' before really giving it any value.As TSS, since tm i local variable it will get the value from stack. If you are very lucky you might get a pointer to memory which is actually valid and the call:utcTimeSnapshot->tm_sec;will work. But most often I think you will get some crash here.So as clive1 points out. Set the char arrays to contain 16 bytes and please initialize the tm to NULL like so: struct tm *utcTimeSnapshot = NULL;After this you need to point tm to some good memory.Then you can use it as you do in your code.Regards,rygelxvi