title: Flow Control with UARTs
body: <p>Consider that I want to connect two microcontrollers (one master running Linux, one slave). Consider that the master asks the slave to send some chunk of data. For the sake of argument, this chunk of data is 16 KB large.</p>
  
  <p>To the best of by knowledge, UARTs do not offer flow control in both directions. In my case, the master only has 4 UART pins: TX, RX, RTS, and CTS. As far as I know, RTS/CTS protect the slave's receive buffer from overflowing. However, in the above example, the receive buffer of the master may actually overflow. The reason is that Linux kernel does seem to use a receive buffer of around 4095 bytes. If the userspace application doesn't read the data fast enough, then the buffer simply overflows. The userspace application may be stalling on disk or network I/O for example.</p>
  
  <p>Software flow control using special in-band escape sequences seems to be flawed as well. Basically, the classic XON/XOFF software flow control requires, that the master sends some XOFF control character before its receive buffer overflows. Doing that in the userspace application seems wrong, as the userspace application cannot guarantee to send XOFF in time. So unless it's part of the Linux kernel drivers, it won't work reliably. However, I cannot find any information about whether (and if so when) the kernel driver would send an XOFF control character. Also, the slave will take some time to react the incoming XOFF. How fast must the slave react? If the Linux kernel driver sends the XOFF, what does it assume about the slave?</p>
  
  <p>Right now, I fancy some kind of flow control along the lines of what TCP does: as the master reads data, it sends acknowledgements to the slave. Every N bytes the master has read, it will send an Ack to the slave. That tells the slave, that N more bytes are now available in the receive buffer of the master. If the slave has an estimate of the master's initial receive buffer size, that should work well. That would of course require to ask the Linux kernel for the total size of the receive buffer.</p>
  
  <p>This leads me to the following series of questions:</p>
  
  <ol>
  <li>How do people actually implement flow control in both directions using UARTs?</li>
  <li>How can I get the receive buffer size from the kernel? APIs like pyserial dont seem to offer anything. (The 4095 I gave above is the result of my own experiments and has been confirmed by looking at the kernel source)</li>
  <li>Can the kernel's receive buffer be enlarged by the userspace application? Again, APIs like pyserial don't offer anything and the kernel source didn't look like the size of the buffer was adjustable.</li>
  <li>Besides USB (which has flow control), what do people use as an alternative to UARTs to avoid these issues?</li>
  </ol>
  
  <p><strong>Update</strong>: Many sources still state, that the master sets RTS (=request to send) when it wants to send data to the slave. The slave then acknowledges the request by setting CTS (=clear to send). This allows flow control in one direction only. However, the <a href="https://en.wikipedia.org/wiki/RS-232" rel="nofollow noreferrer">English Wikipedia on RS-232</a> states, that the RTS line was redefined to something more appropriately called RTR (ready to receive) in the 1980s. RTR/CTS allows flow control in both directions.</p>