cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS + LWIP + MDNS

i2pi
Associate II

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.

 

2 REPLIES 2
i2pi
Associate II

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

i2pi
Associate II

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.