This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32F0 uint32_t access across boundary

Hi

I am using MDK5.11a on STM32F050. I come across a hard fault, which I eventually find out it is the following construct that causes the problem.

The following is just to demonstrate the fault.

uint8_t array[30] ;
uint32_t *intptr ;
uint8_t i ;
.....
.....
for(i = 0 ; i <= 10 ; i++)
{ intptr = *(uint32_t*)&array[i]) ;

// then access via the integer pointer if(*intptr == 0) {.... }
}

sure, sooner or later, it crashes with hard fault.

My problem in using this approach to access 32 bit is that I received a stream of data from the USART, and put into the array. Depending on the header bytes, somewhere down the stream, the data bytes can either be interpreted as uint16_t or uint32_t, so accessing the 1st byte of the uint32_t by casting its address to uint32_t* and accessing it as 32 bit may bear the problem if the 4 bytes are not aligned correctly, which in my case, is very likely.

The easy way is copy byte by byte (memcpy) into a uint32_t variable and then further processing the variable. But is there any easy way (compiler directives)? As the construct is C compliant, I would have thought that it is the work of the compiler to deal with this automatically without user knowledge about this cross boundary problem?

Rgds

Calvin

Parents
  • "I think the compiler has already implemented this feature for M3/4 but miss out for M0."

    How/why would the compiler do that? If it would be preferred for the compiler to produce code that doesn't care about alignment, then there would be no reason for having any pragma or other way to specify that data is "packed".

    But the problem here is that code written to work with any alignment is larger and slower. So you do not want a compiler that does something as silly as that.

    Some memory controllers can mask alignment issues by adding a second memory access and then merge parts of the first and second memory access before returning a value to the processor core. A memory controller has the ability to do this without adding extra code size and only adding extra performance loss from the extra memory cycles when the data is unaligned. The disadvantage is a memory controller that hides incorrectly aligned data doesn't let the developer know when they have done something really stupid and managed to get lots of their data unaligned - the developer will just have to try to figure out why the program runs slower than expected.

Reply
  • "I think the compiler has already implemented this feature for M3/4 but miss out for M0."

    How/why would the compiler do that? If it would be preferred for the compiler to produce code that doesn't care about alignment, then there would be no reason for having any pragma or other way to specify that data is "packed".

    But the problem here is that code written to work with any alignment is larger and slower. So you do not want a compiler that does something as silly as that.

    Some memory controllers can mask alignment issues by adding a second memory access and then merge parts of the first and second memory access before returning a value to the processor core. A memory controller has the ability to do this without adding extra code size and only adding extra performance loss from the extra memory cycles when the data is unaligned. The disadvantage is a memory controller that hides incorrectly aligned data doesn't let the developer know when they have done something really stupid and managed to get lots of their data unaligned - the developer will just have to try to figure out why the program runs slower than expected.

Children
No data