Backup existing firmware

Hi,
Apologies for asking what must have surely been documented somewhere, but I cannot for the life of me find it.

I recently dusted off an old spark core running device firmware … unknown.

I’d like to update the device OS, which seems simple enough, but one should always make backups before messing with such things… yet despite plenty of documentation on how to perform an update, I can find nothing on how to back up the current firmware.

The only reference I can find is this thread, which specifies the command:

dfu-util -d 1d50:607f -a 1 -s 0x00020000:0x00022000 -U backup_frfirmware.bin

I’m a bit wary of trusting an old, undocumented command from a community user with magic numbers i don’t understand - is that address range correct? How am I to know it will work?

Can anyone provide a reference for this?

Hi, and welcome to the community!

What happens if you visit build.particle.io and then:

select your device:
image

Star it to flash it and click on Device OS target:

The flash it?
image

You would need to have your firmware code handy so you can flash it along.

Cheers,
Gustavo.

Hi Gustavo, thanks for the reply.
I’m not sure how to get the ‘star’ - I’ve got no such icon.
The default device OS target, as shown in your screenshot is 1.4.4.

Screenshot_2021-12-02_00-36-43

I’m not sure what you mean by having the firmware code handy. I have the application source code, but not a compiled binary file. From reading the docs i’m under the impression that if i try to re-flash with the sourcecode again, it’ll result in it being recompiled against the latest deviceOS firmware, which will then be incompatible with the device, which will do a self-heal update. I’m trying to do a backup, before the update, so perhaps I missed the point there.

ok, no star would mean you have only one device, which I think is your case.

So, you can paste the application source code right there, on top of the default code (void setup()… that you see on the right panel).
You can then proceed with the save, compile, flash buttons you see on the left.

Let me know how it goes,
Gustavo,

Right… but as I mentioned in my previous message, I believe that will overwrite the firmware I’m trying to backup. :neutral_face:

oh, you mentioned you had the application source code, so what are you trying to back up exactly?
thanks

I’m trying to backup the deviceOS firmware.

oh, sorry, I do not know how to back it up.

May I ask why would you do that? Just curious about what you want to achieve here.
Gustavo.

Well, I have a working system, and if, for some unexpected reason, updating breaks it, I would like to be able to restore it to the way it was before. … that’s generally the idea of backups. :upside_down_face:

1 Like

As Gustavo already pointed out, you can select which device OS you will be building against.
So there should not be any need to backup the current binary from the device.

Also once you built your code you can download the resulting binary as well as the project sources - this would typically be the better way to backup the originals rather than flashing the binary to the device and then pulling it off the device again for backup.

Right. So in order to restore the current situation, which deviceOS version would I build against? (hint: check the screenshot in my opening post :wink: )

You can put your device in Listening Mode and run particle serial identify and particle serial inspect. This should give you some hints.

unfortunately it just returns

$ particle serial list
Found 2 devices connected via serial:
/dev/ttyACM1 -  - undefined
/dev/ttyACM0 -  - undefined
$ particle serial inspect
? Which device did you mean? /dev/ttyACM1 -  - undefined
Could not get inspect device: Serial timed out

Edit: apologies, didn’t spot that it had to be in listening mode:

$ particle serial inspect
? Which device did you mean? /dev/ttyACM1 -  - undefined
Could not get inspect device: Unexpected token : in JSON at position 3

Have you tried the other device?
If your computer can’t decide which device to use you can specify it via the --port switch

> particle help serial identify
Ask for and display device ID via serial
Usage: particle serial identify [options]

Global Options:
  -v, --verbose  Increases how much logging to display                                                           [count]
  -q, --quiet    Decreases how much logging to display                                                           [count]

Options:
  --port  Use this serial port instead of auto-detecting. Useful if there are more than 1 connected device      [string]

Unfortunately I haven’t got any Cores anymore, so I cannot test but maybe @rickkas7 can.
He’d also be able to assist with the binary download from the device and how to flash such a snapshot back.
The command you quoted above should still work.

  • 1d50:607f stands for the vendor and device IDs the USB controller should be applying the command to.
  • 0x00020000:0x00022000 stands for the address space to backup

Trying the other device gives time out. I can otherwise communicate with the core over ttyACM1, for example to set wifi credentials, which gives me the impression this is the right port.
Perhaps unrelated, but I do note that dfu identified the device ID as different to what the docs suggest, in case that provides a hint

Found DFU: [1d50:607f] ver=0200, devnum=63, cfg=1, intf=0, path="1-10", alt=1, name="@SPI Flash : SST25x/0x00000000/512*04Kg", serial="8D83217E5355"
Found DFU: [1d50:607f] ver=0200, devnum=63, cfg=1, intf=0, path="1-10", alt=0, name="@Internal Flash  /0x08000000/20*001Ka,108*001Kg", serial="8D83217E5355"

Supposedly a Core is expected to be [2b04:d000]....

0x00020000:0x00022000 stands for the address space to backup

I guess this is the only bit that concerns me, to know that this address space is correct... i'm not sure if it changes between versions, or devices (especially considering my device ID is not according to the docs...)

BTW, instead of particle serial identify you can also use a normal serial terminal program and send the letter i to the device in Listening Mode.

1d50:607f is correct for the Spark Core

The 2b04:.... IDs are Particle devices.
I’m not sure whether and if, from which device OS version on, the Core was pulled into the Particle flock.

1 Like

Ahah!

$ particle serial identify
? Which device did you mean? /dev/ttyACM1 -  - undefined

Your device id is 5*******************7
Your system firmware version is 0.5.1

It seems like that identified it! … so in theory i can rebuild against this OS version from build.particle.io

I see, thanks for clarifying on the device ID. I was going by this page - the docs are already pretty hard to find for this device!

I must admit especially given how “deprecated” this already is, having a local backup of a working firmware seems like a prudent idea all the same.

2 Likes

OK, so this thread seems to have died a death, yet the topic remains unanswered.
I still don’t know how to retrieve the device OS off my device.
Let’s try to motivate why that might be a good idea.

The last post established that I’m apparently running deviceOS v0.5.1. I go to download the deviceOS firmare binary files off github…

…but find that despite being listed for Core/Photon/P1/Electron (that’s 4 devices) that page has the following downloadable assets:

system-part1-0.5.1-electron.bin 120 KB
system-part1-0.5.1-p1.bin 245 KB
system-part1-0.5.1-photon.bin 245 KB
system-part2-0.5.1-electron.bin 118 KB
system-part2-0.5.1-p1.bin 184 KB
system-part2-0.5.1-photon.bin 

… that’s 3 devices. Guess which one’s missing. :upside_down_face:
Well why be so attached to version 0.5.1 anyway? Why not just update? OK, so I updated my device to firmware 1.4.4. After all, I can re-build and reflash for 0.5.1 if need be by selecting it from the drop-down menu shown in post #3.

So I upgrade. And my device stops working. Repeated reboots, SoS flashing code 11. The same user application code that worked just fine on 0.5.1 now dies with “invalid case” on the latest (final) release build for the Core device OS.

OK, fine. Back to v0.5.1.


Nope. Not allowed.

So, ok. I skip ahead a few versions and have now built against 0.5.4, and the code is working just fine… for now. But again, release 0.5.4 has no files for the Core!

So, either I sit here playing whack-a-mole, hoping to find a release with firmware files for the Core that also doesn’t crash, or I grab the firmware files straight device… i.e. the thread topic.

The Core does not have a separate device OS module. Its firmware is monolithic.
That means when you build your application against a particular device OS version the resulting binary will contain both Device OS and Application firmware.
That's also reflected by the fact that the Tinker binaries for the Core (downloadable at that same place) are much bigger than the binaries for the other three platforms.

Hence, build the binary and download it and back it up.

However, we can pass the question about how to extract and reapply the complete firmware from/to the device to @rickkas7 again.

That's an indication that the code may have some flaws that don't survive the stricter scrutiny of the more advanced/stable versions.

The Core does not have a separate device OS module. Its firmware is monolithic.
That means when you build your application against a particular device OS version the resulting binary will contain both Device OS and Application firmware.
...
Hence, build the binary and download it and back it up.

Oh! Well that's nice to know, I do have the built application firmware saved from the web IDE, so I guess that means i have the deviceOS backed up as well. I must have missed that in wherever it was documented (perhaps it could be mentioned on deviceOS release posts?), thankyou.

That’s an indication that the code may have some flaws that don’t survive the stricter scrutiny of the more advanced/stable versions.

Quite possibly - I didn't write it, and to be honest, if it works (with an old deviceOS), I don't have the time to spend debugging it.
That said the investigation I did do found that this behaviour was caused by 6 lines in the code:

        UDP udp;
        udp.begin(port);
        udp.beginPacket(broadcastIP, port);
        udp.write(contents, sizeof contents);
        udp.endPacket();
        udp.stop();

It seems as though UDP broadcasts had ongoing issues with the Core. I've modified the code with all the 'success' tips i've found - enclosing the code in an if(WiFi.ready()), reading any echoed packets back, adding delays, but with no change in behaviour. Notably it crashes on the first loop() invocation, so this code never even runs, leaving me rather puzzled. But as they say, if 0.5.4 ain't broke, don't fix it.