deviceOS@4.0.0 - Cannot flash new firmware without device restore

Like many, I am excited about deviceOS@4.0.0. After being on the previous LTS release (2.3.0), I was excited to avail myself of all the improvements I have been watching over the past 18 months accumulate on the development stream.

I decided to take the plunge but have had an issue.

If I update a device using the “cloud flash” or via DFU, from deviceOS@2.3.0 to deviceOS@4.0.0, the deviceOS will update but not the firmware.

Here is what I see when I attempt to flash new firmware at deviceOS@4.0.0 onto a device.

The device will go into DFU mode, connect and go through a few cycles of blue/red updating. This is the last line of the Particle identify command which shows the device is now on deviceOS@4.0.0 but, the firmware has not been updated despite giving every indication of doing so:

Screen Shot 2022-09-07 at 7.58.30 PM

This is the result when I flash the example 04-persistent.cpp from StorageHelperRK:

The only way to flash new firmware seems to be to do a device restore using the Chrome plugin. Once complete, I can then flash new firmware using either the DFU mode or the cloud flash. If this is the case, I am wondering how to update my deployed devices to the new LTS version.



Cloud flash OTA should work, but flashing from Workbench by DFU (Flash application only (local) or Flash application and Device OS (local)) will exhibit that behavior if your application is less than 128K bytes.

The problem is that Device OS 3.1.0 added support for 256K user firmware binaries. Older versions of Device OS only supported 128K. This was done by moving the start 128K earlier in flash, so the end of a 256K binary is in the same place as a 128K binary used to be.

When you target 3.1.0 or later, a 256K binary is always created, and it’s flashed to the 256K binary slot. However, two special things occur:

In a normal firmware OTA update, the user firmware binary is flashed first, then the cloud updates any dependencies.

However, when you cross the 256K binary boundary (3.1.0) on Gen 3 devices, the cloud intercepts the user firmware flash and flashes the bootloader first. Otherwise, the pre 3.1.0 bootloader does not know how to load from the new 256K binary slot. After the bootloader is flashed, the user binary is flashed, then the other dependencies are updated.

Problem 1 with Workbench DFU is that this doesn’t happen, and by default Workbench doesn’t flash the bootloader. It’s normally updated OTA, however you can run into a situation if your user binary is greater than 128K where the bootloader on the device does not know how to load a 256K binary, and there is no 128K binary, so the device can’t boot into safe mode to get the bootloader OTA because there is no user firmware binary. The device goes into DFU mode instead.

Problem 2 is when your new user binary is less than 128K. When you DFU a 256K binary, you’re in a situation where you have an old 128K binary in the original slot, and a new 256K binary in the 256K binary slot. Though it initially seems counter-intuitive, the 128K binary, the old one, has precedence. This has to be done, otherwise flashing Tinker with DFU from the CLI or from the mobile apps would not actually replace the 256K binary.

If you Flash application and Device OS by DFU this is how you end up with 4.0.0 and the old binary. Flashing Device OS 4.0.0 from Workbench upgraded Device OS, but did not update the bootloader and SoftDevice. It did flash the new binary, but because there is still the old 128K 2.x binary, that’s the one that’s run because it was not overwritten.

Device Restore USB, Device Restore JTAG, and Hex Generator all invalidate the 128K binary slot when flashing a 256K binary so this does not happen.

It would require some digging to figure out exactly why your OTA update didn’t work, but it should work.


Hi @chipmc ! I’ve tried to reproduce this with Workbench, starting a Boron on 2.3.0 and using Cloud Flash to update to 4.0.0, and everything updates as expected. Would you please clarify if Cloud Flash is also failing for you, or is it just DFU (which is expected as Rick pointed out)?

I have made sure to add the following block of text to the Device OS Github release notes for 4.0.0 and 5.0.1

Gen 3 256KB application binary support

Device OS v3.1.x and further releases bring support for 256KB application binaries to all Gen 3 platforms (at that time: Argon, Boron, B SoM, B5 SoM, Tracker). A few important aspects of this change:

  1. Compatibility with 128KB applications built with < Device OS 3.1 versions is maintained. Devices can still run them even if other parts have been upgraded to Device OS 3.1+.
  2. Upgrade process OTA (including product-based upgrades) is transparent.
  3. When upgrading locally (using DFU or Serial), make sure to update the bootloader first, as it has some logic managing compatibility between 128KB and 256KB application types. See this page on steps how to perform the update.
  4. If using standalone Particle CLI installation, make sure it’s updated to >= 2.12.0 version, which includes support for 256KB applications.

@BDub and @rickkas7 ,

Sorry, in figuring out what was happening, I lumped in cloud flash with DFU. I just took a fresh device at deviceOS@2.3.0 and was able to cloud flash it to deviceOS@4.0.0 and updated firmware. So, it seems this issue is for updating locally. Thank you for explaining this issue and providing steps to resolve it.

Thank you, Chip

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.