Teensyduino: Add data_lost = Serial.reset(flags)?

Not open for further replies.

Nominal Animal

Well-known member
Hi @PaulStoffregen, @FrankB, and others working on the nitty-gritty details of USB Serial in the Teensyduino cores,

I'd like to propose a new member function, .reset(), with an optional flag, that resets the USB buffers on the Teensy. (The flag would have two enumerated constants, to indicate whether only read or write or both are to be cleared; the result indicates which types of buffered data had to be discarded to get things reset properly.)

I haven't yet looked at the core code carefully enough to suggest a patch, but there are practical situations where this interface is necessary.

Obviously, this is all about USB buffering in Linux (and possibly other systems; I am currently only using Linux, and don't know the details on others, although I do believe MacOS X has the exact same issues).

When a Teensyduino sketch runs out of receive or transmit USB buffers, both sides get stuck. This is a deadlock (in that both receive and transmit are stuck), and there does not seem to be any sane way to recover from this situation. The .reset() interface would solve this, by dropping all pending data (on the side(s) specified in the flags) on the floor, and rearming any interrupts etc. necessary to get information to flow again.


On Linux, and I do believe on Macs and BSDs, the kernel character device corresponding to the Teensy USB serial device will buffer (some) data when no userspace application has the character device open. This buffer is very limited (I suspect it might be implicit due to the architecture; only one URB), and will halt any further transfers from the Teensy. The Teensyduino USB serial stack does not seem to be able to recover from this. This can occur for example when an userspace application is receiving a lot of data, and suddenly exits, and the Teensyduino sketch does not realize that in time.

Note that this stops Teensy from both receiving and sending data, even though it was just a temporary loss of data consumer on the userspace side.

Related threads:

In the recent Teensy 3.2 Linux Mint USB serial connection issues with fix thread, I "fudged" things a bit, by saying that using .begin() and .end() to maintain the USB serial object state fixes the issue (although I am well aware by looking at the Teensy 3 core code at GitHub) that they are actually NOPs.

Instead, the true "fix" is in my example to not allow the transfer halt to never occur, by always checking the USB serial connection state before attempting output.
I do not see any way (other than poking my dirty little fingers into the Teensyduino internal state) to fix the issue.

The correct fix would be to Serial.reset(RESET_RX | RESET_TX) when the connection is lost to the userspace application (in lieu of Serial.end()).
When a new userspace application connects, a sketch that outputs first would do Serial.reset(RESET_TX | RESET_RX) before outputting the initial message; and a sketch that receives first would do Serial.reset(RESET_TX).


In a perfect world, the function would return 0 if no information was lost, LOST_RX if received data was discarded, LOST_TX if data buffered for sending was discarded, and LOST_RX | LOST_TX if both received data and data queued for sending had to be discarded. If the buffering system does not allow discarding only the data asked, or discarding only the data asked would not necessarily unstick the transfers, then getting the USB serial back in operative state should override the parameter, and the return value reflect that more had to be discarded for a "reset" to be effective.

I know I am asking others to do work that I really should do myself, but I suspect (based on comments and history of the .begin()/.end() methods) that you are already aware of this issues, and this suggestion -- coming from the "user" side, i.e. what practical sketches need, rather than what the hardware allows or supports -- might evoke a practical solution in yall's minds.

If not, then do just tell me to buckle up and find the solution myself, since I seem to have a grip on it already; I do want this fixed, because it affects myself and people I help by creating Linux interfaces to various oddball sensors via Teensies, directly.
Not open for further replies.