Skip to main content
Graduate
June 8, 2025
Question

FreeRTOS + LWIP + MDNS

  • June 8, 2025
  • 2 replies
  • 539 views

I have an STM32H735 Discovery Kit and am running the example LWIP code from STM32H7-LwIP-Examples/STM32H735_Disco_ETH. This works great. But, when I add MDNS, I get a very curious crash.

I enabled MDNS in CubeMX, and then created a new thread to wait for an address to be assigned by DHCP before initializing MDNS:

void mdns_thread(void *argument) {
 mdns_resp_init();

 while(!dhcp_supplied_address(&gnetif)) {
 vTaskDelay(1000/ portTICK_PERIOD_MS);
 }
 LOCK_TCPIP_CORE();

 mdns_resp_add_netif(&gnetif, "scion", 60);
 /*
 mdns_resp_add_service(&gnetif, "_scion", "_scion", DNSSD_PROTO_UDP, 9000, 3600, srv_txt, NULL);
 mdns_resp_announce(&gnetif);
 */
 UNLOCK_TCPIP_CORE();

 while (1) {
 vTaskDelay(500/ portTICK_PERIOD_MS);
 }
}

 With the thread created as:

 osThreadAttr_t attributes;
 memset(&attributes, 0x0, sizeof(osThreadAttr_t));
 attributes.name = "MDNS";
 attributes.stack_size = 512;
 attributes.priority = osPriorityNormal;
 osThreadNew(mdns_thread, &gnetif, &attributes);

The issue occurs when I uncomment mdns_resp_add_netif(), as per the code snippet above. 

 

Enabling mdns_resp_add_netif(&gnetif, "scion", 60); causes the program to hang on:
 
 configASSERT( pxQueue->uxItemSize == 0 );
Inside xQueueSemaphoreTake:
Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGINT:Interrupt)
xQueueSemaphoreTake() at queue.c:1,433 0x8005210
osMutexAcquire() at cmsis_os2.c:1,416 0x8004586
sys_mutex_lock() at sys_arch.c:435 0x8011f9e
mem_trim() at mem.c:751 0x80089de
pbuf_realloc() at pbuf.c:444 0x800973e
mdns_send_outpacket() at mdns.c:1,485 0x80078c4
mdns_send_probe() at mdns.c:2,005 0x8007abe
mdns_probe() at mdns.c:2,035 0x800833c
sys_check_timeouts() at timeouts.c:390 0x800e276
tcpip_timeouts_mbox_fetch() at tcpip.c:98 0x8006b02
<...more frames...>
This pxQueue is supposed to be a semaphore, but the data inside it has been corrupt. 
p &pxQueue->uxItemSize
$3 = (UBaseType_t *) 0x24002e90 <ucHeap+3088>
So, let's set a watch on that in GBD and restart:
watch *(uint32_t *)0x24002e90
Hardware watchpoint 6: *(uint32_t *)0x24002e90
It first breaks in prvInitialiseNewQueue, which is totally kosher. Continuing execution and it breaks here:
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08006d06 in mdns_readname_loop (p=p@entry=0x30000470, offset=offset@entry=12, domain=domain@entry=0x24002ec4 <ucHeap+3140>, depth=depth@entry=0)

Thread #1 [main] 1 [core: 0] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)
mdns_readname_loop() at mdns.c:360 0x8006d06
mdns_readname() at mdns.c:424 0x8006e12
mdns_compress_domain() at mdns.c:798 0x8006e12
mdns_compress_domain() at mdns.c:842 0x8006ee4
mdns_write_domain() at mdns.c:849 0x8006ee4
mdns_add_question() at mdns.c:923 0x8006fb4
mdns_add_answer() at mdns.c:1,001 0x8007086
mdns_add_a_answer() at mdns.c:1,176 0x80073fa
mdns_send_outpacket() at mdns.c:1,320 0x80079e8
mdns_send_probe() at mdns.c:2,005 0x8007abe
<...more frames...>
 
 
Look at the psp:
 
info registers
r0 0x30000470 805307504
r1 0xc 12
r2 0x24002ec4 603991748
r3 0x0 0
r4 0x30000470 805307504
r5 0xc 12
r6 0x2400307c 603992188
r7 0xd 13
r8 0x0 0
r9 0x24003204 603992580
r10 0xa5a5a5a5 2779096485
r11 0x2400307c 603992188
r12 0x2e 46
sp 0x24002e90 0x24002e90 <ucHeap+3088>
lr 0x8006e13 134245907
pc 0x8006d06 0x8006d06 <mdns_readname_loop+6>
xpsr 0x81000000 -2130706432
fpscr 0x0 0
msp 0x2404ffe0 0x2404ffe0
psp 0x24002e90 0x24002e90 <ucHeap+3088> <== SHOULD BE &pxQueue->uxItemSize!!!
primask 0x0 0
basepri 0x0 0
faultmask 0x0 0
control 0x2 2
 
So, psp is now pointing to an address inside a mutex. This shouldn't happen :)
 
and for reference we're in the "tcpip_thread", with
 
p pxCurrentTCB->pxTopOfStack
$3 = (volatile StackType_t *) 0x240032bc <ucHeap+4156>
p pxCurrentTCB->pxStack
$4 = (StackType_t *) 0x24002f70 <ucHeap+3312>

 

So psp is below pxStack. I'm at a loss as to what I should be changing in terms of memory settings, linker files, etc., to get this to work. Suggestion would be greatly appreciated!

 

My full source is attached.

 

    This topic has been closed for replies.

    2 replies

    i2piAuthor
    Graduate
    June 8, 2025

    Ok. So increasing TCPIP_THREAD_STACKSIZE from 1024 to 2048 words seems to have fixed it. Now I just need to work out why I can't see the MDNS messages. Looking into wireshark and I don't see any UDP packets being sent.

    Tracing the code, I see that memp_malloc(MEMP_UDP_PCB) (inside mdsn_resp_init(), udp_new()) fails as memp_pools[MEMP_UDP_PCB]->tab = 0x0.

     

    I've enabled semihosting and I see a stream of:

     

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem overflow in pool UDP_PCB" failed at line 109 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem underflow in pool UDP_PCB" failed at line 120 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem underflow in pool UDP_PCB" failed at line 120 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem underflow in pool UDP_PCB" failed at line 120 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem underflow in pool UDP_PCB" failed at line 120 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    Assertion "detected mem underflow in pool UDP_PCB" failed at line 120 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

    i2piAuthor
    Graduate
    June 9, 2025

    The issue was that my mdns_thread was starting before memp_init() ran, so the pools were not set up. It also turns out that CubeMX dropped Driver_PHY, so I set that back to LAN8742, and now the issue I'm seeing is:

     

     
    Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
    Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
    Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
    Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
    Assertion "pc->custom_free_function != NULL" failed at line 767 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c

    Which is happening here:

    Thread #1 (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)	
    	HardFault_Handler() at stm32h7xx_it.c:91 0x800174a	
    	<signal handler called>() at 0xfffffffd	
    	0x0	
    	pbuf_free() at pbuf.c:768 0x8008490	
    	icmp_input() at icmp.c:193 0x800f642	
    	ip4_input() at ip4.c:715 0x800fcce	
    	ethernet_input() at ethernet.c:186 0x801083e	
    	tcpip_thread_handle_msg() at tcpip.c:174 0x8006f70	
    	tcpip_thread() at tcpip.c:148 0x8006fd6	
    	0x8006940	

    I reduced the size of MEMP_NUM_ARP and _DNS, and that kinda fixed it? I'm able to ping it (although i get ~20% packet loss). My wireshark shows MDNS being announced, but its not appearing in mDNS-Explorer and my client application can't find it.