Cloud firmware update without OS change

I've downloaded the latest Particle OS source code and I've made a modification that eliminates a problem I have with the present Bluetooth stack (see https://community.particle.io/t/particle-ble-stack-fragmentation-data-loss/68756/12?u=tnilsen )

Using DFU mode over a USB cable I burn this into my Boron and all is well.

However, if I need to burn new firmware (not OS), and I use Visual Studio Code to burn via the Cloud then the OS is automatically "downgraded" to Particle's official release.

Is there a way I can burn new application code via the Cloud and not have this happen?

To make your scenario work, you need to note the version you based your custom version of Device OS from. You then must always target that version number when you flash user firmware.

When using local flash, make sure you use Flash application (local) option, not the version that flashes Device OS, when using a computer that does not have the modified version of Device OS, otherwise it will switch to the official version. The target version must also match.

When using cloud flash, as long as the version numbers match, Device OS will not be updated.

Device OS is never downgraded OTA, but you have to make sure you never target a newer version of Device OS because that will replace your modified version with the upgraded production version.

2 Likes

Rick,

I just tried it:

Using VSCode I flashed my Boron with my modified version of 6.3.0 (deviceOS@source). I burned OS and code locally via a USB cable. (I verified that the OS version number showed up as 6.3.0 on the Console web-page).

Next, I changed the the Active Device OS Version to deviceOS@6.3.0. I made a small change to my application code, and still using VSCode I flashed just the application, but now via the Cloud.

This changed my OS back to the official 6.3.0 pre-release :frowning:

Any pointers? (Does it use some sort of checksum to determine that the OS is not valid perhaps and needs updating?)

Did it flash Device OS by USB or OTA? It's a little hard to tell, because there will be a short blinking magenta phase in both cases if it flashes the bootloader, but if there is a lengthy breathing magenta or blinking magenta phase, that would indicate upgrade OTA.

There shouldn't be a checksum, but Workbench may be detecting that you are leaving DeviceOS@source mode and forcing a flash of Device OS by USB. That could be present to take into account switching from debug mode to regular mode, where you do want to re-flash Device OS even for the same version.

Does this happen if you cloud flash from Workbench after Particle: Configure project for device is switched from DeviceOS@source to the same version number?

So I can tell that when I’m flashing via the Cloud that it’s updating the OS by looking at the LED flashing magenta and does so for a 10-15 seconds or more (ie it’s lengthy).

Furthermore, it’s clear the OS has been updated to the real 6.3.0 version since the problem my OS build fixes reappears.

Here’s a summary:

  1. I flash my modified OS via VSCode local USB (DFU).
  2. I verify my OS fix is good by watching Boron operating (I get a published message saying BT packets are complete).
  3. I change the OS version on VSCode to Particle’s 6.3.0 pre-release
  4. I make a small non important change to my application code and then using VSCode I flash via Cloud.

This last operation sadly flashes Particle OS pre-release 6.3.0 overwriting my version (of 6.3.0).

Anything I can try? It might be a few days from now. I’m away for a few days from tomorrow.

When you made your modifications from the Device OS source you cloned from Github, did you do so from develop, or a specific tag or branch? Which tag?

Also, after doing the flash with the custom Device OS, can you do a particle serial inspect or use the web device inspect tool?

I really can’t remember which branch, other than it shows up as version 6.3.0 when flashed.
When I get back from my trip I’ll delete the clone I have now. I’ll clone a fully released version like 6.2.1 (if I remember correctly) and redo my changes and try again.

Thanks for your help, Rick. I’ll let you know how I get on.

This is the procedure I followed for my custom OS.

I don’t think me redoing that will change anything since I didn’t specify any particular build and it did give the latest pre release 6.3.0

I’ll try your latest suggestion and report back.

As requested (particle serial inspect). This is with the Boron running my custom OS version.

Device: xxxxx
Platform: 13 - Boron

Modules
  Bootloader module #0 - version 3100
  Size: 48.586 kB / MaxSize: 49.152 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

  System part module #1 - version 6302
  Size: 567.26 kB / MaxSize: 573.44 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      Bootloader module #0 - version 3100
      Radio stack module module #0 - version 202

  User part module #2 - version 6
  Size: 73.89 kB / MaxSize: 262.144 kB
    UUID: xxxx
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System part module #1 - version 6302

  Radio stack module module #0 - version 202
  Size: 0 kB / MaxSize: 155.648 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

I did a Cloud flash via VSCode and after it updated both my code and OS I ran particle serial inspect on that 6.3.0 version. I noticed the only difference is User part module #2 - the sizes and the UUID is different. I erased that UUID from my inspect post. Here it is (for my version OS)

UUID: 4d9bea8e164d9b2217707e3440ce22491cbdb42c9efb3e7bd9919c9435aecda0

For completeness here is the serial inspect output for the official Particle 6.3.0 version:

Device: xxxxx
Platform: 13 - Boron

Modules
  Bootloader module #0 - version 3100
  Size: 48.586 kB / MaxSize: 49.152 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

  System part module #1 - version 6302
  Size: 567.26 kB / MaxSize: 573.44 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      Bootloader module #0 - version 3100
      Radio stack module module #0 - version 202

  User part module #2 - version 6
  Size: 74.414 kB / MaxSize: 262.144 kB
    UUID: dd8906813de1bd6b9c83ebbde8b4100c995e55ad6e6f056236e536b47b6e46ff
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System part module #1 - version 6302

  Radio stack module module #0 - version 202
  Size: 0 kB / MaxSize: 155.648 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

I went ahead and re-did the git clone of the OS, made my modifications and retried flashing just code OTA. It still changes the OS.

Any ideas? It clearly doesn't like the "corrupted" OS and overwrites it.

  1. I deleted my custom OS version
  2. I did the git clone procedure as per above screen shot
  3. I made my OS changes and flashed application and OS locally
  4. I confirmed my OS change was operating. OS version now is 6.3.3
  5. I changed VSCode to use Particle pre-release OS version 6.3.3. It installed it, I compiled all, and then flashed application code OTA (i.e. via the cloud)
  6. After it finished I verified that my OS changes had been overwritten.

Here is the serial inspect of my OS version based on 6.3.3:

Device: xxxx
Platform: 13 - Boron

Modules
  Bootloader module #0 - version 3100
  Size: 48.586 kB / MaxSize: 49.152 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

  System part module #1 - version 6304
  Size: 571.3 kB / MaxSize: 573.44 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      Bootloader module #0 - version 3100
      Radio stack module module #0 - version 202

  User part module #2 - version 6
  Size: 74.018 kB / MaxSize: 262.144 kB
    UUID: 52bff5487e0ecaff59651e1219d62b499e57e256f251ef0023f116a7c137ae78
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System part module #1 - version 6304

  Radio stack module module #0 - version 202
  Size: 0 kB / MaxSize: 155.648 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

Here is the serial inspect after an OTA flash of the application code:

Device: xxxx
Platform: 13 - Boron

Modules
  Bootloader module #0 - version 3100
  Size: 48.586 kB / MaxSize: 49.152 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

  System part module #1 - version 6304
  Size: 571.3 kB / MaxSize: 573.44 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      Bootloader module #0 - version 3100
      Radio stack module module #0 - version 202

  User part module #2 - version 6
  Size: 74.542 kB / MaxSize: 262.144 kB
    UUID: c0c71f1294f4f75951c86c34215a71fdb40c9a2642c18339ff474c00a2f4eb76
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System part module #1 - version 6304

  Radio stack module module #0 - version 202
  Size: 0 kB / MaxSize: 155.648 kB
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS

I just realized that one of your modifications is to spark_wiring_ble.cpp. Sorry, I forgot to check that earlier. Because this file is compiled into your user firmware binary, the only way you'll be able to build is to build locally with your changed Device OS files.

My OS change is to two macros in the file

ble_hal_impl.h

within the hal/src/rtl872x and hal/src/nRF52840 directories.

So I guess you're saying that I can only flash my code locally then. Any means of circumventing that?

If those are your only changes, in the hal directory, then it should work. It's not clear to me why it's upgrading to the production version of Device OS because it shouldn't be doing that.

You shouldn't need to build Device OS after switching to 6.3.3. You should only need to Particle: Compile application (local).

What happens if you switch to production 6.3.3 and use Particle: Cloud Flash and do not build locally?

Just tried this:

  1. I burn locally OS and App (my OS version)
  2. I change OS to pre-release 6.3.3 in VSCode
  3. I immediately use Particle: Cloud Flash

OS reverts to Particle's.

I'm pretty sure it should not do that; I'll try to reproduce this week.

Rick, thanks again for looking into yet another one of my issues.
(Maybe it's just OS image part 2 where I've modified code that does this.)

I tried some other things:

  1. Flash custom OS and App locally (6.3.3 based)
  2. Verify OS fix works
  3. Select pre-release 6.3.0 and do a Cloud flash of appcode
  4. Os remains at 6.3.3, but OS fix is gone.

and

  1. Flash custom OS and App locally (6.3.3 based)
  2. Verify OS fix works
  3. Select release 4.2.0 and do a Cloud flash of appcode
  4. Os remains at 6.3.3, but OS fix is gone.

hmmm....

Theory: Maybe because Particle IoT devices are initially claimed/configured via BLE (which is the OS part I've modified), the flashing process detects a "corrupted" BLE stack and overwrites it to ensure the ability to claim etc.