cpu/esp32: esp_wifi improvements and cleanups#11997
Merged
benpicco merged 7 commits intoRIOT-OS:masterfrom Sep 5, 2019
Merged
Conversation
a9fcab6 to
f39e6d5
Compare
benpicco
reviewed
Sep 5, 2019
Contributor
|
This looks good! With ringbuffers you could even do without locking if you sacrifice one element. I thought tsrb would already provide a convenient implementation for that, but I don't see how it could guarantee integrity for records > 1 bytes. Anyway, this is already a big improvement, we can always optimize it further in another PR if that's necessary. |
Contributor
|
Just squash already |
Events of different type can be pending at the same time. Therefore it is not possible to use ascending identifiers for the presence of a pending event. Rather, each event type has to be represented by one bit. Thes bits ORed identify all types of pending events. In the esp_wifi_isr function all pending events are then handled in one call. Otherwise, some events might be lost.
Receive call back function `_esp_wifi_rx_cb` is called from WiFi hardware driver with a pointer to a frame buffer that is allocated in the WiFi hardware driver. This frame buffer was freed immediately after copying its content to a single local receive buffer of the `esp_wifi` netdev. The local receive buffer remained occupied until the protocol stack had processed it. Further incoming packets were dropped. However, very often a number of subsequent WiFi frames are received at the same time before the first one is processed completely. Having the single local receive buffer to hold only one received frame, led to a number of lost packets, even at low network load. Therefore, a ringbuffer of rx_buf elements was introduced which doesn't store the frames directly but only references to the frame buffers allocated in WiFi hardware driver. Since there is enough memory to hold several frames, the frames buffers allocated in WiFi hardware driver aren't freed immediatly any longer but are kept until the frame is processed by the protocol stack. This results in a much less loss rate of packets.
Instead of having a send buffer as member `esp_wifi` netdev, a local variable is used now as send buffer. This avoids the need for a locking mechanism and reduces the risk of deadlocks.
63a8f04 to
6d77529
Compare
benpicco
approved these changes
Sep 5, 2019
Contributor
benpicco
left a comment
There was a problem hiding this comment.
Tested on esp32 with flood pings, dropped packets reduced significantly.
Contributor
Author
|
@benpicco Thanks for reviewing and testing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contribution description
This PR provides several improvements and cleanups that
esp_wifiof ESP8266 for future code deduplicationIn detail the PR provides the following changes:
_esp_wifi_rx_cbis called from WiFi hardware driver with a pointer to a frame buffer that is allocated in the WiFi hardware driver. This frame buffer was freed immediately after copying its content to a single local receive buffer of theesp_wifinetdev. The local receive buffer then remained occupied until the protocol stack had processed it. Further incoming packets were dropped.Very often, however, multiple consecutive WiFi frames are received simultaneously before the first is fully processed. Having the local receive buffer to hold only one received frame, led to a number of lost packets, even at low network load.
Therefore, a ringbuffer of
rx_bufelements was introduced which doesn't store the frames directly but only references to the frame buffers allocated in WiFi hardware driver. Since there is enough memory for a number of such frames, the frames buffers allocated in the WiFi hardware driver are no longer freed immediately, but are kept until the frame has been processed by the protocol stack. This leads to a much lower loss rate of packets.esp_wifinetdev, a local variable is now used as send buffer. This avoids the need for a locking mechanism and reduces the risk of deadlocks.esp_wifi_isrfunction all pending events are then handled in one call. Otherwise, some events might be lost.Testing procedure
Compile and flash
examples/gnrc_networkingto one ESP32 node.Simultaneously ping the ESP32 node from different terminals or machines with very high, but different rates and different payload sizes:
The loss rate should be 0 % for all pings.
Compare with current master, where the loss rates is already 20 % with only one ping.
The reason is the missing ring buffer for simultaneous incoming WiFi frames.
Again, simultaneously ping the ESP32 node from different terminals or machines with high, but different rates and different payload sizes. Additionally, send UDP packets from the ESP32 node:
Once the udp command has been finished, stop
ncwithand check the number of characters received by
nc. It should be 10.000, that is 0 % loss rate. Also the ping commands should still have a loss rate of 0 %.Issues/PRs references
Depends on PR #11947