xSemaphoreGive results i BusFault on STM32F777

I applied some HardFaultHandler that I got from a friend, and here is the result containing fault info. Do you see maybe what could probably be the reason of this fault?

Is there any chance you can display the register contents consistently in hex, not some in hex and some in decimal?

Sorry, had to switch accounts, I didn’t know about daily replies limit for newcomers.

Here it is:

well, one thing that springs to mind here is that the PC is invalid, so apparently, your task stack got overtrampled*. If the stack size is no problem, then you overwrite automatic variables. Comment out the above code and see what happens. I believe Hein is on the spot; make sure that you don’t mix pointers to buffers and buffers.

*there are other possibilities that might make this happen such as corrupted TCBs, but I’d check the contents of the call stack first.

Commenting this line solved the problem with hard fault. So it is something wrong with the pointers indeed. I will figure it out now, thank you very much! I will return to the subject tomorrow and share solution explanation, when I’ll find it.

This frame variable is declared on stack and its data member is never initialized. Then you do a memcpy to frame.data:

Since frame.data is uninitialized, the above call will corrupt memory.

Thanks.

1 Like

Of course, thank you very much. The thing is, I was planning to statically allocate memory for data, and even ALMOST did it…

typedef struct
{
	recorder_frame_header_t header;
	uint8_t data[];
}recorder_frame_t;

just forgot to write size of data in brackets, and then written everything as if I did.

I’m just wondering about one thing. Why hard fault didn’t occurred in the line of memcpy(frame.data, data_ptr, frame.header.data_size);? Why it continued running till xSemaphoreGive? Just out of curiosity and wanting to fully understand what happened

well, the copy was ok as far as the MCU is concerned: Source and target point to valid memory. It’s just that the stack got overwritten, and thus a function return popped a wrong value and tried to jump into nothingness. Note that one the factors that play into the equation is an idiosyncracy of the Cortex architecture and the corresponding compiler which may resolve a tail recursive call to a jump instead of a jump to subroutine; if this had been a “regular” function call sequence, the PC would have been pushed correctly, but then problems would have shown otherwise.

It’s absolutely typical and expected for an RTOS problem to crash (potentially long) after the original logical problem occurred. Again, as long as the memcpy source and target pointers point to physically existing memory, there is no reason to crash because the MCU doesn’t know whether the target pointer’s memory is logically wrong to copy to or not.

Thanks for so wide explanation and for all the help.

I’m just wondering why doesn’t compiler at least warn from memcpy’ing to/from pointer that was uninitialized at the first place? It seems like something that is easy to catch and can be really problematic. Also I don’t see any reason for doing so on purpose, so it just seems like it should generate some information for developer to avoid troubles

there is no way for the compiler to catch that. Imagine you had passed the address of your frame structure to some external opaque function that would have initialized the pointer:

InitFrameStructure(&frame);

In that case, the data member may or may not have been valid. Without knowing what InitFrameStructure exactly does, the compiler would need to employ a lot of heuristic to generate appropriate warnings. Scanning the code for possible side effects and analysing those is something some compilers already do for optimization, yet those issues can become really subtle.

Possibly your compiler already does emit a warning in your case with a fitting warning level, have you checked?

This is C, not Java. On purpose and by design it leaves a lot of room for code design which in return also opens up space for errors that languages with integrated runtime environments would catch. Once you’ve spent enough time coding in C, you’ll develop an inner eye for these kinds of things.

Sure, it’s quite obvious that it can by initialized via pointer to the structure and it doesn’t need to be done explicitly like frame.data = x didn’t think of it asking the question.

Well I have all the answers now, and a lot more knowledge. Thank you guys again for your answers and comments. It seems like the topic can be closed