Killed a Teensy 4.0 through trying to use PlatformIO and debugging through GDB?

Knas

Member
So i was tired of the clunky Arduino IDE and decided to try and get a proper debugging scenario working with GDB https://github.com/ftrias/TeensyDebug and PlatformIO under Visual Studio Code. After much struggling i finally got it working with a test program and lo and behold a real debugger with breakpoints and watches!

So i tried to port my real program to the Visual Studio Code way of doing things and had all sorts of trouble but managed to compile it after a few hours. Unfortunately, then my Teensy just disappeared from the list of USB devices (i'm on Linux). Okay so now i noticed its blinking 9 times whenever i plug it in which apparently signals some JTAG issue? Anyway i reset the thing by holding the reset button down and after a while it reboots and shows the default blink program - success! Buuuttt its still not on the list of USB devices, no matter what i do. My other Teensy (i am a klutz so i got two) however gladly enumerates as a USB device still.

Did i manage to kill it somehow? Is Visual Studio Code the bringer of doom?
 
By default the blink restore program DOES NOT include USB serial, so what you are seeing is normal. You should be able to upload another program that does include USB serial now though and the teensy will enumerate a serial port.
 
By default the blink restore program DOES NOT include USB serial, so what you are seeing is normal. You should be able to upload another program that does include USB serial now though and the teensy will enumerate a serial port.

ohhh well arent i the idiot, i didnt even think about it *not* programming the thing over USB so i didnt look for any other USB devices.. oh boi sorry for the noise - and thank you!
 
As noted in p#2 - it is doing well if running 'Blink' after the 15 second Restore, but like when factory new that Blink code does NOT present as a USB device ... that simple Blink fits (IIRC) in a 4KB block to minimize flash loss - with USB would be much larger. Also, historically PJRC chose to not put USN even in the factory blink as (IIRC) it caused grief on older Windows when a driver had to be installed before plugging it in would go without issue.

And the Button is 'Program' not 'Reset'. It will always take the Teensy offline to bootloader mode - if the Teensy Loader is active - or when it becomes active - with a sketch to upload it will upload and restart ... until then it will sit offline waiting and not 'Reset'.

Also, interesting - another case of using PIO and having a Teensy end up in the 9 Blink state? But it ran for some time after upload? Or did it take time to get it to builod and fail right after uploading? While using debugging?

<EDIT re: p#9>: after the 15 second Restore, UNlike when factory new that Blink code does present as a USB device of type RawHID and ready for programming without a Button push.
 
Last edited:
ohhh well arent i the idiot, i didnt even think about it *not* programming the thing over USB so i didnt look for any other USB devices.. oh boi sorry for the noise - and thank you!

Nah, Teensy is unique in a number of ways. It is programmed over USB - but PJRC presents the Teensy as a RAW HID device to perform the upload. This happens on the Button push - or when the running Teensy having working USB and monitors for the 'trigger signal/message' to enter that Bootloader RAW HID mode.
 
As noted in p#2 - it is doing well if running 'Blink' after the 15 second Restore, but like when factory new that Blink code does NOT present as a USB device ... that simple Blink fits (IIRC) in a 4KB block to minimize flash loss - with USB would be much larger. Also, historically PJRC chose to not put USN even in the factory blink as (IIRC) it caused grief on older Windows when a driver had to be installed before plugging it in would go without issue.

And the Button is 'Program' not 'Reset'. It will always take the Teensy offline to bootloader mode - if the Teensy Loader is active - or when it becomes active - with a sketch to upload it will upload and restart ... until then it will sit offline waiting and not 'Reset'.

Also, interesting - another case of using PIO and having a Teensy end up in the 9 Blink state? But it ran for some time after upload? Or did it take time to get it to builod and fail right after uploading? While using debugging?

So here's the tricky part; it fails *directly* after uploading and it does it very repeatedly. It seems that if programming the Teensy using the ADS1x15 library in combination with GDBStub just kills the entire USB communication. It's happening right where it tries to initiate I2C comms with the AD
 
So here's the tricky part; it fails *directly* after uploading and it does it very repeatedly. It seems that if programming the Teensy using the ADS1x15 library in combination with GDBStub just kills the entire USB communication. It's happening right where it tries to initiate I2C comms with the AD

Hanks, first read suggested it ran some time - but re-reading suggested that was the time to make the build work.

Would be interesting if the same build could be done with the Arduino IDE to see if the result is the same.
 
As noted in p#2 - it is doing well if running 'Blink' after the 15 second Restore, but like when factory new that Blink code does NOT present as a USB device ... that simple Blink fits (IIRC) in a 4KB block to minimize flash loss - with USB would be much larger. Also, historically PJRC chose to not put USN even in the factory blink as (IIRC) it caused grief on older Windows when a driver had to be installed before plugging it in would go without issue.

This is incorrect.

Teensy 4.x after the 15 sec restore, and every brand new Teensy, does indeed have USB communication as RawHID. The tiny program packed into just 4K at the end of flash memory, which gets copied to the beginning of flash as part of the restore process, does indeed implement USB as RawHID (yes, quite a lot of special optimization work was done to cram it into only 4K).

It is not USB Serial, so programs like PIO that only understand serial devices won't see it. But if you use Arduino IDE, after 15 sec restore completes and the orange LED is blinking again, you should see Teensy detected like this in the Tools > Ports menu. This screenshot is Ubuntu 20.04, but you should see something very similar on Windows, MacOS and other Linux.

screenshot.jpg

Of course, after you load your own code, Teensy will reappear as whatever USB Type your program uses. In Arduino IDE you would select that from Tools > USB Type. In PlatformIO, maybe you need to edit some INI file? I don't use PIO, so I can't say for sure. As far as I know, PIO doesn't have any sort of GUI like Arduino IDE Tools > Ports which can detect and show you Teensy in any of the supported USB Types. My limited understanding of PIO is it's basically designed like the early days of Arduino IDE where everything was assumed to always be a serial port.
 
This is incorrect.

Teensy 4.x after the 15 sec restore, and every brand new Teensy, does indeed have USB communication as RawHID. The tiny program packed into just 4K at the end of flash memory, which gets copied to the beginning of flash as part of the restore process, does indeed implement USB as RawHID (yes, quite a lot of special optimization work was done to cram it into only 4K).

It is not USB Serial, so programs like PIO that only understand serial devices won't see it. But if you use Arduino IDE, after 15 sec restore completes and the orange LED is blinking again, you should see Teensy detected like this in the Tools > Ports menu. This screenshot is Ubuntu 20.04, but you should see something very similar on Windows, MacOS and other Linux.
...
Of course, after you load your own code, Teensy will reappear as whatever USB Type your program uses. In Arduino IDE you would select that from Tools > USB Type. In PlatformIO, maybe you need to edit some INI file? I don't use PIO, so I can't say for sure. As far as I know, PIO doesn't have any sort of GUI like Arduino IDE Tools > Ports which can detect and show you Teensy in any of the supported USB Types. My limited understanding of PIO is it's basically designed like the early days of Arduino IDE where everything was assumed to always be a serial port.

I sit corrected! And confirmed: T_4.1 after 15 sec Restore does present as RawHID

It is running 'Factory' Blink - but online as RawHID and ready for upload without a Button push!:
RawhidRestore.png
So not "Factory" NOOB Blink with no USB as wrongly assumed and indicated.
 
Try updating your core library to the latest from github.

Or if that's too much trouble, try manually applying just this patch to startup.c

https://github.com/PaulStoffregen/cores/commit/3f95c8e6f632d76ca20210cd5edef92fa791191d

Does that make any difference?

So i downloaded & installed everything yesterday, including teensyduino however i found that the process was quite cumbersome and confusing so i might have done something wrong?

So i think i was confused because i'm using Arduino 2.0 (as an appimage) to program the teensy and for that all i had to do was install the teensy extension and it worked like a charm.

GDBStub however requires teensyduino - it turns out - and teensyduino in turn requires Arduino 1.8 so after much hair pulling i figured it all out and installed Arduino 1.8, then teensyduino that then let me install GDBStub TeensyDebug. However this *still* didnt make the latter get copied anywhere that PlatformIO understood (which i assumed it would) so i manually copied it into the "framework-arduinoteensy/libraries" so that PlatformIO / Visual Studio Code would be able to find & use it.

It works like a charm to debug the classic "blink"-project but ill make a minimal project using the ADS1x15 to verify thats whats breaking it
 
Alright so i did some investigation and im running this small program

Code:
#include <Arduino.h>
#include <TeensyDebug.h>
#include <Adafruit_ADS1X15.h>

#pragma GCC optimize ("O0")

Adafruit_ADS1115 ads;

void setup(){
  while (!SerialUSB1) {}    // Wait for Debugger connect
  debug.begin(SerialUSB1);  // Start Debug Serial e.g. COM11

  Serial.begin(115200);     // Start User Serial e.g. COM10
}

int boop = 0;

void loop(){
  boop++;
  digitalWrite(LED_BUILTIN, HIGH);   // <<<<< Add A Breakpoint on this line
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

With my platformio.ini looking like
Code:
[env:teensy40]
platform = teensy
board = teensy40
framework = arduino

lib_deps =
  SPI
  Adafruit ADS1X15
  TeensyDebug
  
;build_type = debug
; See https://github.com/platformio/platform-teensy/issues/65
build_unflags = -DUSB_SERIAL
build_flags = -DUSB_DUAL_SERIAL
debug_port = /dev/ttyACM1
debug_tool = custom
debug_load_mode = manual
debug_server = 
debug_init_cmds =
  target extended-remote $DEBUG_PORT
  $INIT_BREAK
  define pio_reset_run_target
  interrupt
  tbreak loop
  continue
  end
  define pio_restart_target
  echo Restart is undefined for now.
  end

debug_init_break =

This works perfectly, i can debug it and put a watch on 'boop' and step through and see how it increases. However, if i change my setup() to include ads.begin() like so
Code:
void setup(){
  while (!SerialUSB1) {}    // Wait for Debugger connect
  debug.begin(SerialUSB1);  // Start Debug Serial e.g. COM11

  Serial.begin(115200);     // Start User Serial e.g. COM10

  ads.begin();
}

All USB ports immediately disappear after programming and i have to do a hard reset. Interestingly enough, if i simply comment out "build_type = debug" in platformio.ini, the program works great - but then i cant debug it anymore so whats the point
 
All USB ports immediately disappear after programming and i have to do a hard reset. Interestingly enough, if i simply comment out "build_type = debug" in platformio.ini, the program works great - but then i cant debug it anymore so whats the point


You might check if your hang/crash when specifying DEBUG optimization is a result of <this> (the whole background story can be found in the rest of the thread), and if so, you should be able to temporarily apply Paul's patch until the next release of Teensyduino comes out.

Hope that helps,

Mark J Culross
KD5RXT
 
You might check if your hang/crash when specifying DEBUG optimization is a result of <this> (the whole background story can be found in the rest of the thread), and if so, you should be able to temporarily apply Paul's patch until the next release of Teensyduino comes out.

Hope that helps,

Mark J Culross
KD5RXT

Well would you look at that, just like Paul said. It totally works now! I thought for some reason this commit was already in the teensyduino that was here https://www.pjrc.com/teensy/td_download.html but i was obviously wrong.

Looking forward to doing some actual debugging of my code now! Thank you to everyone who answered, this is one of the more helpful forums i've experienced!
 
Well i guess i talked too quickly. It seems now that if i instead *remove* all the TeensyDebug stuff and just try to run a clean program i get the same behavior as i did before updating startup.c.

My platformio.ini

Code:
[env:teensy40]
platform = teensy
board = teensy40
framework = arduino

lib_deps =
  SPI
  Adafruit ADS1X15
;  TeensyDebug
  
;build_type = debug
;; See https://github.com/platformio/platform-teensy/issues/65
;build_unflags = -DUSB_SERIAL
;build_flags = -DUSB_DUAL_SERIAL
;debug_port = /dev/ttyACM1
;debug_tool = custom
;debug_load_mode = manual
;debug_server = 
;debug_init_cmds =
;  target extended-remote $DEBUG_PORT
;  $INIT_BREAK
;  define pio_reset_run_target
;  interrupt
;  tbreak loop
;  continue
;  end
;  define pio_restart_target
;  echo Restart is undefined for now.
;  end
;
;debug_init_break =

and my main.cpp


Code:
#include <Arduino.h>
//#include <TeensyDebug.h>
#include <Adafruit_ADS1X15.h>

//#pragma GCC optimize ("O0")

Adafruit_ADS1115 ads;

void setup(){
//  while (!SerialUSB1) {}    // Wait for Debugger connect
//  debug.begin(SerialUSB1);  // Start Debug Serial e.g. COM11

  Serial.begin(115200);     // Start User Serial e.g. COM10

  ads.begin();
}

int boop = 0;

void loop(){
  boop++;
  digitalWrite(LED_BUILTIN, HIGH);   // <<<<< Add A Breakpoint on this line
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

I'm wondering if i botched my platformio / arduino installation? I just found the old startup.c files and replaced it with the one from github. Btw the reason i tried running without the debug stuff is because the debugger was reporting inconsistent and obviously incorrect variable contents through the watch list and it would also show "optimized out" for a bunch of stuff despite optimization being turned off, i dont know if this means anything.
 
Back
Top