cancel
Showing results for 
Search instead for 
Did you mean: 

can not display sprintf to LCD ?

antonius
Senior
Posted on January 11, 2014 at 22:28

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-code
48 REPLIES 48
troy1818
Senior
Posted on January 11, 2014 at 23:27

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,

/rygelxvi

troy1818
Senior
Posted on January 11, 2014 at 23:27

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,

/rygelxvi

Posted on January 12, 2014 at 01:25

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.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on January 12, 2014 at 02:16

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 ?

antonius
Senior
Posted on January 12, 2014 at 02:20

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=false
Posted on January 12, 2014 at 03:36

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.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on January 12, 2014 at 05:49

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 ??

antonius
Senior
Posted on January 12, 2014 at 11:04

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 ? thanks

troy1818
Senior
Posted on January 12, 2014 at 11:32

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