2025-08-21 11:41 PM - last edited on 2025-08-22 2:26 AM by mƎALLEm
Hi everyone!
I have a working project based on STM32F746 with LCD, Ethernet and SDRAM(IS42S16160J-6TL) and now we are moving it to STM32H753II. I set up a FMC controller and tested whole SDRAM region with 8, 16, and 32 bit access. I use GCC.
During this migration I discovered a line of the code that always generate a HardFault error with UNALIGNED flag set. This is this line:
if (strncmp(data + i, boundary_str, 9) == 0)
from:
for (i = 0; i < len; i++)
{
if (strncmp(data + i, boundary_str, 9) == 0)
{
boundaryOffset = i + 9;
break;
}
}
data is placed in SDRAM like this:
char eth_rx_buf[MAX_LENGH] __attribute__((section (".sdram_noncached")));
and boundary_str like this:
static const char boundary_str[10] = "boundary=";
HardFault happens every time when i becomes 10.
MPU settings were copied from STM32F7 project:
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0xC1000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
data and boundary_str reside in 0xC0000000 part.
I have tried almost everything that I could find in Internet.
Please, give me some advice what is the cause of the HardFault. I can change this code to compare these strings one char at a time, but I want to know why it happens at all.
Thanks in advance.
Solved! Go to Solution.
2025-08-22 2:23 AM - edited 2025-08-22 2:26 AM
Hello,
FMC in STM32F7 is an AHB version of the FMC, STM32H7 embeds the AXI version of the FMC.
FMC controller doesn’t support unaligned read access when cache is disabled for H7. According to the information you provided:
@Zed wrote:
data and boundary_str reside in 0xC0000000 part.
From your code:
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
data and boundary_str reside in non cacheable region. Please enable the cache for 0xC0000000.
2025-08-22 2:23 AM - edited 2025-08-22 2:26 AM
Hello,
FMC in STM32F7 is an AHB version of the FMC, STM32H7 embeds the AXI version of the FMC.
FMC controller doesn’t support unaligned read access when cache is disabled for H7. According to the information you provided:
@Zed wrote:
data and boundary_str reside in 0xC0000000 part.
From your code:
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
data and boundary_str reside in non cacheable region. Please enable the cache for 0xC0000000.
2025-08-22 7:55 AM
Thank you for your suggestion. I have moved data to another section with cache enabled:
char eth_rx_buf[MAX_LENGH] __attribute__((section (".sdram_cached")));
this region:
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0xC1000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
And I changed boundary_str to this:
for (i = 0; i < len; i++)
{
if (strncmp (data + i, "boundary=", 9) == 0)
{
boundaryOffset = i + 9;
break;
}
}
but this Hard Fault error continues to happen.
This is the exact place where it happens:
And this is a state of the MCU just before Hard Fault:
Thank you for your help!
2025-08-22 2:09 PM - edited 2025-08-22 2:17 PM
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
From AN4838 "Managing memory protection unit in STM32 MCUs", Table 4: combination of TEX=1, C=1, B=0 is undefined. To get normal cacheable memory, use TEX=0, C=1, B=1 (B=0 not recommended because of the write-thru errata, 2.1.1) or TEX=1 C=1 B=1.
2025-08-25 12:24 AM
2025-08-25 8:24 AM
Of course the answer of @mƎALLEm is the best! thanks.