cancel
Showing results for 
Search instead for 
Did you mean: 

FMC SDRAM conflict with LWIP configuration

Tu Nguyen Ngoc
Associate II

Hi everyone,

I have a project using STM32H723ZG interface with SDRAM IS42S16400J (via FMC) and LAN8742. If I enable both FMC and LWIP to run with FreeRTOS, my program ends up jump to hard fault handler. If either FMC or LWIP is enabled with FreeRTOS, my program will be worked fine.

This is my MPU config. I know I have done something wrong, but I don't know what it is. Please give me some advice. Thank you in advance.

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};
 
  /* Disables the MPU */
  HAL_MPU_Disable();
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x30000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x30004000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
  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      = 0x60000000;
  MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
  MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER2;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /** Initializes and configures the Region and the memory to be protected
  */
  /* Configure the MPU attributes of SDRAM as Write back, Read allocate, Write allocate */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0xC0000000;
	MPU_InitStruct.Size             = MPU_REGION_SIZE_32MB;
	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_NUMBER3;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
	HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
}

10 REPLIES 10
Khouloud ZEMMELI
ST Employee

Hello @TNguy.15 Ngoc​ 

Thanks for your post, could you please share what type of conflict are you facing (I think with CubeMX configuration)?

Khouloud

Hi,

Sorry, missed click, I mentioned my situation above, please take a look. Thanks

Hi Piranha,

Thank you for your reply, really appreciate that. I'll check your advice, btw to clarify my situation:

For more details:

Case 1: FreeRTOS + LWIP => work fine

Case 2: FreeRTOS + FMC (sdram) => work fine

Case 3: FreeRTOS + FMC + LWIP => the first task cann't run, the program immediatetly jumped into hardfault handler.

I'll check again the linker and ram section. Anyway, I wonder how to move the user heap into SDRAM, so I can allocate a large dynamic memory?

Thank you.

PPhil
Associate II

@TNguy.15 Ngoc​  Were you able to resolve it? I am facing the same issue

MPU_Region_InitTypeDef MPU_InitStruct;

 /* Disable the MPU */

 HAL_MPU_Disable();

 /* Configure the MPU attributes as Device not cacheable

for ETH DMA descriptors */

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.BaseAddress = 0x30000000;

 MPU_InitStruct.Size = MPU_REGION_SIZE_256B;

 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER0;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

 MPU_InitStruct.SubRegionDisable = 0x00;

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /* Configure the MPU attributes as Normal Non Cacheable

for LwIP RAM heap which contains the Tx buffers */

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.BaseAddress = 0x30004000;

 MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;

 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_SHAREABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER1;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;

 MPU_InitStruct.SubRegionDisable = 0x00;

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

 /** Initializes and configures the Region and the memory to be protected

  */

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;

 MPU_InitStruct.Number = MPU_REGION_NUMBER2;

 MPU_InitStruct.BaseAddress = 0xC0000000;

 MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;

 MPU_InitStruct.SubRegionDisable = 0x0;

 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;

 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

 HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */

 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

my MPU config

Pavel A.
Evangelist III

@TNguy.15 Ngoc​ If you use the SDRAM without LwIP, do you enable MPU too?

If not, it looks like configuration of MPU for LwIP above affects the region of SDRAM.

If yes, then v.v.

Currently, I'm using H743, both SDRAM and LWIP work fine. :D

PPhil
Associate II

@TNguy.15 Ngoc​ Thanks for sharing. I am trying to run the LWIP stack from external SDRAM and I am not able to get ping.

Khouloud ZEMMELI  If I run the LWIP stack from QSPI or internal Flash memory, its working fine. Please advice. I am using H745.