Teensy 3.2 USB serial lockup

Status
Not open for further replies.

adwuk

Member
I have been using a Teensy 3.2 on Mac OSX El Capitan 10.11.3 and Arduino 1.6.7 with latest Teensyduino add on.

I've run into a bunch of problems with USB serial where I thought that there were serial buffer overruns, but now I am not so sure.

This simple sketch should be able to reproduce the problem:

Code:
void setup() {
  Serial.begin(115200);
  pinMode(13, OUTPUT);
}

void blinkLED() {
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
  delay(400);
}

void loop() {
  static long last = 0;
  int x;
  long now;
  now = millis();
  if (now > last + 5000) {
    x = Serial.available();
    Serial.println(x);
    Serial.send_now();
    last = now;
  }
  blinkLED();
}

If you then open the serial monitor and type a bunch of characters in, you will see the serial buffer fill up. I would expect that this will continue until the input buffer is full, but what happens (at around 200-300 bytes) is that the serial comms locks up. The LED continues to flash.

Any ideas?

edit: It isn't simply a problem with the serial monitor as it can be reproduced using "Serial Tools" and "Serial" applications as well with the Arduino IDE closed. It would appear that in certain conditions the LED stops flashing (when disconnecting the serial connection after lockup), so the Teensy 3.2 is clearly in a loop somewhere.
 
Last edited:
Code:
void setup() {
  Serial.begin(115200);
  pinMode(13, OUTPUT);
}

void blinkLED() {
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
}

void loop() {
  static long last = 0;
  int x;
  long now;
  now = millis();
  if (now > last + 1000) {
    x = Serial.available();
    Serial.println(x);
    last = now;
    blinkLED();
  }
}

So it seems pretty repeatable - send a single character using serial monitor and watch the Serial.available() increase each time. On the 10th character sent, the Serial.println() will stop outputting, although the led will continue to blink. Close the serial monitor and the LED stops blinking. Open the serial monitor again, nada. Close it and the Teensy restarts blinking. Open the serial monitor and proof of the restarts as Serial.available() is back at 0.

Anyone?
 
So increasing NUM_USB_BUFFERS in usb_desc.h to 64 seems to make things more reliable, but I guess I am just masking an underlying problem. By putting a usb_flush_serial_input() in after the println() statement then the buffers never become full and the USB Serial interface stays working.

Another issue that I have uncovered is that if you run the sketch above, and simply open and then close the serial monitor, the LED stops flashing. Its takes another open and close of the serial monitor for the Teensy 3.2 to reboot, after which the LED starts to flash.

I am really surprised that no one else has seen these sorts of things so far.
 
I am really surprised that no one else has seen these sorts of things so far.

Seems nobody did such tests!

OK, I can confirm similar behavior running the sketch on a T31.1 with Windows10
Difference:
teensy continues to blick
terminal never prints '10' but locks and cannot be closed (teensyduino terminal)
similar lockup of com port is also when using puttytel: terminal closes but, if restarted, does not print numbers
 
OK, I can confirm similar behavior running the sketch on a T31.1 with Windows10

Phew! I was starting to think it was just me :)

I've found another one. Output data to the transmit buffer with no remote end reading the data. The transmit buffer fills and the Teensy will lock up. I will create a sketch shortly which hopefully will reproduce that fault.

I'm seeing quite a few of these in dmesg:

"AppleUSBACMControl set line coding returned 0xe00002ed"
 
@adwuk
I don't know what you wanted to show.
OK I run your code and it locked up, then I looked into your code and found that you are never reading the character sent by remote computer
with
Code:
    x = Serial.available();
    [COLOR="#FF0000"]if(x)
     Serial.read();[/COLOR]
    Serial.println(x);

you can type a whole line und you see that more than 10 characters are buffered.

Is your point that a program that is not program to function (reading transferred data) has side effects, then yes there may be an issue,
otherwise ....
 
Last edited:
You can type a whole line - in fact you can type 9 whole lines and then on the 10th line the serial will crash. The reason I started looking at this is that I am trying to interface to a program that sends quite a bit of data in one burst (over 500 bytes). I thought at first that the input buffer was overflowing and hence why I was letting the input buffer fill up, but it isn't - something else is going on.

10 lines of 2 characters, 10 lines of 1 character, 10 lines of 20 characters - makes no odds.

The other side of this is that the Teensy is also interfaced to a CAN bus, and transmitting a fair amount of data (which takes some cycles). I need the serial buffer to work properly as I cannot dedicate 100% of the Teensy's time to reading the serial data. Hope that makes sense.
 
Last edited:
Thanks @defragster - I've experimented with SerialEvent already, but will have another go and see if I can clear the buffers fast enough. I still have to find the other issue that is causing the Teensy to reset when the serial connection is closed by the host.
 
I too am seeing problems with USB. For ages I have had a custom MIDI keyboard working fine, then suddenly today it started acting up and resetting.

So I grabbed my brand new Teensy 3.6 and tried this little sketch:

Code:
void setup() {
    Serial.begin(115200);
}

void loop() {
    Serial.println(millis());
    delay(100);
}

As output I get:

Code:
883
983
1083
1183
1283
1383
1483
1583
1683
1783
1883
1983
2083
2283
2383
2483
2583
2683
2783
2883
2983
3083

And that's all. It stops at that point.

I'm on Linux (Ubuntu Zesty 17.04, but I have also had the same results on Xenial 16.04).
 
A bit of digging and it looks to be reception without reading crashes nastilly. Seems ModemManager has been reinstalled on my computer with an update (barstewards!). Removing that "fixes" it, but as soon as I send 10 line feeds it crashes. So there is definitely some kind of buffer overrun / lockup issue there.
 
Do you have the udev rule file installed?

It has a parameter which is supposed to tell the Gnome ModemManager to leave Teensy alone.
 
I'm running the code from msg #11 here on a Teensy 3.6 with Ubuntu 14.04. It's definitely not stopping.

sc.png
 
And are you *sending* data to the teensy? It's the sending without any active reading in the sketch that causes it to crash. Either the Rx buffer is overflowing or its filling up and blocking waiting for the sketch to read from it. If it's blocking then that needs changing. It should be discarding data not blocking. Your choice as to whether it discards the oldest or most recent data to arrive...
 
A bit of digging and it looks to be reception without reading crashes nastilly .... as soon as I send 10 line feeds it crashes. So there is definitely some kind of buffer overrun / lockup issue there.

I'm looking into this problem. First, I should mention this thread has become a confusing mess of other (likely) unrelated reports. Please don't read this as a reply to all these messages. This is only regarding the original test in msg #1.

The problem is ultimately due to all USB endpoints sharing the same pool of packet buffers, without enough safeguarding for one endpoint starving all the others of memory. As packets arrive from the PC, they consume USB buffers in Teensy's memory. The default is only about a dozen buffers. When they're all full, Serial.print() can't get a buffer to send the outgoing text.

This TODO in the code at line 1007 was meant to be a reminder of this potential problem:

Code:
					// TODO: implement a per-endpoint maximum # of allocated
					// packets, so a flood of incoming data on 1 endpoint
					// doesn't starve the others if the user isn't reading
					// it regularly

Looks like I need to actually get this done. But it's not a simple matter....
 
Serial buffer saturation

I'm looking into this problem. First, I should mention this thread has become a confusing mess of other (likely) unrelated reports. Please don't read this as a reply to all these messages. This is only regarding the original test in msg #1.

The problem is ultimately due to all USB endpoints sharing the same pool of packet buffers, without enough safeguarding for one endpoint starving all the others of memory. As packets arrive from the PC, they consume USB buffers in Teensy's memory. The default is only about a dozen buffers. When they're all full, Serial.print() can't get a buffer to send the outgoing text.

This TODO in the code at line 1007 was meant to be a reminder of this potential problem:



Looks like I need to actually get this done. But it's not a simple matter....

I am just replying to this thread to make a note in case someone is having the same problem and looking for a solution. According to the comments, it looks like the buffer still gets saturated. I was using a USB C to HDMI monitor connection, and once I disconnected that, the serial communication seems to work without a hiccup.

PS: Thanks for this comment, found it super useful!
 
Status
Not open for further replies.
Back
Top