2009-12-08 11:23 AM
Intermittent program crash during printf and USART receive
2011-05-17 04:31 AM
I am trying to debug an intermittent program crash in my STM32f103RE board which occurs intermittently during combined use of printf() and USART receive.
The application is general robotics, where the STM32 reads ADC channels, receives serial GPS data on the USART3 port, then outputs status and data on the USART1 port. The code runs through each of the main functions, then comes to a final printf() statement before looping. The printf is simple, consisting mostly of characters and two float conversions, where the float values are taken from indices of a float array. When all the functions are active, the program will run for a few hundred cycles and will crash/freeze/hard fault during the printf statement. The crash always occurs after one of the commas, which separate the message header and the printed float values. If I comment this printf line, the program continues to run fine and can send out occasional printfs elsewhere in the code. I can also get the program to work by disconnecting power to the GPS, whose data is received on USART3 using a simple buffer-stuffing in the interrupt routine. Here are some of the troubleshooting steps I took: - I can send out a printf statement that does not reference the float array without issue - I changed the scope of float array, from a global, extern variable to a function argument Could this be some conflict between USART3 (GPS Rx) and USART1 (Data Tx)? Is it possible that the memory is configured incorrectly? Is this a general problem with using printf in a 50Hz loop? Thanks for any insight...2011-05-17 04:31 AM
Thanks for your reply.
I do not have any printf statements in ISRs, but I did put a few USART1 character transmits in the hard fault ISR and found that the STM32 is definitely entering a hard fault. Unsure about the stack overflowing, how can I check this? thread shows hard fault ISR code that I have not yet tried, but will attempt shortly. My presumption about printf being simple is admittedly elementary, since it seems innocuous from the one-line call, although surely it causes considerable processing strain to deal with. I use it, perhaps ignorantly, out of convenience, since it converts many datatypes into a format that is easily viewed on a terminal. What is an acceptable way to handle data telemetry? Should I convert floats to strings or send them as four bytes, then use an interrupt-fed Tx buffer?2011-05-17 04:31 AM
Quote:
The printf is simple
No, printf is not simple! And neither is floating point! Is your stack overflowing? Especially if you are using printf from any ISRs...2011-05-17 04:31 AM
Dear STM32 contributors,
What is your compiler ? Try to change the optimization level ( try higher ones ) and see if the problem is there.. I have seen a similar case in the past and was due to compiler issue when mixing printf and floating librairies it might come from a division by Zero or a wrong casting ... Cheers, {STOne-32}2011-05-17 04:31 AM
STOne-32,
I'm using Keil Realview and have tried using two different optimization settings (-O0 and -O3). The code size is smaller using the -O3, but the problem unfortunately persists. Should I use the optimize for time setting? Thanks for the continued help... still trying to achieve runtime happiness...2011-05-17 04:31 AM
I ran into this problem using sprintf for floating point numbers while running under an RTOS. It turned out that for floating point the stack must be 8-byte aligned when you enter sprintf. You also need to ensure that the stack is not overflowing, and you must have some space on the heap for sprintf to allocate a large quantity of memory. (Put an error indicator in sbrk.)
I have not validated it yet, but printf may require less stack and system memory if you only print one float per printf call. Someone with more knowledge of the inner working of printf will have to answer that one.2011-05-17 04:31 AM
Brilliant! Thanks for your help, st7, STOne-32, and stephen3.
It turned out to be a stack overflow problem, as suggested. Changing the stack size to 0x400 (from the default value of 0x200) solved the problem. The program now runs continuously with no issue. Thanks again.2011-05-17 04:31 AM
Well done :)
2011-05-17 04:31 AM
Stack Overflow is a very common problem, and its symptoms can be very obscure. Therefore it'd be really useful if ST would provide an App Note and example illustrating techniques to detect it.
The commonest one, I guess, is to pre-fill the stack area with some easily-recognised pattern, and then check how much of that gets overwritten - a kind of ''high-water mark'' test... [ This message was edited by: st7 on 01-12-2009 09:52 ]