Skip to main content
Associate III
February 15, 2026
Solved

[STM32H730ZBT] FMC memory management fault

  • February 15, 2026
  • 3 replies
  • 256 views

Hello, 
I'm trying to run SDRAM (AS4C4M16SA-5TCN) with FMC. It looks like all connections are correct. When I try to read/write to memory pointer, I got memory management fault handler.

My FMC configuration:

sebxx4_0-1771156931814.png

Clock connected to FMC is 275MHz (HCLK3). I've tried also to lower it to ~30MHz, but it didn't help.

Under "USER CODE BEGIN 2" I'm executing FMC_Init() function. This is it:

sebxx4_1-1771157270163.png

I tried to write something to memory, but this is the moment when fault handler is activated:

*(__IO uint8_t*) (SDRAM_START_ADDR) = 0x00;
SDRAM_START_ADDR is defined as 0xC0000000.

All FMC's GPIOs are set to Very High speed. What else can I check?
@Tesla DeLorean maybe you could help, please?

 

Best answer by mƎALLEm

Hello,

Do you have the default MPU configuration activated to prevent the CM7 speculative access in your project? like this:

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = 0x00;
 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x87;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

That MPU configuration prevents any access to any external memory. See this thread for the explanation.

You need to add another MPU region to activate the access to you SDRAM memory region.

This is an example of the FMC_SDRAM provided by the H7 CubeHAL. There is a default MPU config and there is a second one to activate the access to the SDRAM:

static void MPU_Config(void)
{
 MPU_Region_InitTypeDef MPU_InitStruct;

 /* Disable the MPU */
 HAL_MPU_Disable();

 /* Configure the MPU as Strongly ordered for not defined regions */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = 0x00;
 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x87;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* Configure the MPU attributes as WB for SDRAM */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = SDRAM_BANK_ADDR;
 MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER1;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x00;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* Enable the MPU */
 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

 Hope that helps.

PS: in next time please use </> to share a code instead of providing a screenshot of it.

3 replies

mƎALLEm
mƎALLEmBest answer
Technical Moderator
February 15, 2026

Hello,

Do you have the default MPU configuration activated to prevent the CM7 speculative access in your project? like this:

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = 0x00;
 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x87;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

That MPU configuration prevents any access to any external memory. See this thread for the explanation.

You need to add another MPU region to activate the access to you SDRAM memory region.

This is an example of the FMC_SDRAM provided by the H7 CubeHAL. There is a default MPU config and there is a second one to activate the access to the SDRAM:

static void MPU_Config(void)
{
 MPU_Region_InitTypeDef MPU_InitStruct;

 /* Disable the MPU */
 HAL_MPU_Disable();

 /* Configure the MPU as Strongly ordered for not defined regions */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = 0x00;
 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x87;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* Configure the MPU attributes as WB for SDRAM */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = SDRAM_BANK_ADDR;
 MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER1;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x00;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* Enable the MPU */
 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

 Hope that helps.

PS: in next time please use </> to share a code instead of providing a screenshot of it.

"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."
sebxx4Author
Associate III
February 15, 2026

Thank you, it seems to be working now. But I noticed, with every code generation, MPU_Config function is overwritten by Cube code. How can I prevent it?

mƎALLEm
Technical Moderator
February 15, 2026

Use the MPU menu in CubeMx to add the new region for SDRAM:

mALLEm_0-1771171109179.png

 

"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."
sebxx4Author
Associate III
February 16, 2026

Thank you, now it works, but I have another problem.
Let's start with array declaration:

uint8_t *externalRAM = (uint8_t*)0xC0000000;
/* USER CODE END PV */

Then I'm trying to write some bytes to this array, ie:

externalRAM[0] = 0xAA;
externalRAM[1] = 0xAA;
externalRAM[2] = 0xAA;
externalRAM[3] = 0xAA;

 And to read it:

uint8_t test[4];
test[0] = externalRAM[0];
test[1] = externalRAM[1];
test[2] = externalRAM[2];
test[3] = externalRAM[3];

And this is the result:

sebxx4_0-1771257761754.png

Sometimes test[1] has 0xAA too, but mostly it's 0. What does this look like?

mƎALLEm
Technical Moderator
February 16, 2026

Hello,

Need to open a new thread for that new question.

Thank you.

"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."