Table of Content
Overview
Preparing Firmware Image
Create Private and Public Keys
Add Related Source Files
Modify Source Codes
Build Application
SIGN SOTAFU Image
Section Layout Configuration
Section Change after Flash Download
Section Change after OTA Firmware Upgrade
OTA Upgrade Procedure
Upgrade Procedure
Control Point Command Format
Status Codes
Sample Codes in Central Side
Simple Introduction of Android Sample Codes
OTA (Over-The-Air) Firmware Upgrade is a technology that a WICED Smart Device downloads an image from a central device (ex. Smart phone) over the (Bluetooth) air interface, and uses this image to upgrade its old firmware to a new one.
There are two kind of OTA Firmware Upgrade:
In WICED Smart SDK, we provide two kind of application for reference:
For the convenience of description, we give a convention here:
Obviously, to support OTA Firmware Upgrade, it needs that:
Notes:
This section describes how to prepare a Firmware Image which supports OTA function in peripheral (WICED Smart Device), and an OTA Image which used to do OTA upgrading.
Note: You also can refer to document “WICED-Secure-Over-the-Air-Firmware-Upgrade.pdf” in WICED Smart SDK.
When building a WICED Smart application, it also generates an OTA Image. So we can prepare these two images at the same time.
As mentioned before, WICES Smart SDK provides OTA Firmware Upgrade application for reference, so we will reuse its source codes.
In here, we use Secure OTA Firmware Upgrade (SOTAFU) to illuminate. The steps in peripheral side are as below:
Note: For No Secure OTA Firmware Upgrade, we only need to skip the Step 1 and 5.
WICED Smart SDK provides a tool to generate private and public key.
C:\Users\mudel\WICED\WICED-Smart-SDK-2.1.0\WICED-Smart-SDK\Tools\WsRsaKeyGen\Win32>WsRsaKeyGen.exe . Seeding the random number generator... . Generating the private key ... ok + Press Enter to exit this program. |
Figure 1: Generate Private and Public Key in Windows
This tool generates three files:
File: rsa_pub.c (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
unsigned char rsa_pub_key[] = { 0x01, 0x00, 0x01, 0x00, … 0x95, 0xae, 0x1f, 0xbf, 0x9d, 0x85, 0xb5, 0x77, 0x2e, 0x1f, 0xa3, 0x5c, 0x9a, 0x1b, 0x85, 0x3e, }; |
Figure 2: Source Codes of Public Key
Note: The private and public key pair is different in each time generated by the tool. If missing any files of them, obviously, the new OTA Image can’t be upgraded success thought the OTA Firmware Upgrade. Therefore, this two files need to be stored into a security place.
File: makefile.mk (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
######################################################################## # Add Application sources here. ######################################################################## APP_SRC = hello_sensor.c ws_sec_upgrade_ota.c ws_upgrade.c rsa_pub.c |
Figure 3: Add Source Files in Makefile to build
1. Add application’s version information.
Note: In current’s source code’s design, the new Major number must larger than old one.
This is the Firmware Image’s version information.
File: hello_sensor.c (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
… #define HELLO_SENSOR_APP_ID 0x3A19 #define HELLO_SENSOR_APP_VERSION_MAJOR 1 #define HELLO_SENSOR_APP_VERSION_MINOR 1 const WS_UPGRADE_APP_INFO WsUpgradeAppInfo = { /* ID = */ HELLO_SENSOR_APP_ID, /* Version_Major = */ HELLO_SENSOR_APP_VERSION_MAJOR, /* Version_Minor = */ HELLO_SENSOR_APP_VERSION_MINOR, }; … |
Figure 5: Define Version Information in Source Codes
File: ws_sec_upgrade_ota.h (src\apps\ota_secure_firmware_upgrade) |
… typedef struct { UINT16 ID; UINT8 Version_Major; UINT8 Version_Minor; } WS_UPGRADE_APP_INFO; … |
Figure 6: Application Version Information Structure
2. Add Secure WICED Smart Upgrade Service into GATT Database.
The main mechanism of OTA Firmware Upgrade is that using GATT Characteristic to control the procedure and OTA Image data’s transfer. So we need to add Secure WICED Smart Upgrade Service into GATT Database
The Secure WICED Smart Upgrade Service characteristics’ Handle and UUID are defined in header file “ws_sec_upgrade_ota.h”.
The characteristics’ handle and name’s mapping and function is described as follow:
Add Secure WICED Smart Upgrade Service in the end of your application’s GATT database as the red part shown in Figure 7.
File: hello_sensor.c (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
… const UINT8 hello_sensor_gatt_database[]= { ... PRIMARY_SERVICE_UUID128 (HANDLE_WS_UPGRADE_SERVICE, UUID_WS_SECURE_UPGRADE_SERVICE), CHARACTERISTIC_UUID128_WRITABLE (HANDLE_WS_UPGRADE_CHARACTERISTIC_CONTROL_POINT, HANDLE_WS_UPGRADE_CONTROL_POINT, UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT, LEGATTDB_CHAR_PROP_WRITE | LEGATTDB_CHAR_PROP_NOTIFY | LEGATTDB_CHAR_PROP_INDICATE, LEGATTDB_PERM_WRITE_REQ, 3), 0x00,0x00,0x00, CHAR_DESCRIPTOR_UUID16_WRITABLE (HANDLE_WS_UPGRADE_CLIENT_CONFIGURATION_DESCRIPTOR, UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION, LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ, 2), 0x00,0x00, CHARACTERISTIC_UUID128_WRITABLE (HANDLE_WS_UPGRADE_CHARACTERISTIC_DATA, HANDLE_WS_UPGRADE_DATA, UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA, LEGATTDB_CHAR_PROP_WRITE, LEGATTDB_PERM_VARIABLE_LENGTH | LEGATTDB_PERM_WRITE_REQ, 20), 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
CHARACTERISTIC_UUID128 (HANDLE_WS_UPGRADE_CHARACTERISTIC_APP_INFO, HANDLE_WS_UPGRADE_APP_INFO, UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 4), HELLO_SENSOR_APP_ID & 0xff, (HELLO_SENSOR_APP_ID >> 😎 & 0xff, HELLO_SENSOR_APP_VERSION_MAJOR, HELLO_SENSOR_APP_VERSION_MINOR, }; …. |
Figure 7: Add Secure WICED Smart Upgrade Service In Source Codes
Note: If Handle definition of Secure WICED Smart Upgrade Service overlaps with your application’s others Handle, you need to re-define them in header file “ws_sec_upgrade_ota.h”.
3. Add initialization code and Write Characteristic handler.
In source file “ws_sec_upgrade_ota.c”, it provides each Handle of characteristic’s handler function. The mapping is as follow:
The modification is as the red part shown in Figure 8.
File: hello_sensor.c (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
… APPLICATION_INIT() { ... bleapp_set_cfg((UINT8 *)hello_sensor_gatt_database, sizeof(hello_sensor_gatt_database), (void *)&hello_sensor_cfg, (void *)&hello_sensor_puart_cfg, (void *)&hello_sensor_gpio_cfg, hello_sensor_create); } void hello_sensor_create(void) { ... legattdb_regWriteHandleCb((LEGATTDB_WRITE_CB)hello_sensor_write_handler); ... ws_upgrade_ota_init(); … } ... int hello_sensor_write_handler(LEGATTDB_ENTRY_HDR *p) { … else if ((len >= 1) && (handle == HANDLE_WS_UPGRADE_CONTROL_POINT)) { return (ws_upgrade_ota_handle_command (attrPtr, len)); } else if ((len == 2) && (handle == HANDLE_WS_UPGRADE_CLIENT_CONFIGURATION_DESCRIPTOR)) { return (ws_upgrade_ota_handle_configuration (attrPtr, len)); } else if ((len > 0) && (len <= WS_UPGRADE_MAX_DATA_LEN) && (handle == HANDLE_WS_UPGRADE_DATA)) { return (ws_upgrade_ota_handle_data (attrPtr, len)); } else { ... } return 0; } … |
Figure 8: Add initialization code and Write Characteristic handler
After building an application, in directory “WICED-Smart-SDK\build\[APP_BUILD_TARGET]”, it will generate three images:
In here,
[APP_BUILD_TARGET] = [MAKE_TARGET]-rom-ram-Wiced-release
[MAKE_TARGET] = [APP_NAME]-[PLATFORM]
When create a new application’s make target, we need to specify its platform. All platforms are listed in folder “WICED-Smart-SDK\Platforms”. We can select one of them based on the chip on the board.
For example, the make target of application “ota_secure_firmware_upgrade” is “ota_secure_firmware_upgrade-BCM920737TAG_Q32 download”, so its [APP_NAME] is “ota_secure_firmware_upgrade”, [PLATFORM] is “BCM920737TAG_Q32”, and [APP_BUILD_TARGET] is “ota_secure_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wiced-release”.
Note: In the above case, the string “download” is a build parameter, it means that it will do downloading action after build success. If we don’t add this action string, it only does the code building. For more details, please refer “WICED-Smart-SDK\Makefile”.
WICED Smart SDK also provides sign tool.
Users\mudel\WICED\WICED-Smart-SDK-2.1.0\WICED-Smart-SDK\Tools\WsRsaSign\Win32>WsRsaSign.exe rsa.pri ota_secure_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wicedrelease.ota.bin 3A19 1 1 . Seeding the random number generator... . Reading private key from 'rsa.pri' . Generating the RSA/SHA-256 signature . Done (created "ota_secure_firmware_upgrade-BCM920737TAG_Q32-rom-ram-Wicedrelease.ota.bin.signed") |
Figure 9: Sign OTA Image
Secure OTA Firmware Image Format is as shown in Figure 10.
This section describes how to configure the NVRAM section to support OTA Firmware Upgrade.
Before to do this configuration, you need to configure the common section layout parameters in the BTP file as referred to document “WICED Smart BCM92073X EEPROM and SFLASH Layout.doc” first.
Obviously, if want to support OTA upgrade, we need a storage space to backup the original application Firmware Image in device, and a storage space to save the downloaded OTA Image, thus we can recover the firmware when the upgrading is interrupted by some unexpected event (ex. Power down).
Therefore, we use two DS that one is stored the current active Firmware Image and the another is used to store the downloaded OTA Image, to guarantee that even if the upgrading is interrupted, the original firmware still can work.
And, we also need one more SS section as a backup.
We need to configure its section layout in source codes as shown in Figure 11.
In Figure 11, “nv_loc_len[0]” is for EEPROM, and “nv_loc_len[1]” is for SFLASH.
The member of structure WS_UPGRADE_NV_LOC_LEN is as below:
File: ws_upgrade.c (WICED-Smart-SDK\Apps\ota_secure_firmware_upgrade) |
… const WS_UPGRADE_NV_LOC_LEN nv_loc_len[2] = { { /* .ss_loc = */ {0, 256}, /* .ds1_loc = */ 0x580, // ConfigDSLocation /* .ds1_len = */ 0x7A00, // ~31KB /* .ds2_loc = */ 0x8000, /* .ds2_len = */ 0x7A00, // ~31KB /* .vs1_loc = */ 0x140, // DLConfigVSLocation /* .vs1_len = */ 0x400, // DLConfigVSLength /* .vs2_loc = */ 0, // No VS2 for EEPROMS /* .vs2_len = */ 0 // No VS2 for EEPROMS }, // We are assuming that we have a 64KByte Serial Flash. If the SF is larger, you may change ds1_len, ds2_loc, ds2_len // accordingly. { /* .ss_loc = */ {0, 0x1000}, /* .ds1_loc = */ 0x4000, // ConfigDSLocation /* .ds1_len = */ 0x6000, /* .ds2_loc = */ 0xA000, /* .ds2_len = */ 0x6000, /* .vs1_loc = */ 0x2000, // DLConfigVSLocation /* .vs1_len = */ 0x1000, // DLConfigVSLength /* .vs2_loc = */ 0x3000, /* .vs2_len = */ 0x1000 }, }; … |
Figure 11: Section Configuration for OTA Upgrade in Source Code
According the configuration in Figure 11, the section layout is as below:
EEPROM Section Layout
In current design, the data size of SS section is 40 bytes. And its Byte 30-33 (The LSB (Least Significant Byte) is Byte 0.) records the DS’s start address. When the active DS section is changed, we need to modify these 4 bytes to point to the right address.
As referred to document “WICED Smart BCM92073X EEPROM and SFLASH Layout.docx”, the application image “[APP_BUILD_TARGET].hex” contains two sections to indicate the flash download by UART. After flash download, the section layout is as shown in Figure 14.
As shown Figure 15, comparing “[APP_BUILD_TARGET].hex” and “[APP_BUILD_TARGET].ota.hex”, we can find “[APP_BUILD_TARGET].ota.hex” only have a DS section, and its data is same as “[APP_BUILD_TARGET].hex”, so the OTA Image only contains the DS section, and it upgrade mainly the DS section in OTA Upgrade.
Figure 15: The Comparing Between Firmware Image and OTA Image
The procedure when upgrading is as below:
To be continued by WICED Smart BCM92073X OTA Firmware Upgrade (2)