cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32H730ZBT] FMC memory management fault

sebxx4
Associate III

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?

 

1 ACCEPTED SOLUTION

Accepted Solutions
mƎALLEm
ST Employee

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.

View solution in original post

5 REPLIES 5
mƎALLEm
ST Employee

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.
sebxx4
Associate III

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?

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.
sebxx4
Associate III

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?

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.