Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 19 of 19

Thread: Teensy 4.0 USB serial lockup

  1. #1
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175

    Teensy 4.0 USB serial lockup

    I think I'm seeing a bug in usb_serial on Teensy 4.0. When I try sending a block of text larger than 2413 bytes via the serial port, it locks up. Here's the sketch:
    Code:
    #include <Arduino.h>
    
    void setup() {
    
    }
    
    void loop() {
      if (Serial.available()) {
        int x = Serial.read();
        Serial.write(x);
      }
    }
    I put 2414 bytes of text into foo.txt and from the macOS terminal:

    Code:
    cat foo.txt > /dev/cu.usbmodem62442801
    This command get stuck as the teensy is no longer reading bytes. Putting 2413 bytes in the file, it works fine. This and much larger text files work fine on Teensy 3.6.

    Any thoughts?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Paul will be doing a full overhaul of the T_4 USB stack to some degree when the functional first pass is replaced with more efficient methods that may double the speed at least once.

    There is a reported issue already { Teensy-4-0-Serial-available()-stops-incrementing }where the buffered byte count STALLS and those bytes must be read to wake the USB read stack to update the count for additional bytes to be recognized/reported. This may somehow relate to that? Maybe the exact number of bytes flushes through leaving count empty and no way to call again to wake the read stack?

    There was another oddity where reading bytes to a STRING stuck in a similar manner on an exact byte count :: Teensy4-0-does-not-receive-data-longer-than-62-characters. Odd thing was I rewrote that loop to use null terminated C string and it acted properly?

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Don't suppose any of these three changes make any difference?

    Code:
    #include <Arduino.h>
    
    void setup() {
    while ( !Serial );
    }
    
    void loop() {
      while (Serial.available()) {
        char x = Serial.read();
        Serial.write(x);
      }
    }

  4. #4
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Thanks, defragster. I did try your changes to no avail.

    I suspect that the issue outlined at https://forum.pjrc.com/threads/57325...s-incrementing is the same one, I missed that thread while trying to figure out what's going on here.

    Funny thing is that I can write those 2413 bytes over and over no problem. It's a single write of 2314 that stalls it out.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Quote Originally Posted by blackketter View Post
    Thanks, defragster. I did try your changes to no avail.

    I suspect that the issue outlined at https://forum.pjrc.com/threads/57325...s-incrementing is the same one, I missed that thread while trying to figure out what's going on here.

    ...
    I didn't think so - but …

    If that is the case then having the Host send another Byte or so after '2314' will rewake the receive unit?

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,680
    Which version of MacOS are you using?

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Not seeing this repro on Windows - LED comes on then goes off with code below.

    @blackketter - does sending one more byte after wake it up - re-reading first post perhaps not as it notes text larger that 2413 ... so may not be related. What do you see with sketch below WRT LED?


    CMDLINE of file 2410 to 2414 bytes:
    Code:
    echo c:\tmp\test2413.txt > \\.\com30
    or 
    type c:\tmp\test2413.txt > \\.\com30
    Sketch with LED:
    Code:
    #include <Arduino.h>
    // https://forum.pjrc.com/threads/57995-Teensy-4-0-USB-serial-lockup?p=218791&viewfull=1#post218791
    elapsedMillis inw = 0;
    void setup() {
      pinMode( 13, OUTPUT );
      digitalWriteFast( 13, 1 );
      inw = 0;
    }
    
    int ii = 0;
    void loop() {
      if (Serial.available()) {
        int x = Serial.read();
        Serial.write(x);
        digitalWriteFast( 13, 1 );
        ii++;
        inw = 0;
      }
      if (inw > 2000)
        digitalWriteFast( 13, 0 );
    }

  8. #8
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by PaulStoffregen View Post
    Which version of MacOS are you using?
    macOS Mojave 10.14.6

  9. #9
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by defragster View Post
    Not seeing this repro on Windows - LED comes on then goes off with code below.

    @blackketter - does sending one more byte after wake it up - re-reading first post perhaps not as it notes text larger that 2413 ... so may not be related. What do you see with sketch below WRT LED?
    Once it locks up I can't unlock it with further transfers. With your example code, shorter sends to the Teensy work fine (led goes on, then goes off a couple of seconds later), but once a large transfer happens, it's stuck until I reboot.

    Interestingly, when I do send the larger file, the LED doesn't come on at all (i.e. no data from that larger transfer is ever available)

    I'm seeing now that the 2413 number isn't magical. I'm able to reproduce it now with the Teensy connected directly to the MBP USB-C port with as few as 64 byte transfers (previously it was through a couple of USB hubs...)

    Doesn't happen when I paste text into the terminal while using miniterm.py. Background: I discovered this while trying to program an ESP32 using esptool.py with the Teensy as a USB serial port adapter. Works great until esptool.py tries to send a 3k packet of code.

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Quote Originally Posted by blackketter View Post
    Once it locks up I can't unlock it with further transfers. With your example code, shorter sends to the Teensy work fine (led goes on, then goes off a couple of seconds later), but once a large transfer happens, it's stuck until I reboot.

    Interestingly, when I do send the larger file, the LED doesn't come on at all (i.e. no data from that larger transfer is ever available)

    I'm seeing now that the 2413 number isn't magical. I'm able to reproduce it now with the Teensy connected directly to the MBP USB-C port with as few as 64 byte transfers (previously it was through a couple of USB hubs...)

    Doesn't happen when I paste text into the terminal while using miniterm.py. Background: I discovered this while trying to program an ESP32 using esptool.py with the Teensy as a USB serial port adapter. Works great until esptool.py tries to send a 3k packet of code.
    @blackketter - Interesting - sounds like it is faulting?

    To see use this version of the sketch - any <FAST SPAZ> blinking?
    Code:
    #include <Arduino.h>
    elapsedMillis inw = 0;
    void setup() {
      pinMode( 13, OUTPUT );
      digitalWriteFast( 13, 1 );
      inw = 0;
    }
    
    int ii = 0;
    void loop() {
      if (Serial.available()) {
        int x = Serial.read();
        Serial.write(x);
        digitalWriteFast( 13, 1 );
        ii++;
        inw = 0;
      }
      if (inw > 2000)
        digitalWriteFast( 13, 0 );
    }
    
    void HardFault_HandlerC(unsigned int *hardfault_args)
    {
      volatile unsigned int nn ;
      while (1)
      {
        digitalWrite(13, HIGH);
        for (nn = 0; nn < 2000000; nn++) ;
        digitalWrite(13, LOW);
        for (nn = 0; nn < 18000000; nn++) ;
      }
    }
    @Paul - 'Fault Blink' the code in >> T:\arduino_1.8.10\hardware\teensy\avr\cores\teensy 4\startup.c :: HardFault_HandlerC(unsigned int *hardfault_args)

    Is still active and " GPIO2_xxx "not right for 1062 with FAST IO enabled

    Code:
    #if 1
    	if ( F_CPU_ACTUAL >= 600000000 )
    		set_arm_clock(100000000);
    	IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 5; // pin 13
    	IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(7);
    	GPIO2_GDIR |= (1<<3);
    	GPIO2_DR_SET = (1<<3);
    	while (1) {
    		volatile uint32_t n;
    		GPIO2_DR_SET = (1<<3); //digitalWrite(13, HIGH);
    		for (n=0; n < 2000000/6; n++) ;
    		GPIO2_DR_CLEAR = (1<<3); //digitalWrite(13, LOW);
    		for (n=0; n < 1500000/6; n++) ;
    	}
    #else
    	if ( F_CPU_ACTUAL >= 600000000 )
    		set_arm_clock(100000000);
    	while (1) asm ("WFI");
    #endif
    For release should the " #if 1 " be " #if 0 " ??
    >> Or perhaps better ... :: #ifdef PRINT_DEBUG_STUFF
    - then a user could turn on debug print and get FAULT blink on pin #13? Of course that would need a comment as #13 may be otherwise tied up.

    And those reg edits to GPIO2 are pre-fast IO?

  11. #11
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by defragster View Post
    @blackketter - Interesting - sounds like it is faulting?

    To see use this version of the sketch - any <FAST SPAZ> blinking?
    Thanks defroster, but alas, no. A single blink when it start, then it locks up as above without any blinks.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Interesting - must just be hung then - I didn't test with triggering a fault.

    If you did a 'pin Change interrupt to an ISR()' that did the blink in the isr() I'm suspecting that changing that pin would execute that code then.

  13. #13
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by defragster View Post
    Interesting - must just be hung then - I didn't test with triggering a fault.

    If you did a 'pin Change interrupt to an ISR()' that did the blink in the isr() I'm suspecting that changing that pin would execute that code then.
    I'm not following. Something to test?

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Quote Originally Posted by blackketter View Post
    I'm not following. Something to test?
    Yes, sorry to drop that and run.

    Here is that coded to pin #19 { #define SOME_PIN 19 } - it is set PULLUP, so when that pin is set to GND it will break into the _isr and blink { more on that off } for 2 seconds if the T4 is alive. Then return to where it was.

    If it goes to unending blink off more than on with short flashes - that is a FAULT. Same code as before should go on for 2 secs when Serial input is received. then off.

    Code:
    #include <Arduino.h>
    
    #define SOME_PIN 19
    
    // https://forum.pjrc.com/threads/57995-Teensy-4-0-USB-serial-lockup?p=218791&viewfull=1#post218791
    elapsedMillis inw = 0;
    uint jj, temp;
    void setup() {
      pinMode( 13, OUTPUT );
      pinMode( SOME_PIN, INPUT_PULLUP );
      digitalWriteFast( 13, 1 );
      attachInterrupt( SOME_PIN, debtt_isr, CHANGE);
      inw = 0;
    }
    
    void debtt_isr() {
      volatile unsigned int nn;
      inw = 0;
      while (inw <2000)
      {
        digitalWrite(13, LOW);
        for (nn = 0; nn < 7000000; nn++) ;
        digitalWrite(13, HIGH);
        for (nn = 0; nn < 18000000; nn++) ;
        delay(1);
      }
    }
    
    int ii = 0;
    void loop() {
      if (Serial.available()) {
        int x = Serial.read();
        Serial.write(x);
        digitalWriteFast( 13, 1 );
        ii++;
        inw = 0;
      }
      if (inw > 2000)
        digitalWriteFast( 13, 0 );
    }
    
    void HardFault_HandlerC(unsigned int *hardfault_args)
    {
      volatile unsigned int nn;
      while (1)
      {
        digitalWrite(13, HIGH);
        for (nn = 0; nn < 2000000; nn++) ;
        digitalWrite(13, LOW);
        for (nn = 0; nn < 18000000; nn++) ;
      }
    }

  15. #15
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by defragster View Post
    Yes, sorry to drop that and run.

    Here is that coded to pin #19 { #define SOME_PIN 19 } - it is set PULLUP, so when that pin is set to GND it will break into the _isr and blink { more on that off } for 2 seconds if the T4 is alive. Then return to where it was.

    If it goes to unending blink off more than on with short flashes - that is a FAULT. Same code as before should go on for 2 secs when Serial input is received. then off.
    Alright! Thanks! With that test the ISR blinking continues to work even after the USB serial is locked up. And no HardFault blinking.

  16. #16
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Also, I should have noted earlier that after the USB serial lockup my larger application continued to work.

    In fact, USB serial writes from Teensy to host continue to work and loop() continues to be called.

    It's just that available() never returns a non-zero value again.

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,924
    Quote Originally Posted by blackketter View Post
    Alright! Thanks! With that test the ISR blinking continues to work even after the USB serial is locked up. And no HardFault blinking.
    Quote Originally Posted by blackketter View Post
    Also, I should have noted earlier that after the USB serial lockup my larger application continued to work.

    In fact, USB serial writes from Teensy to host continue to work and loop() continues to be called.

    It's just that available() never returns a non-zero value again.
    That is interesting and should give Paul something to work with as far as info.

    I noticed during Beta that the MCU could seem USB Serial or loop() stalled, but _isr active when I was working out a debug_tt library to offer some debugging log and feedback options - which is where the above code came from.

    When that _isr triggers and blinks it can also Serial.print - as you found the output Serial is still active but stuff doesn't come in or loop() can be stalled somewhere - but the _isr() can be usefully activated.

  18. #18
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Quote Originally Posted by defragster View Post
    That is interesting and should give Paul something to work with as far as info.
    @Paul: Any clue where I could dig to see if I could find where the lockup is happening? Happy to dig in here a bit...

  19. #19
    Senior Member
    Join Date
    May 2015
    Location
    San Francisco
    Posts
    175
    Still an issue. Filed bug here https://github.com/PaulStoffregen/cores/issues/401 so this doesn't get lost.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •