cancel
Showing results for 
Search instead for 
Did you mean: 

Debugging of ethernet ping test on NUCLEO-STM32F767ZI

ak52
Associate III

In continuation of debugging the Ethernet ping test (from this thread)  @Andrew Neil @bouazizm 

Main issue:

  • When debugging the project, everything works well and i am able to ping the MCU
  • When flashing the project, the ping test fails

Here are the details of my stm32 cube environment.

Operating system: Ubuntu

STM32cubeIDE version details:

ak52_0-1753763776780.pngak52_1-1753763803385.png

Firmware version : 1.17.3

ak52_2-1753764061389.png

I have attached the project for your reference.

Main configuration changes for the project for a successful ping:

  • In the ethernet module: RX and TX descriptors addresses are 0x2007c000 and 0x2007c0a0 respectively.
  • In LwIP  , Under General Settings, DHCP is disabled and static IP(192.168.1.125) and mask(255.255.255.0) are provided
  • In LwIP , Under Key options, MEM_SIZE is 16000 Bytes and LWIP_RAM_HEAP_POINTER is 0x2007c140
  • In FreeRTOS module, the default task stack size increased to 3000 words.
  • In the linker .ld file add .lwip_sec
  .lwip_sec (NOLOAD) :
  {
  . = ABSOLUTE(0x2007c000);
  *(.RxDecripSection)
  
  . = ABSOLUTE(0x2007c0a0);
  *(.TxDecripSection)
  
  . = ABSOLUTE(0x2007c140);	/* Not used */
  *(.lwIPHeap)
  
  } >RAM

With the above configurations, once the code is generated, go to /LWIP/Target/ethernetif.c:

  • Increase INTERFACE_THREAD_STACK_SIZE to 1024

Rebuild and debug the project. Open a terminal and 'ping 192.168.1.125'

6 REPLIES 6
mbarg.1
Senior III

Version 1.18 of STM32CubeIde is buggy - upgrade asap to 1.19.

What do you mean " when flashing" ?

STM32CubeIde load a copy of code avery time you debug, pushing reset you run the same code.

In my design, I always keep serial port debugging on: this allow to see where the code crash with simple one char messages or more complex messages.

In your case, there is (my best guess) a variable overflowing on code or other variable sensitive, stack is a weak area but semaphores, mutex are also critical - print on serial and reduce area of investigation.


@mbarg.1 wrote:

What do you mean " when flashing" ?


I mean just running the code , not debugging.

ak52_0-1753770277265.png

 

I will try with v1.19 and check

Again: first place to look at, variable overflow, like stack size and buffers.

Andrew Neil
Super User

So did you look at the articles I linked?

Did you try the delay, or looking whatever it is you need to wait for?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

After a little debugging , i think i found the main problem,

Firstly it does not matter if we Debug or Run, the main issue is that if the ethernet cable is connected and then the board powers up, i am able to ping the board successfully.

But if i first power up the board, and then insert the ethernet cable, the ping does not succeed.

 

Yes @Andrew Neil  i did try the delay , it did not help!

I tried to debug the issue further:

In the default task , we call MX_LWIP_Init(); once!

void StartDefaultTask(void *argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN 5 */

  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */
}

Here is the MX_LWIP_Init function:

void MX_LWIP_Init(void)
{
  /* IP addresses initialization */
  IP_ADDRESS[0] = 192;
  IP_ADDRESS[1] = 168;
  IP_ADDRESS[2] = 1;
  IP_ADDRESS[3] = 125;
  NETMASK_ADDRESS[0] = 255;
  NETMASK_ADDRESS[1] = 255;
  NETMASK_ADDRESS[2] = 255;
  NETMASK_ADDRESS[3] = 0;
  GATEWAY_ADDRESS[0] = 0;
  GATEWAY_ADDRESS[1] = 0;
  GATEWAY_ADDRESS[2] = 0;
  GATEWAY_ADDRESS[3] = 0;

/* USER CODE BEGIN IP_ADDRESSES */
/* USER CODE END IP_ADDRESSES */

  /* Initialize the LwIP stack with RTOS */
  tcpip_init( NULL, NULL );

  /* IP addresses initialization without DHCP (IPv4) */
  IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
  IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
  IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);

  /* add the network interface (IPv4/IPv6) with RTOS */
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);

  /* Registers the default network interface */
  netif_set_default(&gnetif);

  /* We must always bring the network interface up connection or not... */
  netif_set_up(&gnetif);

  /* Set the link callback function, this function is called on change of link status*/
  netif_set_link_callback(&gnetif, ethernet_link_status_updated);

  /* Create the Ethernet link handler thread */
/* USER CODE BEGIN H7_OS_THREAD_NEW_CMSIS_RTOS_V2 */
  memset(&attributes, 0x0, sizeof(osThreadAttr_t));
  attributes.name = "EthLink";
  attributes.stack_size = INTERFACE_THREAD_STACK_SIZE;
  attributes.priority = osPriorityAboveNormal;
  osThreadNew(ethernet_link_thread, &gnetif, &attributes);
/* USER CODE END H7_OS_THREAD_NEW_CMSIS_RTOS_V2 */

/* USER CODE BEGIN 3 */

/* USER CODE END 3 */
}

The functions ethernet_link_status_updated and the new thread ethernet_link_thread are never called, ever.

I tried setting a dummy variable inside ethernet_link_thread but it is never set and a breakpoint to the same also does not  halt the program

static void ethernet_link_status_updated(struct netif *netif)
{
  if (netif_is_up(netif))
  {
/* USER CODE BEGIN 5 */
	  HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET); //breakpoint here
/* USER CODE END 5 */
  }
  else /* netif is down */
  {
/* USER CODE BEGIN 6 */
	  HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET); //breakpoint here
/* USER CODE END 6 */
  }
}

void ethernet_link_thread(void* argument)
{
  ++dummy_var;                         //breakpoint here
  ETH_MACConfigTypeDef MACConf = {0};
  int32_t PHYLinkState = 0;
  uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;

  struct netif *netif = (struct netif *) argument;
/* USER CODE BEGIN ETH link init */

/* USER CODE END ETH link init */

  for(;;)
  {
  PHYLinkState = LAN8742_GetLinkState(&LAN8742);

  if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
  {
    HAL_ETH_Stop_IT(&heth);
    netif_set_down(netif);
    netif_set_link_down(netif);
  }
  else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
  {
    switch (PHYLinkState)
    {
    case LAN8742_STATUS_100MBITS_FULLDUPLEX:
      duplex = ETH_FULLDUPLEX_MODE;
      speed = ETH_SPEED_100M;
      linkchanged = 1;
      break;
    case LAN8742_STATUS_100MBITS_HALFDUPLEX:
      duplex = ETH_HALFDUPLEX_MODE;
      speed = ETH_SPEED_100M;
      linkchanged = 1;
      break;
    case LAN8742_STATUS_10MBITS_FULLDUPLEX:
      duplex = ETH_FULLDUPLEX_MODE;
      speed = ETH_SPEED_10M;
      linkchanged = 1;
      break;
    case LAN8742_STATUS_10MBITS_HALFDUPLEX:
      duplex = ETH_HALFDUPLEX_MODE;
      speed = ETH_SPEED_10M;
      linkchanged = 1;
      break;
    default:
      break;
    }

    if(linkchanged)
    {
      /* Get MAC Config MAC */
      HAL_ETH_GetMACConfig(&heth, &MACConf);
      MACConf.DuplexMode = duplex;
      MACConf.Speed = speed;
      HAL_ETH_SetMACConfig(&heth, &MACConf);
      HAL_ETH_Start_IT(&heth);
      netif_set_up(netif);
      netif_set_link_up(netif);
    }
  }

/* USER CODE BEGIN ETH link Thread core code for User BSP */

/* USER CODE END ETH link Thread core code for User BSP */

    osDelay(100);
  }
}

 

Hello @ak52 and welcome to ST Community!

After reviewing your project, it seems you have allocated an excessive stack size for your default thread—512 words should be sufficient instead of 3000. Additionally, you can remove the delay you added. With these adjustments, your application should work even if the Ethernet cable is plugged in after boot. Please let me know if this resolves the issue.

Best regards,

To improve visibility of answered topics, please click 'Accept as Solution' on the reply that resolved your issue or answered your question.