cancel
Showing results for 
Search instead for 
Did you mean: 

Hard fault caused by unaligned access

RBrec.1
Associate III

Hi, 

I have an issue when trying to copy a struct by direct assignment on STM32H743; 

The code: 

 

 

void function(const structName_t *incomingStruct) {

Signal_t sendSignal;

sendSignal.desiredStruct = *incomingStruct;  // <-- Causes unaligned access

..

}

 

 

If desiredStruct consists of only 8 or 16 bits fields, everything works perfectly. If however, one or more of the fields is 32-bits, then the SCB->CFSR->UNALIGNED bit goes high and the programs enters the hard_Fault handler after line 5. I do have a quick fix on this; declaring the desiredStruct as __attribute__((__packed__)). However, as other projects running on STM32F7 use the same library without any issues, I would like to know if anybody has a local solution, or any idea of what's going on. As I understand it, it is the compilers job to add the desired padding to the data to have it aligned, but it doesn't look like it's able to do so? I would assume the compiler ideally don't want any packed attribute, as we remove it's freedom to alter the space between each structure field. I would love to have more input on this specific problem :)

Thanks

 

EDIT: Copying each struct field one by one also works, it is only the operation above that causes trouble. 

23 REPLIES 23

What you quoted is some assembler guide, not architectural documentation. Does that assembler support Cortex-Mx at all?

JW

RBrec.1
Associate III

@waclawek.jan @gbm So quick update after another hour of debugging. Following some questions regarding the casting from the byte buffer, I did look into the messageReceiveFromSocket to see if this was misinterpreted. Turns out that after the initial casting of the data into the desired struct, I am fully able to do the same copying that later in the program fails. So there seems to be a bug on the queue handlers in this case, as I can do the copying prior to sending it on the queue, but not after.

This also explain the fact that this worked on other projects, as we now use Azure and the previous projects use FreeRTOS. So the difference in queue implementations is causing some misaligning in the data somewhere (yet to be found).. 

 

Anyway, thanks a lot for all good suggestions! :flexed_biceps: One step closer I guess

> after the initial casting of the data into the desired struct, I am fully able to do the same copying that later in the program fails

Is this "same copying after initial casting" in a separate source from the "later copying which fails"? Are these two hat sources compiled with different compiler options?

But this may be also that the compiler is too smart to "see" that in the former case the pointer may point to unaligned variable (as it was result of "aligment-suspicious" typecasting), while in the latter case compiler already does not see any reason not to treat the struct as aligned.

JW

Yes they are in separate sources, but still in the same project and compiled with the same options. I have yet to see if there is any difference in the padding between the two cases. Not quite sure how the compiler would work in the different situations, but I would think in theory it should be able to detect bugs causing misalignment?