HardFault on unaligned access, after enabling MPU
Hi
I want to start using the MPU on STM32F7, however when I enable the MPU then unaligned accesses lead to a HardFault immediately.
Code to reproduce the HardFault:
static unsigned short foo[5] = { 0 };
memcpy(&foo[1], &foo[3], 4);I wrote a minimal HardFault handler to output some exception information, it also points to a alignment-related issue (SCB->HFSR=FORCED, SCB->CFSR=UNALIGNED):
SCR : 0x00000000
CCR : 0x00070200
CFSR : 0x01000000
HFSR : 0x40000000
DFSR : 0x0000000b
MMFAR : 0x00000000
BFAR : 0x00000000
AFSR : 0x00000000The above dump also shows that CCR->UNALIGN_TRP is not set.
I don't get a HardFault and everything runs smoothly if the MPU is not activated.
The program also runs smoothly with MPU activated if no unaligned memory accesses are happening.
I'm kind of puzzled, as I searched all the MPU documentation and found no hints to any side effects regarding unaligned memory accesses. Some sources indicate that unaligned exceptions may be raised if the meory region is marked as device region (bufferable, shareable, not cacheable). However I observe this error with all possible combination of MPU region attributes.
Thanks in advance, Patrick
MPU initialization:
void configureMPU()
{
LL_MPU_Disable();
// start addresses of RAM, FLASH, SRAM1 sections (from linker script)
extern int _sdata, _flash_start, _ssram1;
unsigned int sram = (unsigned int)&_sdata; // 0x20000000
unsigned int sflash = (unsigned int)&_flash_start; // 0x08000000
unsigned int ssram1 = (unsigned int)&_ssram1; // 0x20020000
/* Configure DTCM RAM region */
LL_MPU_ConfigRegion(LL_MPU_REGION_NUMBER0, 0x00, sram, LL_MPU_REGION_SIZE_128KB
| LL_MPU_REGION_FULL_ACCESS
| LL_MPU_ACCESS_BUFFERABLE
| LL_MPU_ACCESS_CACHEABLE
| LL_MPU_ACCESS_NOT_SHAREABLE
| LL_MPU_TEX_LEVEL1
| LL_MPU_INSTRUCTION_ACCESS_DISABLE);
/* Configure FLASH region */
LL_MPU_ConfigRegion(LL_MPU_REGION_NUMBER1, 0x00, sflash, LL_MPU_REGION_SIZE_2MB
| LL_MPU_REGION_FULL_ACCESS
| LL_MPU_ACCESS_NOT_BUFFERABLE
| LL_MPU_ACCESS_CACHEABLE
| LL_MPU_ACCESS_NOT_SHAREABLE
| LL_MPU_TEX_LEVEL0
| LL_MPU_INSTRUCTION_ACCESS_ENABLE);
/* Configure SRAM1 region */
LL_MPU_ConfigRegion(LL_MPU_REGION_NUMBER2, 0x00, ssram1, LL_MPU_REGION_SIZE_256KB
| LL_MPU_REGION_FULL_ACCESS
| LL_MPU_ACCESS_BUFFERABLE
| LL_MPU_ACCESS_NOT_CACHEABLE
| LL_MPU_ACCESS_SHAREABLE
| LL_MPU_TEX_LEVEL0
| LL_MPU_INSTRUCTION_ACCESS_ENABLE);
LL_MPU_Enable(LL_MPU_CTRL_HFNMI_PRIVDEF);
}