Hi,
I'd like to implement a firmware update procedure that would work for a BLE Peripheral running 2541 with 256KB Flash.
Since I didn't find any readily available solution, here is how I plan to go about and make it happen:
- Define a BLE service that will transfer firmware images from Central to the Peripheral via lots of GATT Characteristic writes (20 bytes each). While collecting all these buffers, data will be written to a few pages in the Flash memory, where they will be stored. Data will possibly be transmitted in some compressed format, and possibly signed with some hash (e.g. CRC32) for verification.
- Upon resetting the device, a modified version of the universal boot loader will load, recognize that a new firmware image is pending (by reading some flag stored in flash memory).
- Above modified boot loader will open pending firmware image, decompress & verify as necessary to some memory area, to get the raw image which can now be used as-is. On a 256KB Flash, and disregarding the UBL footprint and possibly a few more Flash pages, firmware images of up to 128KB may be used with this process if we can safely override the current firmware version. If we can't override the current version, tighter restrictions will apply.
- Delete previous firmware image (or possibly keep it for recovery purposes).
- When done, reset again and load the (new) firmware image. Run normally.
- Using GATT characteristic writes to transfer data is slow. From what I read, under good conditions, effective throughput for this method doesn't get much higher than 5KBps (kilo-bytes). For a firmware image of 128KB, it will take ~25sec just to transfer the data. Is there a cleaner and/or faster way to do this?
- Are there any samples for bulk data transfer over BLE I can start off from?
- Are there any samples I can use as reference for modifying the UBL to do something similar to what I described?
- What is the footprint of UBL and other management data in the flash? From what I read it seems the UBL itself takes around 5 pages == 10KB. Is my information correct? Is there any "reserved" data I'm missing here?
- Which tools can I use to effectively minimize the object size of my firmware images? I realize it's already pretty bare-bones, but if there are specific compiler/linker flags I can use, modules that may be removed etc. It would make things quicker.
- Can the process be done more effectively than I described? Any suggestions would be welcome.