'Over the Air' firmware updates, changes for flashing Teensy 3.5 & 3.6

I think I spotted the problem: my application uses Teensyduino EEPROM and that emulates EEPROM in the T41 flash chip, also at/near the top of the flash memory. Therefore, the FlashTxx.c concludes that my original codespace was as big as the entire flash rom. It thus finds not enough (zero in my case) space for a buffer in flash - because that code assumes anything != 0xffffffff from top of flash downwards is the tail of the code.
Once any program ever wrote something in top of flash of the Teensy, any subsequent program download with FlasherX (using flash buffer) will fail. The only workaround in my case was a complete Teensy41 'wipe' reset (reset switch down 15+ seconds so that flash is erased fully, and restored with the default led blink code). Looking at the memory regions picture on https://www.pjrc.com/store/teensy41.html I think the same problem will surface when using LittleFS... Not sure if the 'Restore Program' at the very top of the flash is also a risk.

Luckely there's the RAM buffer option with T41. So I better use that from now on.

For a next release, maybe add a check on buffer_size and refuse to run update_firmware if the buffer_size passed as argument to it is zero?
And not use '1' or '2' for user entry options (Serial, SD) because Intel hex format throws those same characters while it keeps attempting to finish an upload.
Plus some Delay(500) lines prior to any REBOOT; so that user can see and carefully read the error messages if any are there.
 
The "'Restore Program' at the very top of the flash is also a risk." is marked read only from the factory - so that has to have been allowed for or would simply fail for exceeding the space in FLASH.
 
Thanks.
Follow-up question then: the FlasherXX now warns with ' serial->printf( "WARNING: this can ruin your device!\n" );' and has '// WARNING: you can destroy your MCU with flash erase or write!' comments.
But is it fair to say that those warnings would relate only to pre T41? Because T41 with this 'read-only' bits cast in stone and the 'wipe reset' would make it impossible to brick it?
 
I think I spotted the problem: my application uses Teensyduino EEPROM and that emulates EEPROM in the T41 flash chip, also at/near the top of the flash memory. Therefore, the FlashTxx.c concludes that my original codespace was as big as the entire flash rom. It thus finds not enough (zero in my case) space for a buffer in flash - because that code assumes anything != 0xffffffff from top of flash downwards is the tail of the code.
Once any program ever wrote something in top of flash of the Teensy, any subsequent program download with FlasherX (using flash buffer) will fail. The only workaround in my case was a complete Teensy41 'wipe' reset (reset switch down 15+ seconds so that flash is erased fully, and restored with the default led blink code). Looking at the memory regions picture on https://www.pjrc.com/store/teensy41.html I think the same problem will surface when using LittleFS... Not sure if the 'Restore Program' at the very top of the flash is also a risk.

Luckely there's the RAM buffer option with T41. So I better use that from now on.

For a next release, maybe add a check on buffer_size and refuse to run update_firmware if the buffer_size passed as argument to it is zero?
And not use '1' or '2' for user entry options (Serial, SD) because Intel hex format throws those same characters while it keeps attempting to finish an upload.
Plus some Delay(500) lines prior to any REBOOT; so that user can see and carefully read the error messages if any are there.

In FlashTxx.h there is a macro named FLASH_RESERVE, with default 0. If you are using EEPROM/LITTLEFS, you can set FLASH_RESERVE to however large a region you are using for this purpose, and FlasherX will search downward from the bottom of this region instead of starting at the top of flash.

I had to go back and check, but this is explained briefly in the README for FlasherX on Github.

FlasherX buffers the new code in flash by default, and automatically defines the largest possible flash buffer, from the top of existing code to the bottom of FLASH_RESERVE (settable in FlashTxx.h).
 
Last edited:
Thanks.
Follow-up question then: the FlasherXX now warns with ' serial->printf( "WARNING: this can ruin your device!\n" );' and has '// WARNING: you can destroy your MCU with flash erase or write!' comments.
But is it fair to say that those warnings would relate only to pre T41? Because T41 with this 'read-only' bits cast in stone and the 'wipe reset' would make it impossible to brick it?

I think that's right. FlasherX started with T3.x, where writing incorrect values to key locations could brick the Teensy.
 
I was about to get FlasherX to run in my hardware. I am loading the hex file from an SD card. I loaded a simple blink program into the SD card and flash_move() was called. After the T41 rebooted, the original firmware was still loaded, not the blink firmware. Could the new firmware be written to a wrong location?

Code:
#define FLASH_BASE_ADDR	(0x60000000)		// code starts here

Screen Shot 2022-12-15 at 5.10.12 PM.png
 
I was about to get FlasherX to run in my hardware. I am loading the hex file from an SD card. I loaded a simple blink program into the SD card and flash_move() was called. After the T41 rebooted, the original firmware was still loaded, not the blink firmware. Could the new firmware be written to a wrong location?

Code:
#define FLASH_BASE_ADDR	(0x60000000)		// code starts here

View attachment 29965

Using RAM buffer or flash buffer? Are interrupts disabled when the move call was made? Maybe add some extra Serial.print statements (plus a delay(1000)) just before all the REBOOT statements anywhere. This to see if your Teensy ever made it that far or not. Over to joepasquariello…
 
I've tried both the RAM and Flash buffer.

I just stripped down my entire code to just the FlasherX function and the blink firmware was written successfully. So it seems like something else in my program is affecting the flash_move() function even though the same function is running. Will dig deeper.

UPDATE: Problem solved! there was an uninitialised object in one of my classes. my main program still ran fine, though I'm not sure why the flasherX function did not.


Question: what's a safe number to use for the FLASH_RESERVE value when using the Flash buffer + eeprom library? I think I had an instance where my eeprom values were overwritten when using a value of 16.
Code:
#define FLASH_RESERVE		(16*FLASH_SECTOR_SIZE)	// reserve top of flash
 
Last edited:
Question: what's a safe number to use for the FLASH_RESERVE value when using the Flash buffer + eeprom library? I think I had an instance where my eeprom values were overwritten when using a value of 16.

If you are using T4.0, the default space used by EEPROM is 15 sectors, plus there is one sector for the recovery program, so 16 would be enough. If you are using T4.1, EEPROM uses 63 sectors, plus 1 for the recovery program, so you should use 64 sectors. Note that you can increase EEPROM sizes by changing the source code in cores\Teensy4\avr\eeprom.h, too.

Also, if you use LITTLEFS in addition to EEPROM, you will need to reserve more space.
 
I have a project running on a Teensy Micromod (16mb Flash) and my sketch uses over 50% of the available flash memory.
I have PSRAM working with a custom cores fork - can I buffer the full hex in there, or on an SD card and then refrlash the device from there - basically eliminating the limitations of buffering in the onboard teensy flash?
Or am I limited to up to 50% of flash size?
 
I have a project running on a Teensy Micromod (16mb Flash) and my sketch uses over 50% of the available flash memory. I have PSRAM working with a custom cores fork - can I buffer the full hex in there, or on an SD card and then refrlash the device from there - basically eliminating the limitations of buffering in the onboard teensy flash? Or am I limited to up to 50% of flash size?

I don't think you can use SD, because that would imply that everything needed for file I/O by "flash_move" would be in RAM. It might work, but given the complexity of SdFat, it seems a bit unlikely. On the other hand, I don't see any reason why you couldn't use PSRAM. You should just have to modify the code that allows use of a RAM buffer for T4, and just give it the address and size of your PSRAM. There should be no need to "erase" the PSRAM before buffering the data there. Let us know how it goes.

EDIT: Just an additional thought. If you have extra flash on the underside of of your T4.1, that should be usable, too.
 
Back
Top