[U-Boot] [PATCH v2] NS16550: buffer reads

Graeme Russ graeme.russ at gmail.com
Mon Oct 24 22:40:25 CEST 2011


Hi Wolfgang,

On 25/10/11 07:00, Wolfgang Denk wrote:
> Dear Graeme Russ,
> 
> In message <4EA5BBEF.1050706 at gmail.com> you wrote:
>>
>>> Why would any of the transfer commands actually turn off flow control?
>>
>> getc() sends an XOFF
> 
> Oops?  You got something wrong, I think.
> 
> Receiving a '\n' would cause sending XOFF, and getc() would, if state
> is XOFF, send an XON.

Oops, yes you are right

>> consider the follow (admittedly canned) example:
>>
>> loadb ; sleep 20
>>
>> An XOFF will be sent when the user hits 'enter' but loadb will send an XON
>> when it calls getc(). Now after the transfer is complete, there will have
>> been no XOFF before the sleep command is run so if the user enters anything
>> during the sleep command, those characters can be lost
> 
> Agreed.  You can relax situation if functions that use the serial line
> for their own purposes (like running some serial transfer protocol)
> would have some initialization part where they remember the line state
> (and, if it was XOFF, send XON), plus a termination part where they
> restore the old line state (i. e. if it was XOFF initially, send XOFF
> again).

I think it is sufficient to send an XOFF just before starting to process a
command and XON after command processing is complete. I would think it safe
to assume any command that consumes characters either does so fast enough,
or does flow control internally. And while not processing a command, we are
in a busy loop processing terminal input waiting for a command.

> But note that such software flow control is again just a little
> improvement, it is definitely not a guaranteed way to prevent any
> character losses.  Assume the situation where the user copy & pastes

Actually, I think we can guarantee no loss provided both ends of the serial
link are configured correctly.

> some multi-line command sequence. We will receive a character sequence
> like this:
> 
> 	a b c d e '\n' f g h i j k ...
> 
> We will send XOFF after receiving the '\n' - guess when XOFF will be
> loaded into our transmitter? When the last bit and stop bits have been
> sent? When the receiver on the other size will actually read this from
> his FIFO? And How long it then will take until his Tx fifo empties,
> and he stops sending more characters?

Provided the transmitter and receiver code are running in busy loops, at
most a few characters. This is why 16550 et. al. have hardware Rx buffers,
to account for the delay in receiving the XOFF. The hardware Tx should
never be used unless you have hardware flow control which is controlled
directly by the UART (and I think the original implementation of the 16550
only had Rx buffers for this very reason).

> Assume we have a simple device with a small Rx FIFO - say, 8 bytes
> only. Guess what the chances are that we will overrun this FIFO (and
> then lose characters) before the other side stops sending?

Should be zero (if you disable the hardware Tx buffer) unless you have an
incredibly slow Rx routine (in which case, your baud rate is too high). And
even with a Tx buffer in play the solution is fairly simple - After sending
an XOFF, flush the Rx buffer (and remote Tx buffer) into an internal buffer
until tstc() returns false - use this buffer for getc() until it is empty.
Of course, this fails if the remote end does not honour XOFF, but that's
the users own fault for turning software flow control on at one end only
and/or using a broken serial emulator.

Regards,

Graeme


More information about the U-Boot mailing list