cancel
Showing results for 
Search instead for 
Did you mean: 

__UNALIGNED_UINT32_READ causes Unaligned Hardfault [solved]

SFahr
Associate III

I have trouble with sporadic Hardfaults and I tracked it down to some unaligned access in the USB routines. Although the code uses the macro __UNALIGNED_UINT32_READ, the STM32 will still causes the Hardfault for unaligned addresses. So I looked at the disassembly and found that __UNALIGNED_UINT32_READ is translated into a simple "ldr.w" which, of course, traps on unaligned addresses.

Looks to me like __UNALIGNED_UINT32_READ does not work. I worked around by disabling the Unaligneded trapping, but any idea why __UNALIGNED_UINT32_READ does not work?

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

In stm32l4xx_ll_usb.c __UNALIGNED_UINT32_READ is used only to access the memory that is supposed to be "normal data". For example a buffer in memory.

CM4 can read and write unaligned 16 or 32 bit values in normal memory natively. GCC knows this and generates plain code without any tricks, even with __attribute__((packed, aligned))

Cortex M0 cannot do unaligned accesses natively so the compiler must generate code to work-around.

On the other hand, if __UNALIGNED_*** macros access device or strongly ordered memory on CM4, the compiler should generate workaround, but there's no way to let the compiler know this (?)

Also IIRC M4 and M7 have a SCB bit that can disable unaligned access so that the CPU behaves as CM0. If this is active, gcc is unaware about it as well.

View solution in original post

7 REPLIES 7

Which STM32?

What code? (I guess Cube, but which portion of it and which version etc.)

> Looks to me like __UNALIGNED_UINT32_READ does not work.

I don't use Cube but it may well be that this macro works only for compilers which support code generation for deliberately unaligned accesses - and AFAIK gcc does not. Also, I was under the impression that the USB code in Cube in case of gcc does not rely on this macro anymore and there is a branch which explicitly splits the accesses. But as I've said, I don't use Cube and don't really care.

HW

SFahr
Associate III

STM32L4R5ZI.

The code in cmsis_gcc.h looks like this:

  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wpacked"
  #pragma GCC diagnostic ignored "-Wattributes"
  __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
  #pragma GCC diagnostic pop
  #define __UNALIGNED_UINT32_READ(addr)          (((const struct T_UINT32_READ *)(const void *)(addr))->v)

SFahr
Associate III

I found only one file that uses those macros, and that's "stm32l4xx_ll_usb.c" (for STM32L4xx).

(It's also in "stm32f4xx_ll_usb.c" for STM32F4xx)

TDK
Guru

FWIW, I can't duplicate this on an F4. __UNALIGNED_UINT32_READ works fine on a STM32F429 with updated gcc.

0693W00000WI80DQAT.png 

0693W00000WI80XQAT.png 

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Evangelist III

In stm32l4xx_ll_usb.c __UNALIGNED_UINT32_READ is used only to access the memory that is supposed to be "normal data". For example a buffer in memory.

CM4 can read and write unaligned 16 or 32 bit values in normal memory natively. GCC knows this and generates plain code without any tricks, even with __attribute__((packed, aligned))

Cortex M0 cannot do unaligned accesses natively so the compiler must generate code to work-around.

On the other hand, if __UNALIGNED_*** macros access device or strongly ordered memory on CM4, the compiler should generate workaround, but there's no way to let the compiler know this (?)

Also IIRC M4 and M7 have a SCB bit that can disable unaligned access so that the CPU behaves as CM0. If this is active, gcc is unaware about it as well.

> __UNALIGNED_UINT32_READ is translated into a simple "ldr.w"

As I've said, it probably doesn't work as expected (i.e. making compiler to split transfers) ​in gcc, only in IAR and Keil.

> which, of course, traps on unaligned addresses.

As Pavel said above, it's not"of course", on CM4 you have to switch off unaligned access support deliberately. So the question really is, why do you do that.

Or, are you sure the problem are unaligned accesses, and not something else.

JW​

SFahr
Associate III

Thanks for your answers.

>So the question really is, why do you do that.

Good question. I used to believe that there must be a good reason why unaligned access can trigger a HardFault (I remember that unaligned access can give undefined behaviour on some architectures)...

Okay, so I just don't enable the unalignment trapping and everything is fine, right?

@TDK:

I take it that you don't have unalignment trapping enabled?