EmbeddedRelated.com
Forums

Firmware upgrade strategies

Started by pozz October 20, 2017
The first thing to think of is the firmware upgrade strategy of an 
electronic device with embedded software.

There are a multitude of bootloader out there for different 
microcontrollers, physical communication links and features.

I know it's difficult, but is there a somewhat standard firmware upgrade 
procedure/strategy/protocol?  Some open approach that is followed by 
different vendors/software.

In my case, I need a firmware upgrade strategy for AVR and SAM devices 
(from Atmel/Microchip) over UART half-duplex master/slave bus: the 
master should manage the firmware upgrade of all the devices.
The devices could be different, so the upgrade should be done for a 
device at a time, keeping the other device in an inactive state.

There are some issues:
- the protocol should use an address, so the bootloader should share
   the address with the application (in a shared memory zone?);
- the master should sends a signal to force entering the bootloader
   (I think a shared reset line is the simplest way to achieve this);
- all the devices on the bus should implement the same upgrade protocol
   and this could by a challenge if the MCUs are very different (from
   small 8-bit devices to big 32-bits devices);

Is there an open bootloader project that can be used in my application?


> - all the devices on the bus should implement the same upgrade protocol > and this could by a challenge if the MCUs are very different (from > small 8-bit devices to big 32-bits devices);
I'm using quite extensively an AVR109 type bootloader for any MCU. Used on "real" AVR parts but also on Cortex parts including some LPC devices, STM32 and Kinetis. The thing is: no matter which the real MCU is, the protocol is faking it to be an AVR part. But this is only to please the "avrdude" PC software, if you make your own software, you can do anything. AVR109 protocol is half duplex. Doesn't include an address, but you can modify it easily to add an address. Of course, an off-the-shelf avrdude program won't work anymore with it...
On 20/10/17 15:20, pozz wrote:
> The first thing to think of is the firmware upgrade strategy of an > electronic device with embedded software. > > There are a multitude of bootloader out there for different > microcontrollers, physical communication links and features. > > I know it's difficult, but is there a somewhat standard firmware upgrade > procedure/strategy/protocol? Some open approach that is followed by > different vendors/software. > > In my case, I need a firmware upgrade strategy for AVR and SAM devices > (from Atmel/Microchip) over UART half-duplex master/slave bus: the > master should manage the firmware upgrade of all the devices. > The devices could be different, so the upgrade should be done for a > device at a time, keeping the other device in an inactive state. > > There are some issues: > - the protocol should use an address, so the bootloader should share > the address with the application (in a shared memory zone?); > - the master should sends a signal to force entering the bootloader > (I think a shared reset line is the simplest way to achieve this); > - all the devices on the bus should implement the same upgrade protocol > and this could by a challenge if the MCUs are very different (from > small 8-bit devices to big 32-bits devices); > > Is there an open bootloader project that can be used in my application? >
I rarely find that ready-made bootloaders are useful in the field at the best of times. It is going to be even harder to find something that supports two completely different architectures. A key aspect of upgrading in the field is that it needs to play well with the normal protocols you are using. If your cards are normally communicated with Modbus and suddenly your master wants to use a third-party protocol to upgrade the firmware on one of the slaves, you can expect chaos. The correct way to handle it in this case is to have a firmware protocol that is embedded in Modbus, and to use normal Modbus registers to transfer things like program version numbers, jump to bootloader requests, etc. So start by looking at the communication you normally have here, and see how upgrades can fit in with that. And consider if the firmware can be transferred and saved while running in normal mode, rather than bootmode. That takes more flash space, and requires flexible erase and program capabilities on the microcontrollers (or an external SPI flash), but will minimise down-time and keep your bootloader code as simple as possible because it does not have to communicate.
Il 23/10/2017 09:00, David Brown ha scritto:
> On 20/10/17 15:20, pozz wrote: >> The first thing to think of is the firmware upgrade strategy of an >> electronic device with embedded software. >> >> There are a multitude of bootloader out there for different >> microcontrollers, physical communication links and features. >> >> I know it's difficult, but is there a somewhat standard firmware upgrade >> procedure/strategy/protocol? Some open approach that is followed by >> different vendors/software. >> >> In my case, I need a firmware upgrade strategy for AVR and SAM devices >> (from Atmel/Microchip) over UART half-duplex master/slave bus: the >> master should manage the firmware upgrade of all the devices. >> The devices could be different, so the upgrade should be done for a >> device at a time, keeping the other device in an inactive state. >> >> There are some issues: >> - the protocol should use an address, so the bootloader should share >> the address with the application (in a shared memory zone?); >> - the master should sends a signal to force entering the bootloader >> (I think a shared reset line is the simplest way to achieve this); >> - all the devices on the bus should implement the same upgrade protocol >> and this could by a challenge if the MCUs are very different (from >> small 8-bit devices to big 32-bits devices); >> >> Is there an open bootloader project that can be used in my application? >> > > I rarely find that ready-made bootloaders are useful in the field at the > best of times. It is going to be even harder to find something that > supports two completely different architectures. > > A key aspect of upgrading in the field is that it needs to play well > with the normal protocols you are using. If your cards are normally > communicated with Modbus and suddenly your master wants to use a > third-party protocol to upgrade the firmware on one of the slaves, you > can expect chaos. The correct way to handle it in this case is to have > a firmware protocol that is embedded in Modbus, and to use normal Modbus > registers to transfer things like program version numbers, jump to > bootloader requests, etc.
Yes, this is possible. However if you base your firmware upgrade on the main application, a critical bug could prevent the upgrade process itself, because you could have a device that is not able to enter bootloader anymore by a command on the bus. I think this is why you need a reliable hardware method to enter bootloader. The problems with mixing different protocols (bootloader and normal communication) can be avoided by stopping all the devices on the bus during upgrade. Here the main requirement is to upgrade the firmware from a remote site, so without pressing buttons or similar manual/local operations. I have an embedded Linux box that features remote connection (Ethernet) and local connection (bus). The Linux box should manage the firmware upgrade of the devices on the bus. I'm thinking to have a shared reset line on the bus to force a hard reset of all the devices that enter the bootloader at the same time. Of course, only one device enters firmware upgrade (because it is addressed by the master in a period of time) while the others stay in bootloader (because not addressed, but they see another device is addressed so avoid launching main application). When the upgrade finishes, another pulse on shared reset line launch the main application on all the devices.
> So start by looking at the communication you normally have here, and see > how upgrades can fit in with that. > > And consider if the firmware can be transferred and saved while running > in normal mode, rather than bootmode. That takes more flash space, and > requires flexible erase and program capabilities on the microcontrollers > (or an external SPI flash), but will minimise down-time and keep your > bootloader code as simple as possible because it does not have to > communicate.
This is a good point. However, as I said before, this could be implemented as a "low-reliable" upgrade method that uses the current firmware to download and save the new firmware. However you always need another method (the hard reset to enter bootloader).
On 23/10/17 10:02, pozz wrote:
> Il 23/10/2017 09:00, David Brown ha scritto: >> On 20/10/17 15:20, pozz wrote: >>> The first thing to think of is the firmware upgrade strategy of an >>> electronic device with embedded software. >>> >>> There are a multitude of bootloader out there for different >>> microcontrollers, physical communication links and features. >>> >>> I know it's difficult, but is there a somewhat standard firmware upgrade >>> procedure/strategy/protocol? Some open approach that is followed by >>> different vendors/software. >>> >>> In my case, I need a firmware upgrade strategy for AVR and SAM devices >>> (from Atmel/Microchip) over UART half-duplex master/slave bus: the >>> master should manage the firmware upgrade of all the devices. >>> The devices could be different, so the upgrade should be done for a >>> device at a time, keeping the other device in an inactive state. >>> >>> There are some issues: >>> - the protocol should use an address, so the bootloader should share >>> the address with the application (in a shared memory zone?); >>> - the master should sends a signal to force entering the bootloader >>> (I think a shared reset line is the simplest way to achieve this); >>> - all the devices on the bus should implement the same upgrade protocol >>> and this could by a challenge if the MCUs are very different (from >>> small 8-bit devices to big 32-bits devices); >>> >>> Is there an open bootloader project that can be used in my application? >>> >> >> I rarely find that ready-made bootloaders are useful in the field at the >> best of times. It is going to be even harder to find something that >> supports two completely different architectures. >> >> A key aspect of upgrading in the field is that it needs to play well >> with the normal protocols you are using. If your cards are normally >> communicated with Modbus and suddenly your master wants to use a >> third-party protocol to upgrade the firmware on one of the slaves, you >> can expect chaos. The correct way to handle it in this case is to have >> a firmware protocol that is embedded in Modbus, and to use normal Modbus >> registers to transfer things like program version numbers, jump to >> bootloader requests, etc. > > Yes, this is possible. However if you base your firmware upgrade on the > main application, a critical bug could prevent the upgrade process > itself, because you could have a device that is not able to enter > bootloader anymore by a command on the bus. > I think this is why you need a reliable hardware method to enter > bootloader.
There is no fixed answer here - it depends on a variety of things, such as the complication of the protocol (maybe it is too complicated for a bootloader), the consequences of failures (are you losing lives or millions of dollars, or does someone just need to turn their automatic light switch on and off?), the level of testing (a critical bug in the main program should never be released!), etc.
> > The problems with mixing different protocols (bootloader and normal > communication) can be avoided by stopping all the devices on the bus > during upgrade.
Yes, that is a possibility - at least for some systems. What if the critical bug in the main program means that some cards don't go into bootloader mode?
> > Here the main requirement is to upgrade the firmware from a remote site, > so without pressing buttons or similar manual/local operations. I have > an embedded Linux box that features remote connection (Ethernet) and > local connection (bus). The Linux box should manage the firmware > upgrade of the devices on the bus. > > I'm thinking to have a shared reset line on the bus to force a hard > reset of all the devices that enter the bootloader at the same time. Of > course, only one device enters firmware upgrade (because it is addressed > by the master in a period of time) while the others stay in bootloader > (because not addressed, but they see another device is addressed so > avoid launching main application). > > When the upgrade finishes, another pulse on shared reset line launch the > main application on all the devices.
Drawing out a reset line directly onto your bus sounds risky. As I say, there is no one strategy that fits every use-case - but I'd be aiming for something that can run alongside normal communication, rather than instead of it. Whether that means getting the new firmware while in main program mode, or that the bootloader has a limited version of the normal communication protocol is a design choice to make.
> > >> So start by looking at the communication you normally have here, and see >> how upgrades can fit in with that. >> >> And consider if the firmware can be transferred and saved while running >> in normal mode, rather than bootmode. That takes more flash space, and >> requires flexible erase and program capabilities on the microcontrollers >> (or an external SPI flash), but will minimise down-time and keep your >> bootloader code as simple as possible because it does not have to >> communicate. > > This is a good point. However, as I said before, this could be > implemented as a "low-reliable" upgrade method that uses the current > firmware to download and save the new firmware. However you always need > another method (the hard reset to enter bootloader). >
No, you most certainly do /not/ always need such a method. You /might/ want it - but it many cases it is simpler, cheaper, and more reliable to say that if the unit fails to upgrade via the normal upgrade method, then the unit is broken and gets thrown away or sent back to the shop for repairs. ("Repair" possibly meaning "firmware upgrade via JTAG".)