Prevent flashing Teensy in deployed state to prevent accidentally flashing wrong one

usererror

Active member
First off: Obligatory disclaimer that I did search, and did not find an answer. Most likely because my search terms were way off the mark.

I have a whole pile of teensy HID projects. One day I hit upload and realized I hadn't manually set the port, and I flashed my input device (teensy powered of course) instead of the teensy I was trying to flash.

I still want to be able to update my HID projects, but I'd like to have a physical switch or some way of preventing them from showing up as a flashable teensy to the Arduino IDE / Platform IO, without making my life too difficult. It'd be worth noting that my HID projects are things I would distribute to others. Accessibility devices, or custom input devices that in some way fill a need not otherwise being filled. It would be great if they could flash it themselves when I'm not around to do so with updated firmware (lets assume it'd be because I didn't test it well enough to find every quirk or bad assumption I made when I wrote it). But, I don't want them accidentally flashing it, like I've done, and suddenly not have a mouse or keyboard or whatever HID device it happens to be.

Not sure what search terms to use to get the answer, so I'm left asking.

I think my preferred solution if possible would be to dedicate a pin to switch it into program mode like some ESP32s do (the ones that don't do it automatically), but if I could in the loop() just say "don't get flashed", that'd solve it for me as well as long as I never forgot to add a delay in setup(). No idea if this is possible, but I suspect I'm not that lucky today.
 
The reset to bootloader command is coded in the CORES in response to USB setting baud to 134.

Not noted what Teensy. Check out these files in the local install.
Edits to the right one can do a programmatic response with a pin check or other as desired perhaps:
Code:
C:\T_Drive\arduino-1.8.19\hardware\teensy\avr\cores\teensy3\usb_dev.c:
  646  				//serial_phex32(line_coding[0]);
  647  				//serial_print("\n");
  648: 				if (line_coding[0] == 134) usb_reboot_timer = 15;
  649  			}
  650  			endpoint0_transmit(NULL, 0);

C:\T_Drive\arduino-1.8.19\hardware\teensy\avr\cores\teensy4\usb.c:
  791  		memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
  792  		printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
  793: 		if (usb_cdc_line_coding[0] == 134) {
  794  			usb_start_sof_interrupts(NUM_INTERFACE);
  795  			usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  ...
  801  		memcpy(usb_cdc2_line_coding, endpoint0_buffer, 7);
  802  		printf("usb_cdc2_line_coding, baud=%u\n", usb_cdc2_line_coding[0]);
  803: 		if (usb_cdc2_line_coding[0] == 134) {
  804  			usb_start_sof_interrupts(NUM_INTERFACE);
  805  			usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  ...
  811  		memcpy(usb_cdc3_line_coding, endpoint0_buffer, 7);
  812  		printf("usb_cdc3_line_coding, baud=%u\n", usb_cdc3_line_coding[0]);
  813: 		if (usb_cdc3_line_coding[0] == 134) {
  814  			usb_start_sof_interrupts(NUM_INTERFACE);
  815  			usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec

C:\T_Drive\arduino-1.8.19\hardware\teensy\avr\cores\usb_serial\usb.c:
  500  				| ((uint32_t)cdc_line_coding[2] << 16)
  501  				| ((uint32_t)cdc_line_coding[3] << 24);
  502: 			if (baud == 134UL) reboot_timer = 15;
  503  			if (baud == 150UL) {
  504  				UENUM = CDC_TX_ENDPOINT;

C:\T_Drive\arduino-1.8.19\hardware\teensy\avr\cores\usb_serial_hid\usb.c:
  787  			usb_ack_out();
  788  			usb_send_in();
  789: 			if (*(long *)cdc_line_coding == 134L) reboot_timer = 15;
  790  			if (*(long *)cdc_line_coding == 150L) {
  791  				UENUM = CDC_TX_ENDPOINT;

Another tool would be to use and distribute TyCommander for uploads that allows pinpointing the desired device.
 
It is primarily for the 4.1, but I could make heavy use of it on the LC, 3.2, and 3.6 (every teensy model I have).

I've been re-reading this over and over. Its a bit above my head, but I'll chip away at it.
I'm going to have to take a run at this again a bit later after reading through the cores files and trying to get a better understanding of it.

Thank you for the direction defragster. I'm definitely not familiar enough with how it handle these things, and I think the 4.x changed how these things work so I'll have to do some comparisons.
Maybe I'll try on an LC before I try it on the new and shiny 4.1's.
 
As long as you save a copy of the original source file the change can always be restored - or a reinstall with TeensyInstaller.

It won't cause any harm - it will just NEVER reboot for upload without pushing the physical button.

That code uses a file 'static' variable and enables an interrupt to trigger the _reboot_Teensyduino_();
Code:
				usb_stop_sof_interrupts(NUM_INTERFACE);
				_reboot_Teensyduino_();

So first guess is just comment out those sets of lines and the USB baud set to 134 will be ignored. Though not sure if that is checked ONCE or continuously on subsequent USB messages.

Will take a few tests and then if a button under your control indicates it should upload new code the trigger that with a call to code like _reboot_Teensyduino_();
 
Back
Top