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

Thread: No USB serial with Teensy 4.x compiled Optimize: Debug

  1. #1

    No USB serial with Teensy 4.x compiled Optimize: Debug

    I compiled the short sketch below with Optimize: Debug and no USB serial port is created under Windows or Linux. It works when using any other Optimize setting, and works with Teensy 3.5 compiled Debug.

    Teensy 4.0 and 4.1
    Arduino 1.8.13
    Teensyduino 1.52 and 1.53
    Windows 10, Ubuntu

    Code:
    void setup() {
      Serial.begin(115200);
      while (!Serial);
    
      Serial.println("Hello world");
    }
    
    void loop() {
    }

  2. #2
    I started digging into this in startup.c, and as soon as I uncommented any of the debug lines 59-63, it started working.

    I add 1 nop and it still failed, but 2 nop's work. The nop's can be added anywhere in ResetHandler.

    This makes me think something doesn't like its alignment offset. Looking at the disassembly, adding 1 nop doesn't change much regarding alignment - the compiler just removes another nop it added for alignment later on. But 2 nop's shifts all the following alignments by 4 bytes.

    Optimize: Debug just happens to have the wrong alignment and the other optimize settings are right.

  3. #3
    Can anyone else duplicate the problem in the first post or is it just me?

    Note that it locks up the Teensy and you have to press the button to get into the bootloader.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195

    THIS DOES REPRO on T_4.1

    Copied presented code into IDE - compiled default and it worked.

    Changed to DEBUG and the Teensy HANGS/goes away after upload.

    Indeed takes a BUTTON to get to bootloader and a reset then ( TyCommander ) - just takes it missing again.

    Changed code to this - and still fails the same - no sign of LED - works when FASTER::
    Code:
    void setup() {
      Serial.begin(115200);
      while (!Serial);
      pinMode( 13, OUTPUT );
      digitalToggle(13);
      Serial.println("Hello world");
    }
    
    void loop() {
      digitalToggle(13);
      delay(100);
    }
    Removing these lines doesn't help:
    Code:
      //Serial.begin(115200);
      //while (!Serial);

  5. #5
    Thanks for the info. I will continue to investigate - maybe a good excuse to try gdb.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195
    Quote Originally Posted by LAtimes View Post
    Thanks for the info. I will continue to investigate - maybe a good excuse to try gdb.
    I was going to mention GDB - but not sure it gets that far - worth a try ...

    Paul: Should any of this work? pinMode() and the globals are not usable in the _hooks() ???
    >> Wrote this to try to see if it gets this far under normal Faster optimization - and it all fails on T_[3.0, 3.1, 3.6, 4.1]
    Code:
    uint32_t test0;
    uint32_t test1;
    uint32_t test2;
    
    void startup_early_hook() {
    	test0 = millis()+2;		// this doesn't work ???
    	//pinMode( 13, OUTPUT );
    	//digitalWrite(13, 1);
    }
    
    void startup_late_hook() { // none of this works
    	test1 = micros()+2;
    	test2 = micros()+2;
    	pinMode( 13, OUTPUT );
    	digitalWrite(13, 1);
    }
    
    void setup() {
    	while (!Serial);
    	pinMode( 13, OUTPUT );
    	digitalWrite(13, 1);
    	delay(3100);
    	Serial.println("Hello world!");
    	Serial.println(test0);
    	Serial.println(test1);
    	Serial.println(test2);
    }
    
    void loop() {
    	digitalToggle(13);
    	delay(100);
    }
    Output for the globals all zeros?
    Code:
    Hello world!
    0
    0
    0

  7. #7
    I've traced this problem down to the last line of configure_cache in startup.c. By adjusting the number of nop's in front of it, I can make it consistently work or fail.

    Also, if this line only enables the data cache, it works; if it only enables the instruction cache, it fails, so the instruction cache is the problem.

    If the instruction that writes to the SCB_CCR register is in the last 3 words of an instruction cache line (address 1a, 1c, 1e), then it locks up the CPU. Any other location works.

    It looks like the cache is being invalidated properly before enabling. Don't know why this is happening. Workaround could be a judicious align statement.

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195
    Quote Originally Posted by LAtimes View Post
    I've traced this problem down to the last line of configure_cache in startup.c. By adjusting the number of nop's in front of it, I can make it consistently work or fail.

    Also, if this line only enables the data cache, it works; if it only enables the instruction cache, it fails, so the instruction cache is the problem.

    If the instruction that writes to the SCB_CCR register is in the last 3 words of an instruction cache line (address 1a, 1c, 1e), then it locks up the CPU. Any other location works.

    It looks like the cache is being invalidated properly before enabling. Don't know why this is happening. Workaround could be a judicious align statement.
    Other func()'s in startup are decorated as follows, and changing this func() allows it to work here as debug in a quick test:
    Code:
    __attribute__((section(".startup"), optimize("no-tree-loop-distribute-patterns")))
    void configure_cache(void)
    {
    This segment is kept on FLASH/PROGMEM - same as it was before - but the optimize setting let it work here when tried with post #1 code compiled debug.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195
    @LAtimes - this pull request was created : github.com/PaulStoffregen/cores/pull/481

    If the change works in testing for you please confirm.

  10. #10
    The change does cause the problem to go away. However, it is because it changes the memory map. I can make the problem re-appear by adding nop's to align the memory such that it fails again. So if Paul fixes some of the TODOs in this routine, the problem could come back in future releases.

    I added setting the LED at various lines after configure cache to see what is really happening. It would flash the LED quickly (~3-4 Hz) right after configure cache - my guess is that the CPU is continuously resetting. The LED stopped turning on when I put it right after enabling the RTC (SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS. But I don't think it's what that line does - if I replace it with nop's, the LED still stops turning on. Maybe this is where the instruction cache hits a bad line or something.

    That's it for this evening.
    Last edited by LAtimes; 07-11-2020 at 03:25 AM. Reason: more info

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195
    @LAtimes - good feedback for Paul. Seeing that optimize used throughout - hoped it might disable some compiler smarts behind the trouble. Though indeed seems on the edge some timing race? Starting cache running from Flash.

  12. #12
    More digging this morning. Appears to be a timing issue near this line in startup.c:

    usb_pll_start(); reset_PFD(); //TODO: is this really needed?

    If I comment out the reset_PFD, it starts working. Also adding nop's in various places nearby/within makes it work. (Note the nop's with why oh why? nearby - maybe related?).

    I think that with the instruction cache enabled and a certain sequence of code within the same line of the cache, it goes too fast.

    I'm going to put this on the back burner for now and let the PLL experts (are there any?) figure this out.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,195
    @Paul and @LAtimes :: Indeed that is a BAD HACK! I had it in place and next 'FASTER' compile of the NAND WIP progress code FAILED to start like in Post #1.

    Added a NOTE to that PR #481 and CLOSED it.

Posting Permissions

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