cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault Unaligned Error on memory region from SDRAM

Zed
Associate III

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.

1 ACCEPTED SOLUTION

Accepted Solutions
mƎALLEm
ST Employee

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

5 REPLIES 5
mƎALLEm
ST Employee

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Zed
Associate III

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! 

Pavel A.
Super User
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.

 

 

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?

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