2013-10-08 04:49 AM
Hello,
I work with a STm32F417 FreeRTOS + lwip 1.4.0 + 7.1.1.I get crash HardFault_Handler. Sometimes after a few minutes, sometimes after a few hours.There is a screenshot in attachment.I can see that it comes from memcpy (). If I am correct about assembler it is: load into r4 the value contained at r1+r3: (0x20001FF7C + 0x84).That is to say, in the heap memory if I look into .map? Strange because I do not use traditional malloc ()?My analysis may be wrong?Thank you for your help.Pierre2013-10-08 06:27 AM
More probably the stack, and blowing through the top of RAM.
If you know the specific memcpy(), you could place sanity checks around it to assure you don't exceed the scope of the buffer/whatever that is being used.2013-10-08 07:06 AM
If you are using FreeRTOS then you are using some sort of heap (look at the config file).
(one of the things I dislike about FreeRTOS, some of us cannot use malloc, every object must be compile time allocated)None of the standard library functions (like memcpy, printf, malloc,...) should be considered thread safe.that means, if two threads use stdlib functions and a context switch occurs while one thread is inside one of these functions, and the other thread calls the stdlib, then the results are undetermined. Some stdlib functions are well behaved, some are not.you should update to FreeRTOS v7.5. many fixes improvements from v7.12013-10-09 07:46 AM
oh yea, see if there is an option to use character based printf rather than string based. It is a blocking call, but it is safer for RTOS.
By default
printf()
andputs()
make use ofmalloc()
to provide a temporary buffer onthe heap in order to generate the string to be displayed.
2013-10-10 04:25 PM
I had a related problem which I'll share as you may be experiencing the same.
I use the GCC compiler which I use to compile both C and C++ applications for STM32. When using memcpy() the compiler includes optimisations to use the stmdb and ldmia instruction to copy multiple items at a time. While the normal ldr and str instructions are able to work just fine with non-aligned memory pointers, the ldmia and stmdb instructions resulted in hard faults (although maybe memory faults). If you use Google you can find other references to this issue, and also how to specify the variables to stop this optimisation from happening - or at least only be applied when the memory being copied is correctly aligned. I can't remember the exact details though, as I wrote my own memcpy replacement instead.2013-10-12 06:40 AM
2013-10-14 08:16 AM
Now I'm sure this is not memcpy. It is a stack overflow. In fact I think I had a problem with lwip and one with memcpy but in reality it is the same. The program accesses at 0x20020000 address.
It could be after 5 minutes of after a couple of hours.I upgraded to FRTOS 7.5.2 and in same time improves the interrupt configuration with help of assert.I enabled MEMP_SANITY_CHECK and MEMP_OVERFLOW_CHECK in lwip. I don't get error message on terminal, only the program crashes early in memp_sanity () (before it was in memcpy).It seems GCC creates local variables at the end of the memory.I don't know how to find the leakage of memory? I added a data breakpoint near the end of RAM but not easy to interpret if it is correct access or not. Does atrace-
debugger might help?
2013-10-14 08:43 AM
The local variable are at the top of memory due to the placement of the stack there.
You could move it lower and put a guard zone there, but that wouldn't stop the code reading where it shouldn't be. Not sure making it bigger helps either, but rather that you have an array, buffer, whatever that you are exceeding. Say the buffer has space for 32 bytes, and you're trying to move 160 or something. Your job is to understand what's going on with the data manipulation or buffer management to cause this problem. Would trace help, perhaps, it might tell you how you arrived at a specific point, but at this point you should know which instantiation of memcpy() is failing, and how to catch that condition before it faults the processor. You could just as easily instrument the code to output diagnostic information about how it arrived there too. The goal is to recognize the failure condition, and work backward up the call tree, and passed data structures.2013-10-14 01:20 PM
not working with ST at this time I can only say what I did last with another brand.
find the hard fault handler, insert a while (1); and when the blow occor, set a breakpoint on the while. There is a lot of good info to be had. an even sneakier way is char blah =1; while (blah) return then on the hang break on blah change to 0 and step to where the hard fault happened