Gecko Bootloader can load application from different sources. It can load from host controller via UART/SPI. It can load from a remote device via Bluetooth connection (OTA - over the air). It can load from internal flash (if the internal flash is big enough to accomodate both the application code and an upgrade image). It can load from external flash.

What it cannot do is uploading the application to the internal/external flash before loading them from there. This article helps you implement the missing step: uploading the image to the internal/external flash via a Bluetooth connection.

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: https://www.silabs.com/community/wireless/bluetooth/knowledge-base.entry.html/2017/07/19/switching_betweenfi-GnNI

 

To make the OTA uploader compatible with the Silicon Labs Bluetooth OTA bootloader that loads the image directly to the application area, first we have to understand how the standard OTA DFU method works.

The standard OTA DFU sequence looks like this (provided that you use Bluetooth in-place OTA type 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 (an devices with small flash size this can overwrite app1.bin!!)
    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 OTA uploader uses a similar process:

  1. App is running (device is not reset, since the Uploader 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. Slot0 can be either in the internal or in the external flash. The application do not have to know this, flash is handled by the bootloader API)
  3. The remote device sends full.gbl (containing both stack and app code) using the same OTA control and OTA data characteristics as the standard OTA DFU bootloader
  4. gbl is saved into slot0/slot1 using the bootloader API (again, the application does not have to know where the slot is, bootloader API handles the writing)
    2017-09-20_14h43_14.png
  5. If there are multiple slots, the remote device chooses again which slot to upload to, using a custom characteristic (e.g. slot1)
  6. The remote device sends another 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 from the internal/external flash
    2017-09-20_14h45_37.png

 

Implementation

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. Remove the Silicon Labs OTA service from your GATT database if it is present
  6. Add the Silicon Labs OTA service in Visual GATT Editor (BLE GATT Configurator)
    1. On the left plane select Services
    2. Find Silicon Labs OTA services
    3. Drag and drop it to the right pane
    4. Select the Silicon Labs OTA Data characteristic
    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. Set Write and Write Without Response properties to true
    8. Select the Silicon Labs OTA control characteristic
    9. set its type the user
    10. Set Write and Write Without Response properties to true
  7. Add Slot Manager service in Visual GATT Editor (only needed if you want to manage multiple slots)
    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
  8. Now your GATT database should look like this:
                          2017-09-20_14h46_16.png          
  9. Click Generate to build the GATT database
  10. Copy the attached ota_dfu_multislot.c and ota_dfu_multislot.h files into the project
  11. Copy btl_interface.c and btl_interface_storage.c from C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v1.1\platform\bootloader\api to your project
  12. Go to Project Properties > C/C++ Build > Settings and add the following folder to the Includes:
    "${StudioSdkPath}/platform/bootloader"
    or copy the .h files from this folder to your project
  13. Add the followings to main.c
    1. Add #include “ota_dfu_multislot.h” to the beginning of 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
  14. Build the project
     
  15. 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-projects/ta-p/195432

    (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)

  16. Flash the image to your device

 

Usage

  1. Create full.gbl file from the application you want to upload. (Note: since the uploader is implemented in the user application, and not in the stack, you should implement the uploader 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

  • Knowledge Base Articles
  • Bluetooth Low Energy
  • Bluetooth Classic