Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lwIP_ESPHost - using interrupt #2036

Merged
merged 1 commit into from
Mar 6, 2024

Conversation

JAndrassy
Copy link
Contributor

I attempt to make the ESPHost work with interrupt. There are two problems.

First problem is small. The DATA_READY pin is active HGH with esp_hosted. So we need a way to return from RawDev the state for interrupt.

Second problem is big. The semaphores don't work. It is a problem without the interrupt too, but with the interrupt version handlePackets doesn't run in async_context so there is no locking.
ethernet_arch_lwip_begin/end only guards code executed within async_context so using it elsewhere doesn't stop the code executing. It only blocks handlePackets if executed from the timer worker.

@JAndrassy JAndrassy marked this pull request as draft March 3, 2024 14:12
@earlephilhower
Copy link
Owner

earlephilhower commented Mar 3, 2024

For the 2nd problem, how is this different from the other Ethernet drivers? I'm not sure I understand it. When using IRQs the callback here does the processing which keeps the LWIP locked:

template<class RawDev>
void LwipIntfDev<RawDev>::_irq(void *param) {
LwipIntfDev *d = static_cast<LwipIntfDev*>(param);
ethernet_arch_lwip_begin();
d->handlePackets();
sys_check_timeouts();
ethernet_arch_lwip_end();
}

The only gotcha is the sendFrame call needs to mask off all Ethernet GPIO IRQs during processing, like here, to avoid Ethernet re-entrancy/deadlock:

uint16_t Wiznet5100::sendFrame(const uint8_t* buf, uint16_t len) {
ethernet_arch_lwip_gpio_mask(); // So we don't fire an IRQ and interrupt the send w/a receive!

...all the sendFrame procesing, finishing with...
ethernet_arch_lwip_gpio_unmask();
return len;
}

Also, the LWIP mutex also disables GPIO IRQs while held so you don't end up with a packet coming in while other LWIP stuff is ongoing.

LWIPMutex() {
if (ethernet_arch_lwip_gpio_mask) {
ethernet_arch_lwip_gpio_mask();
}

if (ethernet_arch_lwip_gpio_unmask) {
ethernet_arch_lwip_gpio_unmask();
}

@JAndrassy
Copy link
Contributor Author

JAndrassy commented Mar 4, 2024

sorry, I forgot to check the other lwip_X for recent changes. I will try to use ethernet_arch_lwip_gpio_mask(); to block the IRQ while accessing the library from the main thread. I need to block access to ESPHost library not just from lwip, but from WiFi functions like MACAddress(mac) and RSSI() too.

@JAndrassy
Copy link
Contributor Author

ok. ethernet_arch_lwip_gpio_mask() works. thank you

@JAndrassy
Copy link
Contributor Author

Did you get any idea how much this helps with latency for, say, ping?

I didn't have much time. Today I continue the testing and I want to do a PR for the interrupt change state setting, which would be merged before this one.

@JAndrassy JAndrassy marked this pull request as ready for review March 6, 2024 20:29
Copy link
Owner

@earlephilhower earlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@earlephilhower earlephilhower merged commit 22139df into earlephilhower:master Mar 6, 2024
13 checks passed
@JAndrassy JAndrassy deleted the esphost_irq_way branch March 7, 2024 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants