Skip to main content
Graduate
August 22, 2025
Solved

Hard Fault Unaligned Error on memory region from SDRAM

  • August 22, 2025
  • 3 replies
  • 936 views

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.

    This topic has been closed for replies.
    Best answer by mƎALLEm

    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.

    3 replies

    mƎALLEmAnswer
    Technical Moderator
    August 22, 2025

    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.

    ZedAuthor
    Graduate
    August 22, 2025

    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:

    Screenshot 2025-08-22 165303.png

     And this is a state of the MCU just before Hard Fault:

    Screenshot 2025-08-22 163851.png

    Thank you for your help! 

    Super User
    August 22, 2025
    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.

     

     

    ZedAuthor
    Graduate
    August 25, 2025

    Thank you very much Pavel A. I have set it like this: TEX=0, C=1, B=1 and now Hard Fault comes no more!

    But the main idea was from mƎALLEm, so I don't know which answer should I accept as a Solution.

    Dear Pavel A., do you mind if I accept mƎALLEm's answer as a Solution?

    Super User
    August 25, 2025

    Of course the answer of @mƎALLEm is the best!  thanks.