Uploading images to slots using OTA DFU

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero Employee</font></font> </a> arkalvac on ‎09-20-2017 07:58 AM

Gecko Bootloader supports multiple storage slots, where multiple firmware images can be stored. These images can then be loaded into the application area to be run. In current Bluetooth stack version (v2.4.x) OTA DFU (over-the-air device firmware upgrade) supports only the overwriting of the running stack and application image and it does not support the populating of the slots. Slots, however, can be easily written by user application using the bootloader API, so uploading can be solved on application level.

This article guides you through how to upload images to storage slots using the standard OTA DFU process. To learn how to bootload the uploaded images from the slots please read this article: http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/Switching-between-firmware-images-usin...

 

Standard OTA DFU versus multislot OTA DFU

 

The standard OTA DFU sequence looks like this (provided that you use Gecko Bootloader):

  1. App is running.
  2. Device is reset into DFU mode, which means that the supervisor code will run in the stack instead of the user application.
    2017-09-20_14h36_53.png
  3. The remote device sends stack.gbl using OTA control and OTA data characteristics
  4. gbl is saved into slot0
    2017-09-20_14h39_39.png
  5. The device is reset
  6. The bootloader parses the GBL file and copies the new stack code to the proper area
    2017-09-20_14h40_25.png
  7. The remote device sends app.gbl using OTA control and OTA data characteristics
  8. The headers of app.gbl file are saved to slot0 for parsing
  9. The remaining part of app.gbl is parsed on-the-fly and the retrieved application code is saved to the application area
    2017-09-20_14h41_12.png

 

The multislot OTA DFU process is the following:

  1. App is running (device is not reset, since multislot OTA DFU is implemented in the user application and not in the stack code)
    2017-09-20_14h36_53.png
  2. The remote device chooses which slot to upload to using a custom characteristic (e.g. slot0)
  3. The remote device sends full.gbl (containing both stack and app code) using the OTA control and OTA data characteristics
  4. gbl is saved into slot0/slot1 using the bootloader API
    2017-09-20_14h43_14.png
  5. The remote device chooses which slot to upload to using a custom characteristic (e.g. slot1)
  6. The remote device sends full.gbl (containing both stack and app code) using the OTA control and OTA data characteristics
  7. gbl is saved into slot0/slot1 using the bootloader API
    2017-09-20_14h44_05.png
  8. The remote device chooses which slot to bootload from using a custom characteristic
  9. The device is reset
  10. The bootloader parses the given slot, retrieves the stack and application code from the .gbl file and copies the code to the appropriate area
    2017-09-20_14h45_37.png

 

Implementing multislot OTA DFU

 

The attached code implements image uploading to the slots using the standard OTA process. It is also extended with the possibility to select a slot to upload to, and to select a slot to boot from. You are free to modify this example according to your needs.

To create a project with multislot OTA DFU follow these steps:

  1. Create an Internal Storage Bootloader (multiple images) or a SPI Flash Storage Bootloader (multiple images) project in Simplicity Studio
  2. Check the Storage Slot configuration in AppBuilder and modify it according to your needs.
  3. Generate and build the project
  4. Create a SoC – Empty project
  5. Add OTA data characteristic in Visual GATT Editor (BLE GATT Configurator)
    1. Add new characteristic under Silicon Labs OTA service
    2. Name it Silicon Labs OTA Data
    3. Set its UUID to 984227f3-34fc-4045-a5d0-2c581f81a153 (this is the standard UUID for OTA data)
    4. Set its ID to ota_data (needed for reference in the code)
    5. Set its type to user (the content will not be stored to database but processed by the application)
    6. Set its length to 244
    7. Add Write and Write Without Response properties
  6. Add Slot Manager service in Visual GATT Editor
    1. Add a new service, named e.g. Slot Manager Service
    2. Add a new characteristic within this service called e.g. Upload Slot (this will be used to select a slot to upload data to)
    3. Set its ID to upload_slot (needed for reference in the code)
    4. Set its type to hex
    5. Set its length to 1
    6. Add Read and Write properties
    7. Add a new characteristic within this service called e.g. Bootload Slot (this will be used to trigger bootload from the given slot)
    8. Set its ID to boot_slot (needed for reference in the code)
    9. Set its type to hex
    10. Set its length to 1
    11. Add Write property
                            2017-09-20_14h46_16.png          
  7. Click Generate to build the GATT database
  8. Copy the attached c and ota_dfu_multislot.h files to the project
  9. Copy c and btl_interface_storage.c from C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v1.1\platform\bootloader\api to your project
  10. Go to Project Properties > C/C++ Build > Settings and add the following folder to the Includes:
    "${StudioSdkPath}/platform/bootloader"
  11. Overwrite main.c with the attached one, or
    1. Add #include “ota_dfu_multislot.h” to main.c
    2. Add ota_dfu_handle_event(evt); after evt = gecko_wait_event();
    3. Remove the code that implements resetting into DFU mode
      (case gecko_evt_gatt_server_user_write_request_id)
    4. Save main.c
  12. Build the project
  13. Add the bootloader image to your application image as described here:

http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/Adding-Gecko-Bootloader-to-Bluetooth-p...

(Note: setting gecko_bootloader=true in the .isc file will copy btl_interface.c and btl_interface_storage.c into your project again. Remove the instances you copied before to avoid duplicated definitions)

 

14. Flash the image to your device

 

Usage of multislot OTA DFU

 

  1. Create full.gbl file from the application you want to upload. (Note: since multislot OTA DFU is implemented in the user application, and not in the stack, you should implement multislot OTA DFU in the application to be uploaded, as well!) E.g.
    1. Make a copy of your multislot OTA DFU project
    2. Change the Device Name from “Empty Example” to “Updated app” in the Visual GATT Editor
    3. Press Generate
    4. Build the project
    5. Run create_bl_files.bat
    6. Find the .gbl files in output_gbl folder
  2. Copy full.gbl to your smartphone (in case of Android copy it to SiliconLabs_BGApp/OTAFiles/myproject, in case of iOS upload it to iCloud)
  3. Open Blue Gecko app on your smartphone
  4. Find your device with Bluetooth browser (advertising as Empty Example) and connect to it
  5. Find the unknown service and open it (this is your custom service including Upload slot and Bootload slot characteristics)
  6. Open the first characteristic (this is the upload characteristic) and write the slot number in it, you want to upload to
  7. In the local menu select OTA
  8. Select the partial OTA tab
  9. Select the folder and the full.gbl file you want to upload
  10. Click OTA. The file will be uploaded to the selected slot.
  11. Now open the second characteristic in the unknown service (Bootload slot) and write the slot number in it, you want to load the application from. The device will be reset and the application will be loaded.
  12. Disconnect and find your device advertising itself as “Updated app”

2017-09-20_14h48_41.png

2017-09-20_14h49_26.png