Teensy 3.5 not always rebooting after OTA firmware update with FlashTxx

Status
Not open for further replies.

paynterf

Well-known member
I have a short T3.5 OTA demo program (TeensyFlashDemoV2.ino) that uses FlashTxx.cpp/h and a TeraTerm macro to automate firmware updates over an HC-05 Bluetooth link. This program works great, and the T3.5 reboot is consistent and fast (within 1-2 seconds after hex file upload completion).

I have another T3.5 program for my robot that uses the same strategy, but the OTA firmware update doesn't behave the same. Instead of the reboot occurring 1-2 seconds after the hex file upload, it takes 5-6 seconds, and sometimes (maybe 1 in 3 or 1 in 5) doesn't reboot at all. I know the firmware update succeeded because if I cycle power to the Teensy, it comes back up running the new firmware.

Both programs use identical FlashTxx.cpp/h code, and exactly the same TeraTerm macro. The demo program hex file is 139Kb and the robot program hex file is 217Kb. I anticipate the robot program growing considerably as I add capability - probably twice the current size.

Any idea what is going on here? Is there some sensitivity to hex file size?

I have attached two ZIPped folders - one for TeensyFlashDemoV2 and one for T35_WallE3_V3 (my robot program). Both projects use VS2019 with the Visual Micro extension.

Any thoughts?

TIA,

Frank
 

Attachments

  • TeensyFlashDemoV2.zip
    1.5 MB · Views: 26
  • T35_WallE3_V3.zip
    90.3 KB · Views: 31
Any idea what is going on here? Is there some sensitivity to hex file size?

I'm only guessing, Frank, but my guess is what you're seeing is a timing and/or buffering issue. You could try increasing your receive buffer sizes via addMemoryForRead() and addMemoryForWrite(), so if something gets delayed briefly, you're less likely to lose any bytes in the transfer. I don't have any experience with bluetooth, so I don't know if there are any potential pitfalls there.

So far, FlasherX simply receives text from TeraTerm (or some other terminal program), with no hand-shaking. As fast as the terminal program can send the data, the Teensy must receive the hex file (text), parse the hex records and write to flash. This is simple, and it's nice because there is no custom host programming required, but if it doesn't keep up, the download can fail. For my own purposes, I would not rely on that method for anything but a demo. What I plan to do next, and I'm pretty close, is to show how to use packetized communication, with the host (PC or other Teensy) sending packets and waiting for an acknowledgement from the target (Teensy), and also use a more rigorous confirmation method, such as a 16-bit CRC of the entire new firmware.
 
You could try increasing your receive buffer sizes via addMemoryForRead() and addMemoryForWrite() said:
Thanks for the pointer - I wasn't aware of those functions. I'll give it a whirl and see what happens ;)

Frank
 
OK, I looked up the addMemoryForRead() and addMemoryForWrite() functions, but I'm unsure about where they would go in the present FlashTxx.cpp/h setup, so I have some questions ;-).

The behavior I'm observing is that the entire hex file is received and parsed correctly, every time, but sometimes the Teensy reboot fails. I'm pretty sure the hex file is received via the serial link and then moved into flash properly, because even if the Teensy doesn't reboot properly, if I cycle power to the Teensy it always (at least so far) comes back up running the new firmware. So, I'm not sure that larger transmit/receive buffers will help - what do you think?
 
You should only have to add the lines shown below to your INO file. You don't need to modify FlashTXX.cpp/h. It contains just the functions required to read/write/erase flash in the process of installing new firmware, which are independent of the method or format in which new firmware is being sent to the Teensy. For example, FlasherX receives the Teensy hex file, but there is nothing in FlashTXX that is specific to hex files.

Code:
// global variables
uint8_t rxbuffer[512];
uint8_t txbuffer[512];

void setup()
{
  ...
  Serial1.addMemoryForRead( rxbuffer, sizeof(rxbuffer) );
  Serial1.addMemoryForWrite( txbuffer, sizeof(txbuffer) );
  ...

Since the reboot is consistent with your OTA demo program, but not your larger robot program, I think it's safe to say your larger program is somehow responsible for the delay. FlasherX.ino does nothing but listen for new firmware on the specified USB or UART serial. What does your robot program do? Is it multi-threaded? When you want to send new firmware to the robot, do you have a way of telling it to stop its robot tasks and dedicate itself to the firmware transfer? If not, how is serial communication interleaved with the robot tasks? These are the types of questions that come up when you want to integrate Flasher capability into a "real" application, and which I will try to address in the next set of updates for FlasherX.
 
After some more instrumentation, I'm now pretty sure that the difference in after-boot delay between my 'short' and 'long' program is due to the longer time required for my robot program to go through all its setup operations. So now all I'm left with is the 1-in-3 to 1-in-5 failure to reboot, which may, in fact be an artifact of something in my hardware rather than FlashTxx.cpp/h. That theory makes more sense now because I'm pretty sure the new firmware ALWAYS gets read in and transferred properly to Flash memory. Ah, well, more work to be done ;-).
 
Robot program is single-threaded, so nothing else going on when updating firmware. Other than the occasional non-boot (or maybe I should say 'something hanging in setup'?), FlashTxxx.cpp/h is doing great. With my TeraTerm macro and 'board.txt' Visual Micro post-build magic, it all works pretty well; Press F5 and everything after that is automatic.
 
Status
Not open for further replies.
Back
Top