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

I've tried the flasher 3b and it goes well till it responds with lower FSEC and upper FSEC match then stops, the example file never runs. Am I missing something?
If I power cycle the t3.5 it still has the flasher code running. Should not the example code start running?
I can use the teensy loader to load/test the BlinkT35.hex file and it works.
 
Last edited:
After you see those messages, you need to type in ":flash XXXX", where XXXX is the number of lines reported by the program, and then hit Enter. When you hit Enter, as long as you have typed in the ":flash" command correctly, with the correct number of lines, you'll see a message that the board is being flashed, and after that is a reboot. You'll know the new program was flashed if you see a number of lines indicating sectors in upper flash being erased after the reboot.
 
> you need to type in ":flash XXXX", where XXXX is the number of lines reported by the program

I recommend that you don't do this. Type in ":flash XXXX", where XXXX is the number of lines you counted in your hex file. The distinction could be critical. Hmm, perhaps the program should be modified to not report XXXX.
 
Hi Jon. Yes, what the Flasher program is doing now (and has always done), is report the number of valid lines received. If it receives any invalid lines or, in the case of T35/T36, it receives a line that is not 64-bit-aligned, the process will abort. I suppose it's possible that exactly one hex line could be somehow "lost", such that Flasher would not report an error, but the flash image would be invalid.
 
That is my concern. Some protocols are likely to lose exactly an entire line. This could get flashed and the error might not be immediately obvious.
 
This is a limitation of using a terminal emulator to send an ASCII hex file. There is no error checking except the record-level checks within the target. I can write a very simple command-line program to send a hex file, count the records, and perhaps also compute a CRC of the flash image. The target-side code, after receiving the EOF record, could send its record count and internally-computed CRC, and if they match, the command-line program could send the "flash" command.
 
Can the flasher3b version handle the hex file output from the complier? or is it necessary to convert it with intelhex.exe first?
when I try to use the hex file as is I get 'flash_block align error cant flash 4 bytes to dc10' on the last line of the file.
When I convert it with IntelHex I get lower FSEC (fffff9deffffffff) and upper FSEC (af72f43f2800fa8a) do NOT match
new firmware not compatible (must contain board ID string fw_teensy3.5)
Ok have tried to use the example blinkwithoutdelay complied for t35 and as is get the same issue about cant flash x bytes.
Run the intelhex on it and get...
done, 660 hex lines, address range 0:2930, waiting for :flash 660
lower FSEC (fffff9deffffffff) and upper FSEC (fffff9deffffffff) match
new firmware not compatible (must contain board ID string fw_teensy3.5)
 
Last edited:
For T35/T36, you must use the IntelHex.exe to convert from 32-bit aligned records to 64-bit aligned. That will avoid the "align error".

Any application you upload must contain the appropriate ID string, e.g. "fw_teensy3.5" for T3.5. This is to prevent an application built for T3.2 being uploaded to a T3.5, etc. Take a look at Flasher3b.h and you can copy the set of conditional defines to the application you want to upload.

Are you getting the "FSEC doesn't match" in the same upload for which you're getting an align error? If so, please try running your hex file through IntelHex.exe and try again.
 
will this be all I need to add to the code

#define FLASH_SIZE 0x80000 // 512Kb of program flash
#define FLASH_SECTOR_SIZE 0x1000 // 4Kb sector size
#define FLASH_WRITE_SIZE 8 // 8-byte/64-bit flash memory writes
#define FLASH_ID "fw_teensy3.5"
#define RESERVE_FLASH (0 * FLASH_SECTOR_SIZE)
 
You just need the #define FLASH_ID "fw_teensy3.5", and then you need to make sure that string gets used within your program. What I suggest is adding a line in your setup function that says Serial.println( FLASH_ID );

If you copy over that whole block of conditional defines, and then delete all of #define statements except for those that define FLASH_ID for each Teensy, whichever Teensy you build for will have the correct FLASH_ID embedded in the hex file.
 
Okay. This is the set of conditional defines you need to add to your program, than add the Serial.println(FLASH_ID);

#if defined(__MK20DX128__)
#define FLASH_ID "fw_teensy3.0"
#elif defined(__MK20DX256__)
#define FLASH_ID "fw_teensy3.2"
#elif defined(__MK64FX512__)
#define FLASH_ID "fw_teensy3.5"
#elif defined(__MK66FX1M0__)
#define FLASH_ID "fw_teensy3.6"
#else
#error "MCU NOT SUPPORTED BY THIS TEST PROGRAM"
#endif
 
I have gotten some success in this with your help,
I need some help understanding this output
done, 4097 hex lines, address range 0:10000, waiting for :flash 4097
lower FSEC (fffff9deffffffff) and upper FSEC (fa30f0014620af7d) do NOT match

looking at the flasher3b.h file my file is less then half the flash size, is there any file size limits?

In order to test things I tried with a small program, blink without delay, put the necessary parts into it, compile, convert
and got it to load, with upper and lower match ok. blinks as it should.
 
Last edited:
I just repeated my tests with T3.2, T3.5, and T3.6, and in all 3 cases, I get a match on the FSEC field between upper (new program) and lower (existing program). The program size limit is 1/2 of the flash size, so 128K for T3.2, 256K for T3.5, and 512K for T3.6.

Can you please specify your target, Arduino and TeensyDuino versions, and build environment?

Also, please open your hex file, copy the record for address 0400, and post it here? It should look as shown below, but without the spaces. For T3.2, the FSEC field is 4 bytes beginning at 040C, and for T3.5/T3.6, it's 8 bytes beginning at 0408.

:10 0400 00 FFFFFFFF FFFFFFFF FFFFFFFF DEF9FFFF 23
 
I'm testing and am wondering if the problem is with intelhex, seems it only reports memory 0000 to ffff written.
the flasher works with code converted thats under ffff bytes in length.

:10040000F3627FE700283FF47DAF204601F030FA29
 
I did a little more digging, and to clarify, for all T3.x, the 16 bytes from 0400 to 040F are set aside as "flashconfig" in the linker files (*.ld). File mk20dx128.c in cores\teensy3 defines those 16 bytes as shown below, where FSEC = DE and FOPT = F9. If other values get written to those critical addresses, you could brick your teensy.


__attribute__ ((section(".flashconfig"), used))
const uint8_t flashconfigbytes[16] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, FSEC, FOPT, 0xFF, 0xFF
};
 
Yes, you're right, IntelHex is currently limited to 64K. I'll have to modify it to handle larger files. Please provide the info about your target and your build environment. If you're using a build environment other than Arduino, your link process may not be correctly setting addresses 0400 to 040F.
 
I must be lucky..lol
I can still upload the flasher code to the t35.
I dont try to :flash xxx if it reports a mismatch. so no bricked teensy yet.
I'm still thinking it might be intelhex limits to 64k
 
The address field in the intel hex format is 16 bits, so the max is 65535. For files larger than 64K, additional record types come into play that specify "base address", and the 16-bit address field becomes an offset to that base. I'll need to review that before I can update IntelHex to support larger files. It may also require an update to Flasher3b.
 
I did some work on this, just trying to understand the workings of the hex file.
I complied a blink program, looked at the hex file and found that at about 3/4 into the file was a misaligned data line.
:0C2BA0009E467047992600003504000096
:042BAC00F8B500BFB9
I noticed these two lines were 12 and 4 bytes so I fixed this to 1 line of 16 bytes and added the checksum.
:102BA0009E4670479926000035040000F8B500BF26
At the end of the file I padded the last line to 16 bytes.
:1034B000FFFFFFFF00000000000000000000000010
:00000001FF
Using flasher3b I got the hacked file to load and run.
Still got work todo.
Joe did you write IntelHex.exe yourself?
 
All Teensy hex files seem to have those lines. The IntelHex program does the same "fix" that you did manually. It is based on a C file (ihex.c) written by Paul, with just a couple of small changes that I made, plus my addition of ihex.h and main.c, all of which are attached. If you look at function load_file() in ihex.c, you'll see that it calls parse_hex_line() for each hex record, then processes that record according to whether the returned status value is 0 (data) or 1 (end of file). Hex files for programs larger than 64K will have additional status values, which are actually hex record types, and those additional record types would need to be handled by load_file(). If you look at the hex record parsing in flasher, you'll see that it handles those additional record types, so you can probably adapt what Jon did within Flasher to IntelHex.
 

Attachments

  • ihex.c
    6.5 KB · Views: 72
  • ihex.h
    792 bytes · Views: 81
  • main.c
    326 bytes · Views: 78
Back
Top