cancel
Showing results for 
Search instead for 
Did you mean: 

How to Configure LWIP + FreeRTOS in STM32CUBE 6.1 ( STM32H750 + LAN8720 ) ?

Hossein Ghaheri
Associate

Hi,

I tried to run lwip and freertos on stm32h750 with physical ic lan8720.

Unfortunately, the program hangs inside the MX_LWIP_INIT() function and I don't have ping.

Other threads do not work either and all codes inside the main function before the MX_LWIP_INIT() function is not executed.

But if I comment this function, the problem will be solved.

Details:

1) Firmware Package : STM32Cube FW_H7 V1.8.0

STM32CUBEMX Version : 6.1

2) MPU :

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.BaseAddress = 0x30040000;
  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 Cacheable write through 
     for LwIP RAM heap which contains the Tx buffers */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x30044000;
  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_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);
//  /* Enables the MPU */
//  HAL_MPU_Enable(MPU_HFNMI_PRIVDEF_NONE);
 
}

3) in ethernetif.c

Reset lan8720

/* USER CODE BEGIN PHY_PRE_CONFIG */
	HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,0);
	HAL_Delay(50);
  HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,1);
/* USER CODE END PHY_PRE_CONFIG */
  /* Set PHY IO functions */
  LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
 
  /* Initialize the LAN8742 ETH PHY */
  //LAN8742_Init(&LAN8742);
	while(LAN8742_Init(&LAN8742) != LAN8742_STATUS_OK)
        ;

Add "SCB_CleanInvalidateDCache();"

static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
  uint32_t i=0;
  struct pbuf *q;
  err_t errval = ERR_OK;
  ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
 
  memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
 
  for(q = p; q != NULL; q = q->next)
  {
    if(i >= ETH_TX_DESC_CNT)
      return ERR_IF;
 
    Txbuffer[i].buffer = q->payload;
    Txbuffer[i].len = q->len;
 
    if(i>0)
    {
      Txbuffer[i-1].next = &Txbuffer[i];
    }
 
    if(q->next == NULL)
    {
      Txbuffer[i].next = NULL;
    }
 
    i++;
  }
 
  TxConfig.Length =  p->tot_len;
  TxConfig.TxBuffer = Txbuffer;
 
	SCB_CleanInvalidateDCache(); //****************
  HAL_ETH_Transmit(&heth, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
 
  return errval;
}

And

static struct pbuf * low_level_input(struct netif *netif)
{
  struct pbuf *p = NULL;
  ETH_BufferTypeDef RxBuff[ETH_RX_DESC_CNT];
  uint32_t framelength = 0, i = 0;
  struct pbuf_custom* custom_pbuf;
 
  memset(RxBuff, 0 , ETH_RX_DESC_CNT*sizeof(ETH_BufferTypeDef));
 
  for(i = 0; i < ETH_RX_DESC_CNT -1; i++)
  {
    RxBuff[i].next=&RxBuff[i+1];
  }
	SCB_CleanInvalidateDCache(); //******************
  if (HAL_ETH_GetRxDataBuffer(&heth, RxBuff) == HAL_OK)
  {
    HAL_ETH_GetRxDataLength(&heth, &framelength);
 
    /* Build Rx descriptor to be ready for next data reception */
    HAL_ETH_BuildRxDescriptors(&heth);

4) Function __HAL_RCC_D2SRAM3_CLK_ENABLE() is called after function SystemClock_Config()

5) ICache and DCache are Enable

Where do you think the problem comes from?

2 REPLIES 2
Piranha
Chief II

Debug where it hangs! If it hangs waiting for a software reset of MAC, then most likely that is because the external MII/RMII clock is not present. Check the pin configuration and actual clock signal presence.

Usage of SCB_CleanInvalidateDCache() is flawed. Read the discussion there:

https://community.st.com/s/question/0D50X0000AnsIJeSQM/how-to-get-ethernet-working-again-after-upgrading-to-firmware-fwh7v140-

And be warned...

https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet

https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

Hossein Ghaheri
Associate

Thank you very much, I am reviewing what you said.

I came across an interesting point: in debug mode, by running the code step by step (breakpoints), the program will run without any problems and ping is ok!

But in normal status, hangs in : MX_LWIP_INIT() -> tcpip_init() -> lwip_init() -> mem_init() (I realized this by trial and error)