Skip to content

Commit 452abcb

Browse files
Use callback from LWIP thread to process Ethernet
Deadlocks/pauses seem to be unavoidable when running Ethernet packet receive outside of the LWIP thread. Add a callback queue message to the LWIP thread to allow for it to run whatever ethernet processing needed. These messages still get stuffed by another simple periodic task.
1 parent ac8c05f commit 452abcb

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

cores/rp2040/freertos/variantHooks.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,15 +578,13 @@ extern "C" bool __isLWIPThread() {
578578
return t.xHandle == __lwipTask;
579579
}
580580

581-
582581
static void lwipThread(void *params) {
583582
(void) params;
584583
LWIPWork w;
585584
assert(__isLWIPThread());
586585

587586
while (true) {
588587
if (xQueueReceive(__lwipQueue, &w, portMAX_DELAY)) {
589-
printf("+LWIPTHREAD %p\n", w.wakeup);
590588
switch (w.op) {
591589
case __lwip_init:
592590
{
@@ -931,6 +929,12 @@ static void lwipThread(void *params) {
931929
*(r->ret) = __real_ethernet_input(r->p, r->netif);
932930
break;
933931
}
932+
case __callback:
933+
{
934+
__callback_req *r = (__callback_req *)w.req;
935+
r->cb();
936+
break;
937+
}
934938
default:
935939
{
936940
// Any new unimplemented calls = ERROR!!!
@@ -939,7 +943,6 @@ static void lwipThread(void *params) {
939943
}
940944
}
941945
// Work done, return value set, just tickle the calling task
942-
printf("-LWIPTHREAD %p\n", w.wakeup);
943946
xTaskNotifyGiveIndexed(w.wakeup, TASK_NOTIFY_LWIP_WAKEUP);
944947
}
945948
}

cores/rp2040/lwip_wrap.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,5 +829,17 @@ extern "C" {
829829
return __real_ethernet_input(p, netif);
830830
}
831831

832+
void lwip_callback(void (*cb)()) {
833+
#ifdef __FREERTOS
834+
if (!__isLWIPThread()) {
835+
__callback_req req = { cb };
836+
__lwip(__callback, &req);
837+
return;
838+
}
839+
#endif
840+
cb();
841+
return;
842+
}
843+
832844

833845
}; // extern "C"

libraries/lwIP_Ethernet/src/LwipEthernet.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,16 @@ static void update_next_timeout(async_context_t *context, async_when_pending_wor
233233
// and polls all Ethernet interfaces
234234
static TaskHandle_t _ethernetTask;;
235235

236+
static void stage2() {
237+
// Scan the installed Ethernet drivers
238+
for (auto handlePacket : _handlePacketList) {
239+
// Note that each NIC needs to use its own mutex to ensure LWIP isn't doing something with it at the time we want to poll
240+
handlePacket.second();
241+
}
242+
// Do LWIP stuff as needed
243+
sys_check_timeouts();
244+
}
245+
extern "C" void lwip_callback(void (*cb)());
236246
static void ethernetTask(void *param) {
237247
(void) param;
238248
while (true) {
@@ -241,13 +251,16 @@ static void ethernetTask(void *param) {
241251
sleep_ms = _pollingPeriod;
242252
}
243253
vTaskDelay(sleep_ms / portTICK_PERIOD_MS);
254+
lwip_callback(stage2);
255+
#if 0
244256
// Scan the installed Ethernet drivers
245257
for (auto handlePacket : _handlePacketList) {
246258
// Note that each NIC needs to use its own mutex to ensure LWIP isn't doing something with it at the time we want to poll
247259
handlePacket.second();
248260
}
249261
// Do LWIP stuff as needed
250262
sys_check_timeouts();
263+
#endif
251264
}
252265
}
253266

libraries/lwIP_Ethernet/src/LwipIntfDev.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,14 +581,13 @@ err_t LwipIntfDev<RawDev>::handlePackets() {
581581
{
582582
return ERR_OK;
583583
}
584-
printf("handlePackets1\n");
584+
585585
xSemaphoreTake(_hwMutex, portMAX_DELAY);
586586
uint16_t tot_len = RawDev::readFrameSize();
587587
if (!tot_len) {
588588
xSemaphoreGive(_hwMutex);
589589
return ERR_OK;
590590
}
591-
printf("handlePackets2\n");
592591

593592
// from doc: use PBUF_RAM for TX, PBUF_POOL from RX
594593
// however:
@@ -599,7 +598,6 @@ printf("handlePackets2\n");
599598
// TODO: tweak the wiznet driver to allow copying partial chunk
600599
// of received data and use PBUF_POOL.
601600
pbuf* pbuf = pbuf_alloc(PBUF_RAW, tot_len, PBUF_RAM);
602-
printf("pballoc ret %p\n", pbuf);
603601
if (!pbuf || pbuf->len < tot_len) {
604602
if (pbuf) {
605603
pbuf_free(pbuf);
@@ -620,9 +618,9 @@ printf("handlePackets2\n");
620618
}
621619

622620
_packetsReceived++;
623-
printf("recv pkt %d: ", tot_len);
624-
for (int i=0; i < tot_len; i++) printf("%02x ", ((uint8_t*)pbuf->payload)[i]);
625-
printf("\n");
621+
//printf("recv pkt %d: ", tot_len);
622+
//for (int i=0; i < tot_len; i++) printf("%02x ", ((uint8_t*)pbuf->payload)[i]);
623+
//printf("\n");
626624
err_t err = _netif.input(pbuf, &_netif);
627625

628626
#if PHY_HAS_CAPTURE

0 commit comments

Comments
 (0)