Skip to content

Commit 0b14547

Browse files
Add IRQ support
IRQs will send a work queue callback instad of actually doing anything. Disable all IRQs when the work noted, and then reset it when done.
1 parent 623c2df commit 0b14547

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

cores/rp2040/freertos/variantHooks.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -556,20 +556,28 @@ void __USBStart() {
556556
}
557557

558558

559-
560-
561-
562-
extern "C" void __lwip(__lwip_op op, void *req) {
559+
extern "C" void __lwip(__lwip_op op, void *req, bool fromISR) {
563560
LWIPWork w;
564-
TaskStatus_t t;
565-
vTaskGetInfo(nullptr, &t, pdFALSE, eInvalid); // TODO - can we speed this up???
566-
w.op = op;
567-
w.req = req;
568-
w.wakeup = t.xHandle;
569-
if (!xQueueSend(__lwipQueue, &w, portMAX_DELAY)) {
570-
panic("LWIP task send failed");
561+
if (fromISR) {
562+
w.op = op;
563+
w.req = req;
564+
w.wakeup = 0; // Don't try and wake up a task when done, we're not in one!
565+
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
566+
if (!xQueueSendFromISR(__lwipQueue, &w, &xHigherPriorityTaskWoken)) {
567+
panic("LWIP task send failed");
568+
}
569+
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
570+
} else {
571+
TaskStatus_t t;
572+
vTaskGetInfo(nullptr, &t, pdFALSE, eInvalid); // TODO - can we speed this up???
573+
w.op = op;
574+
w.req = req;
575+
w.wakeup = t.xHandle;
576+
if (!xQueueSend(__lwipQueue, &w, portMAX_DELAY)) {
577+
panic("LWIP task send failed");
578+
}
579+
ulTaskNotifyTakeIndexed(TASK_NOTIFY_LWIP_WAKEUP, pdTRUE, portMAX_DELAY);
571580
}
572-
ulTaskNotifyTakeIndexed(TASK_NOTIFY_LWIP_WAKEUP, pdTRUE, portMAX_DELAY);
573581
}
574582

575583
extern "C" bool __isLWIPThread() {
@@ -585,7 +593,8 @@ static void lwipThread(void *params) {
585593

586594
while (true) {
587595
if (xQueueReceive(__lwipQueue, &w, portMAX_DELAY)) {
588-
switch (w.op) {
596+
switch (w.op)
597+
{
589598
case __lwip_init:
590599
{
591600
__real_lwip_init();
@@ -943,7 +952,9 @@ static void lwipThread(void *params) {
943952
}
944953
}
945954
// Work done, return value set, just tickle the calling task
946-
xTaskNotifyGiveIndexed(w.wakeup, TASK_NOTIFY_LWIP_WAKEUP);
955+
if (w.wakeup) {
956+
xTaskNotifyGiveIndexed(w.wakeup, TASK_NOTIFY_LWIP_WAKEUP);
957+
}
947958
}
948959
}
949960
}

cores/rp2040/lwip_wrap.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ recursive_mutex_t __lwipMutex;
3737

3838
extern "C" {
3939

40-
extern void __lwip(__lwip_op op, void *req) __attribute((weak));
40+
extern void __lwip(__lwip_op op, void *req, bool fromISR = false);
4141
extern bool __isLWIPThread();
4242

4343
static XoshiroCpp::Xoshiro256PlusPlus *_lwip_rng = nullptr;
@@ -820,7 +820,6 @@ extern "C" {
820820
if (!__isLWIPThread()) {
821821
err_t ret;
822822
__ethernet_input_req req = { p, netif, &ret };
823-
printf("__ethernet_input_req\n");
824823
__lwip(__ethernet_input, &req);
825824
return ret;
826825
}
@@ -829,17 +828,21 @@ extern "C" {
829828
return __real_ethernet_input(p, netif);
830829
}
831830

832-
void lwip_callback(void (*cb)(void *), void *cbData) {
831+
void lwip_callback(void (*cb)(void *), void *cbData, bool fromISR) {
833832
#ifdef __FREERTOS
834-
if (!__isLWIPThread()) {
833+
if (fromISR) {
834+
// In ISR we can't check what the current thread is
835+
__callback_req req = { cb, cbData };
836+
__lwip(__callback, &req, fromISR);
837+
return;
838+
} else if (!__isLWIPThread()) {
835839
__callback_req req = { cb, cbData };
836-
__lwip(__callback, &req);
840+
__lwip(__callback, &req, fromISR);
837841
return;
838842
}
839843
#endif
840844
cb(cbData);
841845
return;
842846
}
843847

844-
845848
}; // extern "C"

libraries/lwIP_Ethernet/src/LwipEthernet.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,13 @@ static void stage2(void *cbData) {
238238
// Scan the installed Ethernet drivers
239239
for (auto handlePacket : _handlePacketList) {
240240
// 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
241-
handlePacket.second();
241+
// handlePacket.second();
242242
}
243243
// Do LWIP stuff as needed
244244
sys_check_timeouts();
245245
}
246246

247-
extern "C" void lwip_callback(void (*cb)(void *), void *cbData);
247+
extern "C" void lwip_callback(void (*cb)(void *), void *cbData, bool fromISR);
248248
static void ethernetTask(void *param) {
249249
(void) param;
250250
while (true) {
@@ -253,7 +253,7 @@ static void ethernetTask(void *param) {
253253
sleep_ms = _pollingPeriod;
254254
}
255255
vTaskDelay(sleep_ms / portTICK_PERIOD_MS);
256-
lwip_callback(stage2, nullptr);
256+
lwip_callback(stage2, nullptr, false);
257257
#if 0
258258
// Scan the installed Ethernet drivers
259259
for (auto handlePacket : _handlePacketList) {

libraries/lwIP_Ethernet/src/LwipIntfDev.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ enum EthernetLinkStatus {
7272
LinkOFF
7373
};
7474

75+
extern "C" void lwip_callback(void (*cb)(void *), void *cbData, bool fromISR);
76+
77+
7578
template<class RawDev>
7679
class LwipIntfDev: public LwipIntf, public RawDev {
7780
public:
@@ -211,6 +214,7 @@ class LwipIntfDev: public LwipIntf, public RawDev {
211214
uint32_t _packetsReceived = 0;
212215
uint32_t _packetsSent = 0;
213216

217+
static void _lwipCallback(void *param);
214218
};
215219

216220

@@ -468,12 +472,23 @@ void LwipIntfDev<RawDev>::end() {
468472
}
469473

470474
template<class RawDev>
471-
void LwipIntfDev<RawDev>::_irq(void *param) {
475+
void LwipIntfDev<RawDev>::_lwipCallback(void *param) {
472476
LwipIntfDev *d = static_cast<LwipIntfDev*>(param);
473-
//ethernet_arch_lwip_begin();
474477
d->handlePackets();
475478
sys_check_timeouts();
479+
ethernet_arch_lwip_gpio_unmask();
480+
}
481+
482+
template<class RawDev>
483+
void LwipIntfDev<RawDev>::_irq(void *param) {
484+
LwipIntfDev *d = static_cast<LwipIntfDev*>(param);
485+
ethernet_arch_lwip_gpio_mask(); // Disable other IRQs until we're done processing this one
486+
lwip_callback(_lwipCallback, param, true);
487+
//ethernet_arch_lwip_begin();
488+
// d->handlePackets();
489+
// sys_check_timeouts();
476490
//ethernet_arch_lwip_end();
491+
477492
}
478493

479494
template<class RawDev>
@@ -489,7 +504,6 @@ EthernetLinkStatus LwipIntfDev<RawDev>::linkStatus() {
489504
template<class RawDev>
490505
err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf) {
491506
LwipIntfDev* lid = (LwipIntfDev*)netif->state;
492-
printf("presend %d\n", pbuf->len);
493507
// ethernet_arch_lwip_begin();
494508
xSemaphoreTake(lid->_hwMutex, portMAX_DELAY);
495509
uint16_t len = lid->sendFrame((const uint8_t*)pbuf->payload, pbuf->len);
@@ -501,7 +515,6 @@ err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf) {
501515
/*success*/ len == pbuf->len);
502516
}
503517
#endif
504-
printf("sent len %d\n", len);
505518
// ethernet_arch_lwip_end();
506519
return len == pbuf->len ? ERR_OK : ERR_MEM;
507520
}

0 commit comments

Comments
 (0)