Serial receive buffer overrun - is there a way to stop receiving if buffer is full?

Status
Not open for further replies.

doughboy

Well-known member
I've been debugging my code using Serial for over a week wondering why it was not working.
Only today I found out it is due to default 64 byte receive buffer size.

When teensy is sending a large amount of data, and not reading, and during this time the teensy keeps receiving serial data beyond 64 bytes, it turns out the oldest data is overwritten!!

I got my program to work by increasing the receive buffer size to 1024, but wondering if there is a way to make teensy serial stop receiving data when receive buffer is full.

This is serial communication between teensy and esp8266 wifi. This is while sending 2k of data using buffered write, by the time write is finished, and I do a read, the data I get is 64 bytes and there is a lot of missing data.

Thanks
 
Sounds like a full duplex data flow is occurring - yes? 8266 is receiving 2K of data from Teensy and simultaneously sending data to the Teensy.

So for full duplex, one must post a non-blocking read, then start a write to serial that is interrupt driven and non-blocking.

Ideally, these use DMA if the baud rates are high.

The UART transmit buffer needs to be as large as the largest burst you'll ever send.
The UART receive buffer needs to be as large as the largest burst you'll ever receive.
A second burst on receive might lead to the need for double- or n-buffering on the UART.

This can happen when a serial link at x baud is essentially bridged over to a different medium (like 802.11) that is much higher speed.
Invariably, this becomes a layer 2.5 or layer 3 flow control issue - not layer 2 with CTS.
UDP to serial is really hard as there's no flow control or windowing in UDP as there is in TCP. But an MTU sized IP packet can be, what, 1400 bytes - streaming in on the serial line? Back to back packets in an TCP window are harder yet.
One can turn off windowing in TCP to prevent that.
This is often a classic system engineering problem.

This is a common challenge in Arduino where the serial drivers are not very sophisticated. Teensy has improved but it may still fall short.
 
per p#1 and p#2 - you are blocking on writing without using the time of buffered output to read buffered input before it overwrites.

Looking at http://www.pjrc.com/teensy/td_uart.html I see Serial1.availableForWrite() that would allow you to progress through your data to be written in chunks as space allows without causing the system to block with output too large to buffer - then go do other stuff - like service the incoming data buffers that can fill as fast as the outgoing empties. Then add code using Serial1.available() or 'serialEvent()' to empty in chunks to a local buffer as the writes go out in parallel. The hardware will deal with buffers for one as you tend to the other.

Managing the in and out buffers for large exchanges is local to your sketch - and jumping between the two while doing whatever you need to.
 
Suggestion: could the ISR code for the reading and writing be combined into one piece of code that handles both the reading and writing by checking the control register (which will reflect a specific type of interrupt) from and to the UART so that independent of a burst on in this case the write will automaticly handles reading the incomming data? I think to always both the read and write within a single ISR will make the UART driver a lot more rugged or am I overlooking something? It is I think worth a shot.
 
Status
Not open for further replies.
Back
Top