jeelabs / esp-link

esp8266 wifi-serial bridge, outbound TCP, and arduino/AVR/LPC/NXP programmer
Other
2.83k stars 722 forks source link

use interrupt or deferred task on uart TX #283

Open tve opened 7 years ago

tve commented 7 years ago

Interrupt would be cleanest, but deferred task may be simpler to implement: https://github.com/sensepost/esp-vnc/blob/7e770585c405288ff93fd42684a246627b5761e0/vnc/vncbridge.c#L220

RoganDawes @RoganDawes 12:34 I implemented a deferred task for processing data received from the TCP connection in smaller chunks as needed, this could be a good use for it Just define a buffer for the incoming data, suspend TCP receive until the buffer reaches a low-water mark, then re-enable TCP receive, rinse, repeat the buffer apparently needs to be 5 full packets long, though Here is the line in question (vncbridge.c is largely copypasta from serbridge.c): https://github.com/sensepost/esp-vnc/blob/7e770585c405288ff93fd42684a246627b5761e0/vnc/vncbridge.c#L220

RoganDawes commented 7 years ago

I don't think it would be simpler to implement, actually, as you need exactly the same infrastructure for both approaches.

  1. Maintain a 5-packet incoming buffer (or 6, if you want to set a low-water mark of e.g. 1 packet of data) per connection. This will limit the number of simultaneous connections, as the free RAM will not allow 4 concurrent with this much buffer per-connection. So that should probably be dropped, or made configurable (perhaps in the web interface?)
  2. Call espconn_recv_hold(conn->conn); as soon as a packet is received (perhaps only if the packet data crosses the low-water mark?).
  3. Write the packet data into the buffer (ideally a ring buffer, I guess, although I simply memcp'd it to the front of the buffer every time I removed anything), and update the number of available bytes.
  4. Fill the serial FIFO with data from the buffer. (I guess you may have to check how much space is available in the buffer first?)
  5. If there is still data in the buffer, either: a) Schedule a deferred task to refill the FIFO or b) enable the FIFO empty interrupt to call the same task
  6. If the amount of data in the buffer drops below the low water mark, call espconn_recv_unhold(conn->conn);