cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-144 STM32F746, FreeRTOS, LWIP

Isol
Associate II

Hello,

I have a problem with LWIP. LWIP doesn’t property work on Nucleo-144 STM32F746 with default settings. After three ping telegrams  LWIP doesn’t work anymore and  FreeRTOS tasks are blocked.

DHCP is activated and I get IP dynamically from DHCP-Server.

 I use STM32CubeIDE 1.3.0. All configuration I have done with STM32CubeIDE and use a default settings of STM32Cube.

Follow steps I have done:

  1. Create new project with  Nucleo-144 STM32F746 board.
  2.  Activate Ethernet interface. (Pins: Very High, No pull-up and no pull down.)
  3.  Activate FreeRTOS:  
    1. Timebase source: TIM5
    2. Version 10.2.1 API: CMSIS v2
    3. Memory management : heap_4
    4.  Created two tasks: StartDefaultTask and aliveTask (LED togle)
  4. Activate LWIP:
    1. LWIP_DHCP enabled
    2. LWIP_ICMP enabled
    3. LWIP_IGMP disabled
    4. LWIP_UDP enabled
    5. LWIP_TCP enabled

Task definition: 

/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 256 * 4
};
/* Definitions for AliveTask */
osThreadId_t AliveTaskHandle;
const osThreadAttr_t AliveTask_attributes = {
  .name = "AliveTask",
  .priority = (osPriority_t) osPriorityLow,
  .stack_size = 128 * 4
};

Tasks:

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN 5 */
 
  /* Infinite loop */
  for(;;)
  {
	  HAL_GPIO_TogglePin(LD1_Green_GPIO_Port, LD1_Green_Pin);
	  osDelay(1000);
  }
  /* USER CODE END 5 */ 
}
 
/* USER CODE BEGIN Header_aliveTask */
/**
* @brief Function implementing the AliveTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_aliveTask */
void aliveTask(void *argument)
{
  /* USER CODE BEGIN aliveTask */
  /* Infinite loop */
  for(;;)
  {
	  HAL_GPIO_TogglePin(LD2_Blue_GPIO_Port,LD2_Blue_Pin);
	  osDelay(500);
  }
  /* USER CODE END aliveTask */
}

What is wrong in default settings of STM32Cube?

Many thanks in advance.

4 REPLIES 4
Isol
Associate II

I found the workaround. Instead CMSIS_V2, I chose the interface CMSIS_V1 for FreeRTOS. It works.

Can anyone explain the difference between CMSIS_V1 and CMSIS_V2?

Regards.

Piranha
Chief II

> Can anyone explain the difference between CMSIS_V1 and CMSIS_V2?

Apart form some different functionality and naming, which is documented and the official documentation is freely available online, another difference seems to be in the amount of bugs...

Isol
Associate II

>>another difference seems to be in the amount of bugs...

It seems that V2 has more bugs than V1.;)

Hi Piranha,

I have tried to find why this configuration doesn’t work with V2.

It seems to be the old bug that you reported here:

https://community.st.com/s/question/0D50X0000BOtUflSQF/bug-stm32-lwip-ethernet-driver-rx-deadlock

    void ethernetif_input(void const * argument)
    {
      struct pbuf *p;
      struct netif *netif = (struct netif *) argument;
      
      for( ;; )
      {
        if (osSemaphoreWait(s_xSemaphore, TIME_WAITING_FOR_INPUT) == osOK)
        {
          do
          {   
            LOCK_TCPIP_CORE();
            p = low_level_input( netif );
            if   (p != NULL)
            {
              if (netif->input( p, netif) != ERR_OK )
              {
                pbuf_free(p);
              }
            }
            UNLOCK_TCPIP_CORE();
          } while(p!=NULL);
        }
      }

The function low_level_input(...) returns NULL value, because the function HAL_ETH_GetReceivedFrame_IT(...) returns a value HAL_ERROR.

The ETH_DMARXDESC_OWN flag is set in heth->RxDesc->Status in HAL_ETH_GetReceivedFrame_IT(...) and a condition of while loop is false. The while loop isn't executed and the fuction returns HAL_ERROR.

    HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
    {
      uint32_t descriptorscancounter = 0;
      
      /* Process Locked */
      __HAL_LOCK(heth);
      
      /* Set ETH HAL State to BUSY */
      heth->State = HAL_ETH_STATE_BUSY;
      
      /* Scan descriptors owned by CPU */
      while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
      {
    //Skip... 
             
      }
     
      /* Set HAL State to Ready */
      heth->State = HAL_ETH_STATE_READY;
      
      /* Process Unlocked */
      __HAL_UNLOCK(heth);
      
      /* Return function status */
      return HAL_ERROR;
    }

After a call of function osSemaphoreWait(...) the task is waiting for a semaphore and I have a deadlock.

Regards