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

face: decoupling forwarder_receive from ISR #38

Open
tianyuan129 opened this issue Jan 26, 2019 · 2 comments
Open

face: decoupling forwarder_receive from ISR #38

tianyuan129 opened this issue Jan 26, 2019 · 2 comments
Labels
enhancement New feature or request

Comments

@tianyuan129
Copy link
Member

Timer discussion #11 got me think of our network face implementation might also be problematic. For example, current 802.15.4 face uses ISR to receive frames from network, and transfers data by directly invoking callback from forwarder, which may further invoke callbacks from direct face (which application code be involved with). Thus, the interrupt probably reaches to application region. Given that we can't expect what application do in direct face's onData()/onInterest(), we better decouple forwarder callback from this ISR.

Wonder if using event queue could solve this. We can do it with timer implementation together. Plus, I suggest to keep interrupts confined in "kernel space" and keep all ISR use cases in NDN-Lite as short and simple as possible to ensure interrupts can return quickly.

@tianyuan129 tianyuan129 added the enhancement New feature or request label Jan 26, 2019
@tianyuan129 tianyuan129 changed the title face: decoupling forwarder callback from 802.15.4 frames reception face: decoupling forwarder_receive from ISR Mar 21, 2019
@tianyuan129
Copy link
Member Author

Current face_receive is still called inside ISR, though only the last segment will trigger it. Our UDP face in POSIX adaptation is a good example, showing how to utilize msg queue to avoid abusing ISR, in order to receive and drive forwarder processing packets. Faces should be refactored with msg queue's help.

@yoursunny
Copy link
Contributor

yoursunny commented Mar 21, 2019

The fundamental difference is pull-style vs push-style API.

POSIX UDP faces are sockets. Kernel buffers incoming frames, waiting for you to pull a frame in a normal thread using recvfrom and pass to forwarder/application.
https://github.com/named-data-iot/ndn-iot-package-over-posix/blob/f6cc43a6b60b12d8c485bf78f1400165931e80a0/adaptation/udp/udp-face.c#L203-L207

nRF52 SDK pushes a frame to you in ISR by calling your nrf_802154_received function. There is no buffering before you.
https://github.com/named-data-iot/ndn-iot-package-over-nordic-sdk-gcc/blob/b65851c385ca39f79986821f23823f26d20cf262/adaptation/802154-adaptation/ndn-nrf-802154-face.c#L229-L241

The classical way to turn a push into a pull is adding a queue. nrf_802154_received pushes the frame into a queue, and a normal thread pulls from the queue.
I had this trouble when developing esp8266ndn's EthernetTransport, and ended up adding a queue.
ESP32 variant uses FreeRTOS Queue API because incoming frames are arriving on another CPU; ESP8266 variant is a simple circular buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants