October 17, 2026

First experiences with STM32 CubeMX -- CubeMX and network/ethernet - packet reception

I have observed both ARP and ICMP packets being received. And responded to -- for a while. The game here is to follow the function calls and explore the code that handles packets as they are received. Hopefully we will discover where both ARP and ICMP packets are handled and figure out logical places to install debug to find out why things stall.

I have installed some debug in LWIP/Target/ethernetif.c and this is where we will start. In the routine "ethernetif_input" we see a call to "low_level_input". This may or may not return anything. When it does, we make a call using a function reference:

netif->input( p, netif)
The function "low_level_init" in this same file has a comment that states that the netif structure will already have been initialized elsewhere. This will get into some study of the LwIP source code.

Take a look at Middlewares/Third_Party/LwIP/src/core/netif.c in the function netif_add() -- this sets the input function pointer. It sets it from a value passed as an argument, so we need to find the call to netif_add() for our case.

This same directory has init.c which contains lwip_init() -- this is called from LWIP/App/lwip.c. And netif_add() is called from LWIP/App/lwip.c also, as follows:

/* add the network interface (IPv4/IPv6) without RTOS */
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
Now we can use ctags, which takes us to: Middlewares/Third_Party/LwIP/src/netif/ethernet.c

This routine contains a big switch/case. One branch handles IP (IPv4 and IPv6 are separate). Another branch handles ARP.
IP is handled by "ip4_input" (see LwIP/src/core/ipv4/ip4.c)
ARP is handled by "etherarp_input" (see LwIP/src/core/ipv4/etharp.c)

Ultimately the reply packet gets handled by ethernet_output() in LwIP/src/netif/ethernet.c which in turn uses netif->linkoutput(netif, p).

Adding some debug in the ARP processing, I see this once things stall:

Rx -  payload at 30003220  tot_len, len = 60 60
tjt = ARP packet
tjt - etharp response being sent
tjt = etharp_raw cannot get pbuf
The code looks like:
 /* allocate a pbuf for the outgoing ARP request packet */
  p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
  if (p == NULL) {
    printf ( "tjt = etharp_raw cannot get pbuf\n\r" );
I should put similar output in the ICMP packet return path and see if it also is unable to get a pbuf. Then take a close look at pbuf_alloc().

Look into ICMP replies

By doing grep on pbuf_alloc in the ipv4 directory we can see various places of interest. The file icmp.c is where we want to focus our attention.

Using this to add some debug

I add printf messages when ARP and ICMP messages are identified. I discover the handy linux utility:
arping
What I observe is that the ST743 is receiving ALL of the arp and icmp packets, and identifying them as such. The ARP packets are 60 bytes in size and the ICMP packets are 98 bytes. Apparently after some time, the ST743 is unable to respond.


Have any comments? Questions? Drop me a line!

Tom's software pages / tom@mmto.org