common bootloader?
#1
I've just ordered my pinetime devkit so it'll be a while before it arrives, but I was thinking the first thing we should probably do in common before we all go off to do our own things is develop a bootloader that will work in common with all our projects. It's all very well writing the flash via SWD with the devkits, but in the production version presumably we're going to need another way of writing the flash that doesn't involve opening the case.

The bootloader should be able to:
  • Drive the display, bluetooth and SPI flash.
  • Present a nice liveness/progress bar indicator during the boot process.
  • Delay on boot, check if the button is pressed.
  • If the button is pressed, enter "rescue" mode that will offer a serial console over bluetooth with xmodem (or similar) support to download a (compressed?) firmware image.
  • Write any firmware image received to SPI flash, verify checksums.
  • Check on boot if a new firmware image is available in external flash, if so write it to internal (memory mapped) flash.
  • Protect the internal flash.
  • Set the watchdog timer.
  • Branch to whatever address we agree the kernel entry point should live at.


Is anyone working on anything like this? If not, I guess that's my first job when I get hold of my devkit.
  Reply
#2
I'm porting Mynewt OS to PineTime but I haven't done a proper bootloader yet. Would the new bootloader be based on MCUboot, which supports Zephyr, RIOT and Mynewt? https://juullabs-oss.github.io/mcuboot/
  Reply
#3
(12-05-2019, 04:43 AM)lupyuen Wrote: I'm porting Mynewt OS to PineTime but I haven't done a proper bootloader yet. Would the new bootloader be based on MCUboot, which supports Zephyr, RIOT and Mynewt? https://juullabs-oss.github.io/mcuboot/

We could use that code as part of it, sure. I think the bulk of the effort is going to be writing a very minimal bluetooth stack though, just enough of the link layer to reply to scans and advertise a serial port.
  Reply
#4
(12-05-2019, 05:24 AM)Jeeves Wrote:
(12-05-2019, 04:43 AM)lupyuen Wrote: I'm porting Mynewt OS to PineTime but I haven't done a proper bootloader yet. Would the new bootloader be based on MCUboot, which supports Zephyr, RIOT and Mynewt? https://juullabs-oss.github.io/mcuboot/

We could use that code as part of it, sure. I think the bulk of the effort is going to be writing a very minimal bluetooth stack though, just enough of the link layer to reply to scans and advertise a serial port.

Hmmm the Bluetooth part might be challenging... My Mynewt OS port uses the open-source NimBLE stack (also available for Zephyr OS): https://github.com/apache/mynewt-nimble

Other ports may choose to use the proprietary Nordic SoftDevice stack. I wrote about NimBLE vs SoftDevice here: https://medium.com/swlh/sneak-peek-of-pi...38e99ec20d
  Reply
#5
(12-05-2019, 06:07 AM)lupyuen Wrote: Hmmm the Bluetooth part might be challenging... My Mynewt OS port uses the open-source NimBLE stack (also available for Zephyr OS): https://github.com/apache/mynewt-nimble

Other ports may choose to use the proprietary Nordic SoftDevice stack. I wrote about NimBLE vs SoftDevice here: https://medium.com/swlh/sneak-peek-of-pi...38e99ec20d

Do you have any data about the object size the NimBLE stack compiles down to? Ideally, the bootloader would probably be less than 4KB so it fits in just the first page of the internal flash. I'd be only too delighted to use a pre-written bluetooth stack if it's small enough.
  Reply
#6
The nRF5's SDK has a bootloader with a few ways to enter it (button on startup, set a bit and force a restart over a normal BLE). Almost every commercial sports tech sensor is using the Nordic Reference or a modified derivative. The down side is that the reference is really setup for "no backsies", as in firmware is given a version, and you can't put on an older one. There was an open bootloader in 15.3.0 (haven't checked 16 yet) but it's nrF52840 USB and not BLE.
  Reply
#7
Quote:
  • Delay on boot, check if the button is pressed.

  • If the button is pressed, enter "rescue" mode that will offer a serial console over bluetooth with xmodem (or similar) support to download a (compressed?) firmware image.
    ...
  • Check on boot if a new firmware image is available in external flash, if so write it to internal (memory mapped) flash.
    ...
  • Set the watchdog timer.

I'm not sure if I'm following here. To save on battery you will want to enter sleep as much as you can, where RAM contents is lost. Off course you'll want a watchdog too. Note that a watchdog keeps going when you've entered sleep. So you must wakeup your device through some kind of RTC alarm just for "kicking" the WD.
If you check for button press within your bootloader I'd guess you're doing that each time to user wakes up the device from sleep. To avoid checking for firmware update candidates immediately you may want to check that the btn is pressed for x seconds, for example keeping it pressed for 5s triggers bootloader, else launch application firmware. So the bootloader will delay any action until user has released the button, or 5s have passed. That's a pitty because you could do quite a bit during that time... Furthermore, if one would were hand gloves that would accidentally push the button for 5s, you're into the bootloader menu waiting for some BL action to happen.
I'd only trigger the fwupdate within the bootloader after powerup/(soft-)reset.
  Reply
#8
I'm currently working on DFU and OTA. 

I've done some tests with wasp-bootloader : https://forum.pine64.org/showthread.php?tid=9134
It's working nearly out of the box but only if the firmware you want to flash is based on the Nordic Softdevice BLE stack (the same softdevice, the same version).
This bootloader embeds the BLE stack whihch is shared with the application firmware. This might be a good thing, but as I said, all the firmwares you'll want to flash will have to be built around the same ble stack.
Another downside is that Nordic Softdevices are not open-source, and there are already some firmware that do not use the Softdevices. For example, Nimble is open-source and supports the NRF82832.

For now, I'm doing some researches on another options : The application is responsible for the download of the new firmware image and for storing it in the memory. Then, the bootloader (which does not embed the ble stack) can detect that a new image is available, swap it with the current one and provide a way to rollback the update if it fails.
The advantage is that the firmware is free to use the BLE stack of its choice, but of course, it is still possible to 'brick' the watch if you flash a firmware that does not allow to OTA another firmware...

For now, I'm just trying to see how it works. I hope it'll help us to have a better overview of the possibilities we have to implement OTA updates Smile

Quote:Do you have any data about the object size the NimBLE stack compiles down to? Ideally, the bootloader would probably be less than 4KB so it fits in just the first page of the internal flash. I'd be only too delighted to use a pre-written bluetooth stack if it's small enough.
The NRF Softdevice (S132 in SDK 15.3) needs 155648 bytes of Flash and 22456 bytes of RAM. I do not have the exact numbers, but it should be quite similar for Nimble. 
If both the bootloader and the application integrate a BLE stack, ~300 KB would be used in RAM, more than half of the available flash memory...
Working on Pinetime with FreeRTOS (C/C++) : https://github.com/JF002/Pinetime

Mastodon : https://mastodon.codingfield.com/@JF
Twitter : https://twitter.com/codingfield
Matrix : @JF002atrix.org
  Reply
#9
Hi PineTime Firmware Developers: I'm now writing a guide for implementing firmware upgrade over Bluetooth in your PineTime firmware. This will also include a common PineTime bootloader: MCUBoot

This is still work in progress. Hopefully we'll have a better experience for PineTime Owners when installing, upgrading and trying out various firmware

https://lupyuen.github.io/pinetime-rust-...ticles/dfu

Sent from my Pixel 4 XL using Tapatalk
  Reply
#10
Quote:For now, I'm doing some researches on another options : The application is responsible for the download of the new firmware image and for storing it in the memory. Then, the bootloader (which does not embed the ble stack) can detect that a new image is available, swap it with the current one and provide a way to rollback the update if it fails.

The advantage is that the firmware is free to use the BLE stack of its choice, but of course, it is still possible to 'brick' the watch if you flash a firmware that does not allow to OTA another firmware...

Hi @JF002 

At work we use mbed-os. ARM has an open source bootloader that does exactly that what you described.
The app can pull in a new firmware image by any means (cellular, bluetooth, CAN, ...) and write it to internal flash or some kind of "external" storage such as SPI flash, etc.
The bootloader is rather basic in that it doesn't rely on any kind data carrier, but only on storage.
This way the bootloader is compatible with a wide range of apps, only minimal configuration is needed plus maybe some tweaking as you would like to have it. It also helps keeping bugs away from the bootloader.
The bootloader does have a few tricks to make sure everything goes wrong. During fwupdate, it always checks the active application for legibility. Next it runs over all fwupdate candidates and checks for the one with highest timestamp. If the timestamp is higher than that of the active application, the candidate is selected. Note that the timestamp is something you have completely control over when you "download" the fwupdate candidate into your device. It's not the application version, so it actually allows to flash older firmware as long as you download it with a newer timestamp. Before the candidate is actually being flashed, t bootloader will perform SHA check on the full firmware candidate data. This takes a few seconds depending on the size of the application.

My experience so far is that we've used it for hundreds of OTA updates without a problem. The binary size is about 30k, that leaves enough for complex applications. However I know that not everyone is keen on ARM's mbed-os due to "vendor lock-in".
Here is the repo: https://github.com/ARMmbed/mbed-bootloader
  Reply


Possibly Related Threads...
Thread Author Replies Views Last Post
  MCUBoot Bootloader for PineTime lupyuen 2 285 05-18-2020, 04:23 PM
Last Post: lupyuen
  wasp-bootloader: a robust SoftDevice bootloader for PineTime danielt 3 508 04-14-2020, 05:31 AM
Last Post: danielt

Forum Jump:


Users browsing this thread: 1 Guest(s)