Skip to main content
Visitor II
March 27, 2021
Question

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

  • March 27, 2021
  • 2 replies
  • 1907 views

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?

    This topic has been closed for replies.

    2 replies

    Graduate II
    March 27, 2021

    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

    Visitor II
    March 27, 2021

    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)