cancel
Showing results for 
Search instead for 
Did you mean: 

Why this pity code at line 13 couse the Hard Fault?

MPony.1
Associate
#include "stm32f0xx.h"
void SysInit(void);
 
uint8_t array1[260] = {0};
uint8_t array2[260] = {0};
uint16_t test;
int main(void) {
	SysInit();
	for(uint16_t i = 0; i < 260; i++)
		array1[i] = i & 0xFF;
	test = *(uint16_t*)&array1[0xEA];
	test = *(uint16_t*)&array1[0xEC];
	test = *(uint16_t*)&array1[0xEB];
	while(1);
}
void SysInit(void) {
	FLASH->ACR |= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
	RCC->CR2 |= RCC_CR2_HSI48ON;
	while(!(RCC->CR2 & RCC_CR2_HSI48RDY)) {};
	RCC->CFGR &= ~(RCC_CFGR_PPRE | RCC_CFGR_HPRE | RCC_CFGR_SW);
	RCC->CFGR |= RCC_CFGR_PPRE_DIV16 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_HSI48;
	while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI48) {};
	RCC->CFGR &= ~RCC_CFGR_PPRE;
	RCC->CFGR |= RCC_CFGR_PPRE_DIV1;
	SystemCoreClockUpdate();
}

Every other valid reading from the filed array1 works normaly (Except Index 0xEB). I tried almost everthing. (volatile, optimizer, additional variables, memory aglin etc.) This code works propely on other arm devices. I need this code for further purpose (writing to TX-SPI 16bit register).

MCU: STM32F072CBT

IDE: STM32CubeIDE, Keil

8 REPLIES 8
mckenney
Senior

"&array1[0xEB]" (in context) generates an odd address, so a 16-bit access is unaligned.

Per DUI0497A Sec 3.3.4: "There is no support for unaligned accesses on the Cortex-M0 processor. Any attempt to perform an unaligned memory access operation results in a HardFault exception."

I'm not sure there are any ARM devices where unaligned accesses do what you want. (The ARM7/9 were especially weird.)

What do you want to accomplish here?

Uwe Bonnes
Principal II

Isn't M3/4/7 supposed to allow unaligne access?

MPony.1
Associate

I need this code for SPI transfer. The only way how to trasmitt data in 16bit mode is by writing the data directly into SPI->DR as 16 bit word. Writting data as 8bit works propely, but for my application is it too slow. The array must be aligned as 8 bit because data is read from 8 bit SRAM. Is there a way how to align the 8bit array for correct 16bit mode? ((I will try to retype the array1 to 16bit and write data from SRAM as 8bit.))

He's using a CM0(+) device, which doesn't tolerate this.

All CMx devices will fault on misaligned STRD/LDRD

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

Problem is you're reading ODD addresses, doesn't matter how 8-bit array is aligned if you're casting both ODD and EVEN elements to 16-bit

Typically with byte aligned/packed structures (say serial packet data or files) you memcpy() to an auto/local array with known alignment, typically 32/64-bit depending on how tightly it is held to ABI expectations.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

I would use something like this:

typedef union
{
  struct
  {
    uint8_t u8_buf[256];
    uint16_t u16_buf[128];
  } b;                                   /*!< Structure used for bit  access */
} myBuf_t;
 
__ALIGN_BEGIN
myBuf_t myAlignedBuffer;
__ALIGN_END

This is IAR (stable and code unaffected by SW tools "upgrade".

The buffer is memory aligned and can be accessed as 8 bit or 16 bit.

Does it help?

Pavel A.
Evangelist III

Does GCC compiler for ARM have some attribute to extract data via unaligned pointer?

Something like uint16_t v = *(uint16_t * __unaligned p)

Actually you have two separate arrays there. Remove the struct and leave those arrays inside the union.

Anyway the cast to properly aligned addresses technically does the same.