Flashing new firmware to production devices

So…we’re testing application software in the development environment, but expect to move devices into “production” in the not-too-distant future. Can someone please point to to documentation that explains how we would update the application firmware on several devices that will be Electrons that are deep sleeping most of the time and only waking up a few times a day to push data to a cloud service and then going back into deep sleep? I’m assuming this functionality is already a part of the Particle platform.

Is there a means to do this while still in development?

Thanks, in advance.

It’s part of the console :smile:
A DIY solution would be to have some server/computer thing listening to ‘online’ SSEs to trigger an update.

@Moors7, Thanks for the confirmation. I simply didn’t know if things were setup to handle an application in which the device is in deep sleep most of the time and briefly wakes up every 6 hours to upload collected information.

Have you tried the firmware update via using the Particle Produce Console with your sleeping devices that only wake up for a brief few seconds?

I’m just wondering if a few seconds are enough to trigger the firmware update or not.

I have not. It wasn’t until just a bit earlier that I was certain this feature is part of the Production environment. I need to also understand if there are any other “issues” moving devices to the production console. If not, I can likely do that within the next week or so.

Our devices are in semi-automatic mode with the cellular radio turned off and in deep sleep. They wake up once an hour to take readings, store them in Flash and then go back to deep sleep. Every six hours, they wake up, turn on the cellular radio, link up to the Particle cloud, request configuration information and then push data to a cloud service and then go back into deep sleep. So…they’ll be “online” (i.e. connected to the Particle cloud) for about 10 seconds. I hope that’s sufficient time to receive/start any available firmware update…

I’m not sure how long it has to be exactly to get an actual update deliveted, but AFAIK you need to be connected about 10sec before a System.updatesPending() would report true, and if so you should allow for a minute or so for the download, reflash and reboot.

@ScruffR, having the device wait for about 10 seconds to check System.updatesPending() would not be problem. However, I’m unclear as to how the application can know if an update is being downloaded and should not issue a command to go back to sleep. The documentation for System.updatesPending() is rather sparse :wink: to say the least.

During cloud "enumeration" which happens during the first few seconds after coming online the presence of a pending update will be signalled to the device and if you're interested in it you'd check System.updatesPending() and if it returns true, add some extra waiting time for the download to start, finish and flash the update.
If you won't wait the download might start but not finish successfully.

Some extra info here
https://docs.particle.io/reference/firmware/electron/#system-events

1 Like

So…would it make sense to merely sit in a loop (with/without delays) until System.updatesPending() no longer returns TRUE? By that I mean, if it did return TRUE after 10 seconds, then wait until it no longer returns TRUE? The assumption being that it has received the desired updated.

Is it safe to assume the device will automatically restart after the download is completed?

I’d do some thing like that

  uint32_t ms = millis();

  // do whatever needs doing for normal ops

  // allow at least 10sec for cloud enumeration to complete
  while(millis()-ms < 10000) Particle.process();
  // now we should be able to learn if there is an update waiting
  if (System.updatesPending())
  { // if update is pending hang around for it a minute - will reboot after update
    ms = millis();
    while(millis()-ms < 60000) Particle.process();
    // if hasn't rebooted before one minute was up go to sleep and try next time again
  }
  System.sleep(SLEEP_MODE_DEEP, sleepTime);
2 Likes

You guys are amazing! Thanks for the concept complete with code!

2 Likes

@ctmorrison, since I’ve not actually tested this code, did this help in any way?

Haven’t had a chance to test yet. There’s another person who has done the majority of the development and I’m pretty much assisting/advising/etc. I hate to tweak his code without him being there. He’s away for a few days, so we’ll be giving it a try next week and I’ll let you know.

This approach really is something that should be published in the documentation, as I “assume” (hate to do that) there are many others with battery powered “sleepy” applications having similar needs.

I agree, hence I’ve opened an issue on GitHub to have Particle think about some more convenient ways to get the task accomplished

1 Like

I found it takes 9 seconds to wait for updates in my own code. So, I wait for 12 just to be sure before I power down, in a Particle.process() loop like ScruffR suggested.

I also do something else, which is to turn off updates so they don’t automatically reset my system while I am doing other things (System.disableUpdates()). Then, when my device is ready to go to sleep, I do a check for updates (System.updatesPending()) and if true, turn back on the updates (System.enableUpdates()) and do an infinite Particle.process() loop, since it will reset from there. I don’t really know if this works, since it’s one of those weird cases that are hard to test, but unless someone says otherwise, I’ve left the code as such.

Just my 2 cents.

2 Likes

Nice tip! We’ll craft it into the application in that fashion.