Skip to main content
Tu Nguyen Ngoc
Associate III
March 12, 2021
Question

FMC SDRAM conflict with LWIP configuration

  • March 12, 2021
  • 10 replies
  • 3653 views

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);
 
}

This topic has been closed for replies.

10 replies

Khouloud ZEMMELI
ST Employee
March 12, 2021

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

Tu Nguyen Ngoc
Associate III
March 12, 2021

Hi,

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

Piranha
Principal III
March 13, 2021
Tu Nguyen Ngoc
Associate III
March 13, 2021

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
November 26, 2021

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

Tu Nguyen Ngoc
Associate III
November 26, 2021

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.
November 26, 2021

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

Tu Nguyen Ngoc
Associate III
November 27, 2021

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

PPhil
Associate
November 29, 2021

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

Tu Nguyen Ngoc
Associate III
November 30, 2021

What do you mean by "from external SDRAM"? Do you want to allocate lwip stack/pool memory from sdram?