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

LAtimes

Well-known member
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() {
}
 
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.
 
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.
 
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);
 
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
 
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.
 
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:
[B]__attribute__((section(".startup"), optimize("no-tree-loop-distribute-patterns")))[/B]
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.
 
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:
@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.
 
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.
 
I just tried compiling with DEBUG for the first time. With Teensy 4.1 (Teensyduino 1.54, Arduino 1.8.15), I have no USB serial.

Did the problem described here get fixed? Do I have this same problem or maybe a new one? How might I be able to tell?

Chip
 
I just tried compiling with DEBUG for the first time. With Teensy 4.1 (Teensyduino 1.54, Arduino 1.8.15), I have no USB serial.

Did the problem described here get fixed? Do I have this same problem or maybe a new one? How might I be able to tell?

Chip

@chipaudette ... Don't recall anything going by that seems related?

There was a general startup issue addressed in TD 1.54 regarding cache or other configuration that causes weird hangs where the cache overlapped or something.

I see p#6 noting the _hooks fail to run "C" code and vars - which I saw the other week is because the __libc_init_array(); occurs after both hooks that suggests that code and memory gets made ready with _init_ after those.


Above issue might be a good case for CrashReport if it was faulting and still does (based on p#4) ... Though sounds like it is up and running in p#14 case - just without usable USB?
 
I ran the sketch from the first post with Teensyduino 1.54, Arduino 1.8.15, compiled with Debug, and it worked. So it appears the issue was fixed in 1.54.
 
I ran the sketch from the first post with Teensyduino 1.54, Arduino 1.8.15, compiled with Debug, and it worked. So it appears the issue was fixed in 1.54.

Indeed it does - was just getting there. p#1 and p#4 variant both work debug and normal fastest.

I started with p#6 - can't get that resolved for working hook()'s ... even moving the init_array() ??
 
I know this is old but it is happening to me using Teensy 4.1, VS Code, PIO, TD 1.57, Teensy lib 4.17.0

using build_type=debug causes the issue
 
Last edited:
Yes, PlatformIO has long-standing problems with Teensy and whatever it's doing for a debug build. Not surprising it hasn't been fixed yet. Maybe they'll fix it someday, but I wouldn't hold my breath waiting.

Just to be clear, as far as PJRC is concerned, PlatformIO is unsupported software, especially in the many ways it can be configured which differ from usage of Arduino & Teensyduino. You're free to discuss PlatformIO bugs here, but don't expect that discussion to lead to a fix. PlatformIO's github issue tracker is the proper place to request a fix.
 
I have spent the last week looking at getting gdb debugging using the TeensyDebug gdb stub to work under platformio/vscode. I have got to a situation where a can I can get into a debug session and do some basic stuff. I eventually hit a problem with the version of arm-none-eabi-gdb running on the host. I will look into that later, it is not the reason for this post.

On the teensy side I have run into a number of usb-serial related problems, including the one mentioned in this thread.

The remote debugging process using TeensyDebug needs a minimum of two CDC virtual USB serial ports to work properly. To debug a sketch that uses the audio library probably requires three (not yet verified).

When -DUSB_DUAL_SERIAL is defined the port associated with SerialUSB1 is enumerated first and is the first device node (/dev/ttyACM1) to appear in the host OS file system, followed by the port associated with Serial (/dev/ttyACM0). This can confuse platformIO, but can be worked around.

This leaves the showstopper. Turning off optimisation of the source code of the sketch triggers the problem referred to in this thread. The sketch never gets executed and the teensy freezes and needs a major reset to unbrick it.

I cannot see that this has anything to do with platformio. It is either in the compiler that is being used or it is in startup.c.

How do we move forward on this?

Roger
 
Use VisualMicro with Visual Studio. All the benefits!! of platformIO without the built in problems/
Also, since it is built on top of the Arduino IDE it is effectively supported by PJRC.
 
Thanks for your reply. But that is not the problem I am looking at. There may well be a combination of compiler flag and preprocessor definitions that cause the same problem in any other IDE.
 
Thanks for your reply. But that is not the problem I am looking at. There may well be a combination of compiler flag and preprocessor definitions that cause the same problem in any other IDE.

same problem in any other IDE
If you post a sketch that reproduces this on IDE 1.8.19 or IDE 2.0.1 (current) and with current TeensyDuino 1.57 or 1.58Beta that could lead to a resolution.
 
Back
Top