2021-03-27 07:08 AM
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?
2021-03-27 10:36 AM
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:
And be warned...
https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet
2021-03-27 01:22 PM
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)