OTA
OTA refers to the wireless delivery of software updates to devices. SDK supports OTA via Bluetooth. SDK supports two Bluetooth transports for Android and iOS: OTA via GATT, which is suitable for both iOS and Android, and OTA via SPP, which is only suitable for Android. The OTA block diagram is shown in the following chart.
As shown in Flash, two bank areas are allocated to store the images, but only one bank is active at a time. The images in the two banks will be authenticated during the SoC boot process. If the images in both banks are all valid, the bank with the higher version will be selected to run. The versions of images in two banks will be compared in a specific sequence until a difference is found. If only one bank’s images are valid, this bank will be selected to run. For OTA, all the images in both banks should be packed together, and the OTA tool will automatically select the images to transfer to the inactive bank. This user manual describes OTA related information. The following topics are included to help users establish the OTA environment.
Flash Layout
OTA Flow
OTA via GATT
OTA via SPP
Code Overview
Experimental Verification
Flash Layout
The flash layout of the chip can be modified according to user requirements. The layout information is stored in the system configuration image and OTA header image. Please refer to the SDK Document (Image Layout and Flash) for more detailed information.
Dual Bank
Two bank areas (bank0 and bank1) can be allocated to save images. However, only one bank is active at a time; the other one is a backup. The SoC will determine which bank is active during boot based on certain rules.
Bank Switching Check Rules
The bootloader authenticates the bank with the higher image version first. If all the images in this bank are authenticated successfully, this bank will be activated. Otherwise, the other bank will be authenticated. If authentication fails for both banks, the SoC will fail to boot and cannot be recovered via OTA. When comparing versions, the OTA header image has the highest priority, followed by the order of images in the OTA header image. For example:
Assuming the OTA Header image version of bank0 is higher than bank1, so bank0 will be selected for authentication first.
Bank Name
Image Version
Result
Bank0
OTA Header(version: 0.0.0.2),
Other imagesBank0 will be selected first regardless other images.
Bank1
OTA Header(version: 0.0.0.1),
Other imagesAssuming the OTA Header image version is the same for two banks, and the FSBL image version of bank1 is higher than bank0. In this case, bank1 will be selected for authentication first.
Bank Name
Image Version
Result
Bank0
OTA Header(version: 0.0.0.1),
FSBL(version:0.0.0.2),
Other imagesBank1 will be selected first regardless other images.
Bank1
OTA Header(version: 0.0.0.1),
FSBL(version:0.0.0.3),
Other images
OTA Flow
Images pushed by the OTA tool will always be saved in the inactive bank during the OTA process. The SoC will reboot after all images have been pushed and validated successfully. The advantage of dual bank OTA is that there is always a backup bank, so users do not need to worry about the SoC crashing if the OTA process fails. Because the bank with all legal images and higher versions will be selected to be activated by the bootloader, the upgraded images should have higher versions and be integrated. Otherwise, the images will not be activated when the chip reboots.
Dual Bank OTA Mode
The dual bank OTA flow is shown in the following chart. The mobile phone is the controller and the SOC is the target. The controller makes a connection to the target before the OTA begins. Subsequently, the controller obtains the target information to determine if the upgrade is authorized.
Image Data Push
During the process of pushing an image from the OTA tool to the SoC, we designed the following mechanism to ensure correctness.
Buffer Check
This function can be considered a simple moving-window detection method. The OTA tool calculates the CRC of every N-byte payload and sends this checksum value to the SoC after pushing the data.
The size of the N-byte payload is negotiated by the MCU and OTA tool before OTA starts.
The SoC first saves this N-byte payload in a temporary buffer, then calculates the data checksum and compares it with the checksum value received from the OTA tool.
If the checksum values match, the SoC saves the data to the inactive bank. If they do not match, the SoC discards the data and notifies the tool, which will then retransmit the payload. This function is enabled by default to detect transmission errors as early as possible.
Encrypted Transmission
The OTA tool and SoC support encrypted transmission. You can change the function app_ota_enc_setting
to set it for the common SDK, and you can use MCUConfig Tool to set it for the headset. Currently, one algorithm AES256 is supported.
The OTA tool encrypts each N-byte payload before pushing it to the SoC.
When buffer check is enabled, the N-byte payload will be encrypted together. When buffer check is disabled, each packet will be encrypted separately before being pushed to the SoC.
The SoC decrypts the data before saving it to Flash.
Image Validation
The OTA tool will send the command to force the SoC to validate the entire image after an image has been fully delivered to the SoC. The checksum value (SHA256 or CRC) will be calculated and filled in the image header when the image is generated. The SoC calculates the checksum value and compares it with the value in the image header. If the two values are different, it will notify the OTA tool, and the OTA process will be considered a failure and terminated.
Image Skip and Copy
As mentioned above, to avoid image mismatches and omissions, packing whole images is mandatory. To improve upgrade efficiency, some mechanisms are designed to avoid unnecessary image transmission. At the beginning of the OTA process, the OTA tool will query the versions and checksums of all the images (including both banks) of the SoC.
Image Skip
The tool will compare each image version and SHA256 with the SoC’s inactive bank image. If both the version and SHA256 value are the same, the tool will regard the image as already existing in the inactive bank. The tool will then send a command to validate this image directly, and the SoC will check the validation and integrity of the image in the inactive bank.
If validation is successful, this image will be skipped.
If validation fails, some images can proceed to the image copy flow.
Image Copy
For some address-independent images, such as the DSP SYS Image, DSP APP Image, DSP Config Image, App Config File, and ANC Config File, the image copy mechanism may also enhance OTA efficiency. The tool compares the version and SHA256 of the address-independent images with those of the active bank images. If both the version and SHA256 value match, the tool will send a copy image command to the SoC. The SoC then copies the image from the active bank to the inactive bank and validates it. If the copy and validation are successful, this image can also be skipped. If both the image skip and image copy methods fail, the tool will proceed with the normal image data push transfer flow.
Reset and Version Re-check
Once all the images are pushed, copied, or skipped, the OTA tool will trigger an SoC reset. SoC will reboot to select the new active bank and activate the upgraded images. OTA tool will attempt to reconnect to the SoC and query the versions of all the images in the currently active bank to verify that the OTA has taken effect.
OTA via GATT
An overview of the GATT profile is provided in GATT Profile Server.
GATT OTA Service Introduction
OTA attribute table is a C array defined in ota_service.c
, which is used to declare two OTA-related services: OTA Service and DFU Service.
static const T_ATTRIB_APPL gatt_extended_service_table[] = {...};
OTA Service
OTA service is used to acquire device information or enter OTA Mode. Service UUID used in OTA Demo is defined in the following table.
Service Name |
Service UUID |
---|---|
OTA Service |
0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00 |
The characteristics are shown in the following table.
Characteristic Name |
Requirement |
Characteristic UUID |
Properties |
---|---|---|---|
Enter OTA Mode |
M |
0xFFD1 |
WriteWithoutResponse |
BD Address |
M |
0xFFD2 |
Read |
Device Information |
M |
0xFFF1 |
Read |
Image Version |
M |
0xFFE0 ~ 0XFFEF |
Read |
Protocol Type |
M |
0xFFE3 |
Read |
Image Section Size |
M |
0xFFF4~FFF6 |
Read |
DFU Service
DFU service is used to do the updating process. Service UUID used in OTA Demo is defined in the following table.
Service Name |
Service UUID |
---|---|
DFU Service |
0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x62, 0x00, 0x00 |
The characteristics are shown in the following table.
Characteristic Name |
Requirement |
Characteristic UUID |
Properties |
---|---|---|---|
DFU Data |
M |
0x8763 |
WriteWithoutResponse |
DFU Control Point |
M |
0x8764 |
Write, Notify |
The opcode is from controller to target and the notification is from target to controller. All opcodes and notifications are shown in the following table.
OPCODE |
OPCODE NAME |
Notification |
Description |
---|---|---|---|
0x01 |
DFU_OPCODE_START_DFU |
0x01 |
Start OTA and transfer header |
0x02 |
DFU_OPCODE_RECEIVE_FW_IMAGE_INFO |
0x02 |
Receive image info |
0x03 |
DFU_OPCODE_VALID_FW |
0x03 |
Valid the received image |
0x04 |
DFU_OPCODE_ACTIVE_IMAGE_RESET |
0x04 |
Reset to active new image |
0x05 |
DFU_OPCODE_SYSTEM_RESET |
0x05 |
Stop OTA flow and reset parameters |
0x06 |
DFU_OPCODE_REPORT_TARGET_INFO |
0x06 |
Get image info of target |
0x07 |
DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ |
0x07 |
Connection parameter update |
0x09 |
DFU_OPCODE_BUFFER_CHECK_EN |
0x09 |
Enable buffer check |
0x0A |
DFU_OPCODE_REPORT_BUFFER_CRC |
0x0A |
Transfer CRC value and start check |
0x0C |
DFU_OPCODE_COPY_IMG |
0x0C |
Copy image from active bank to inactive bank |
0x0D |
DFU_OPCODE_GET_IMAGE_VER |
0x0D |
Get inactive bank image version |
0x0E |
DFU_OPCODE_GET_SECTION_SIZE |
0x0E |
Get layout size of image in active bank |
0x0F |
DFU_OPCODE_CHECK_SHA256 |
0x0F |
Check the field of SHA256 |
0x10 |
DFU_OPCODE_GET_RELEASE_VER |
0x10 |
Get the release version of APP Config File |
Detailed OTA via GATT Flow
The detailed flow via GATT is shown in the following chart.
OTA via SPP
An overview of the SPP profile is provided in SPP.
SPP OTA CMD and EVENT Introduction
The CMD is from controller to target and the event is from target to controller. All OTA CMD and EVENT are shown in the following Table.
CMD NAME |
CMD ID |
EVENT NAME |
EVENT ID |
Description |
---|---|---|---|---|
CMD_OTA_DEV_INFO |
0x0600 |
EVENT_OTA_DEV_INFO |
0x0600 |
Get device info of target |
CMD_OTA_ACTIVE_BANK_VER |
0x0601 |
EVENT_OTA_GET_IMG_VER |
0x0601 |
Get image version of target |
CMD_OTA_START |
0x0602 |
EVENT_OTA_START |
0x0602 |
Start OTA and transfer header |
CMD_OTA_PACKET |
0x0603 |
EVENT_OTA_PACKET |
0x0603 |
Transfer data packet |
CMD_OTA_VALID |
0x0604 |
EVENT_OTA_VALID |
0x0604 |
Valid the received image |
CMD_OTA_RESET |
0x0605 |
NONE |
NONE |
Stop OTA flow and reset parameters |
CMD_OTA_ACTIVE_RESET |
0x0606 |
EVENT_OTA_ACTIVE_ACK |
0x060B |
Reset to active new image |
CMD_OTA_BUFFER_CHECK_ENABLE |
0x0607 |
EVENT_OTA_BUFFER_CHECK_ENABLE |
0x0605 |
Enable buffer check |
CMD_OTA_BUFFER_CHECK |
0x0608 |
EVENT_OTA_BUFFER_CHECK |
0x0606 |
Transfer CRC value and start check |
CMD_OTA_IMG_INFO |
0x0609 |
EVENT_OTA_IMG_INFO |
0x0607 |
Get image info of target |
CMD_OTA_SECTION_SIZE |
0x060A |
EVENT_OTA_SECTION_SIZE |
0x0608 |
Get layout size of image in active bank |
CMD_OTA_DEV_EXTRA_INFO |
0x060B |
EVENT_OTA_DEV_EXTRA_INFO |
0x0609 |
Get extra info of target |
CMD_OTA_PROTOCOL_TYPE |
0x060C |
EVENT_OTA_PROTOCOL_TYPE |
0x060A |
Get protocol type |
CMD_OTA_GET_RELEASE_VER |
0x060D |
EVENT_OTA_GET_RELEASE_VER |
0x060C |
Get the release version of APP Config File |
CMD_OTA_INACTIVE_BANK_VER |
0x060E |
EVENT_OTA_INACTIVE_BANK_VER |
0x060D |
Get inactive bank image version |
CMD_OTA_COPY_IMG |
0x060F |
EVENT_OTA_COPY_IMG |
0x060E |
Copy image from active bank to inactive bank |
CMD_OTA_CHECK_SHA256 |
0x0610 |
EVENT_OTA_CHECK_SHA256 |
0x060F |
Check the field of SHA256 |
Detailed OTA via SPP Flow
The detailed flow via SPP is shown in the following chart.
Code Overview
The OTA code overview will be introduced according to the following parts:
The OTA code directory will be introduced in the chapter Source Code Directory.
The OTA source code overview will be introduced in the chapter Source Code Overview.
Source Code Directory
This section describes the OTA directory.
OTA via GATT Source Code Directory
The reference files directory is as follows:
app_ota.c
:sdk\src\sample\ota_demo
.app_ota.h
:sdk\src\sample\ota_demo
.ota_service.c
:sdk\src\sample\common\app_ble_service
.ota_service.h
:sdk\src\sample\common\app_ble_service
.
OTA via SPP Source Code Directory
The reference files directory is as follows:
app_ota.c
:sdk\src\sample\ota_demo
.app_ota.h
:sdk\src\sample\ota_demo
.
Source Code Overview
This section provides a description of certain portions of the source code used in the OTA.
OTA via GATT Source Code Overview
Register OTA service in the initialization process and increase the server number of server_init()
.
void app_ble_service_init(void)
{
...
server_init(...);
ota_add_service(audio_app_ota_srv_cb);
...
}
Re-generate 128-bit UUID of OTA service by generator tool, and fill it to GATT_UUID_OTA_SERVICE[16]
.
Also, update the UUID at iOS/Android Controller.
static const uint8_t GATT_UUID_OTA_SERVICE[16] = {...};
Process can be added to the callback function.
static T_APP_RESULT audio_app_ota_srv_cb(T_SERVER_ID service_id, void *p_data)
{
...
}
The OTA attribute table defined in ota_service.c
is used to declare the two OTA-related services, you can add services and characteristics here.
static const T_ATTRIB_APPL gatt_extended_service_table[] = {...};
If you add a new service or characteristic to the attribute table, you can handle it in the following two functions.
static T_APP_RESULT ota_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
uint16_t attr_index, T_WRITE_TYPE write_type, uint16_t length,
uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
static T_APP_RESULT ota_service_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
uint16_t attr_index,
uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
New control point handle can be added to this function.
T_APP_RESULT app_ota_ble_handle_cp_req(uint8_t conn_id, uint16_t length, uint8_t *p_value)
{
...
}
OTA via SPP Source Code Overview
SPP OTA command and event ID can be added to the ID Tables.
typedef enum
{
...
EVENT_OTA_DEV_INFO = 0x0600,
EVENT_OTA_GET_IMG_VER,
EVENT_OTA_START,
EVENT_OTA_PACKET,
EVENT_OTA_VALID,
EVENT_OTA_BUFFER_CHECK_ENABLE,
EVENT_OTA_BUFFER_CHECK,
EVENT_OTA_IMG_INFO,
...
}
typedef enum
{
...
CMD_OTA_DEV_INFO = 0x0600,
CMD_OTA_GET_IMG_VER,
CMD_OTA_START,
CMD_OTA_PACKET,
CMD_OTA_VALID,
CMD_OTA_RESET,
CMD_OTA_ACTIVE_RESET,
CMD_OTA_BUFFER_CHECK_ENABLE,
CMD_OTA_BUFFER_CHECK,
CMD_OTA_IMG_INFO,
...
}
SPP command handle function app_ota_cmd_handle()
is added to the SPP Data Entrance.
void app_cmd_handler(uint8_t *cmd_ptr, uint16_t cmd_len, uint8_t cmd_path, uint8_t rx_seqn,
uint8_t app_idx)
{
switch (cmd_id)
{
...
case CMD_OTA_DEV_INFO :
case CMD_OTA_ACTIVE_BANK_VER:
case CMD_OTA_START:
case CMD_OTA_PACKET:
case CMD_OTA_VALID:
case CMD_OTA_RESET:
case CMD_OTA_ACTIVE_RESET:
case CMD_OTA_BUFFER_CHECK_ENABLE:
case CMD_OTA_BUFFER_CHECK:
case CMD_OTA_IMG_INFO:
{
app_ota_cmd_handle(cmd_len, cmd_ptr, app_idx);
}
break;
...
}
}
SPP ack handle function app_ota_cmd_ack_handle()
is added to the SPP Data Entrance.
void app_cmd_handler(uint8_t *cmd_ptr, uint16_t cmd_len, uint8_t cmd_path, uint8_t rx_seqn,
uint8_t app_idx)
{
...
switch (cmd_id)
{
case CMD_ACK:
{
...
if (cmd_path == CMD_PATH_UART)
{
...
}
else if ((cmd_path == CMD_PATH_LE) || (cmd_path == CMD_PATH_SPP))
{
...
if (event_id == EVENT_OTA_ACTIVE_ACK)
{
app_ota_cmd_ack_handle(event_id, status);
}
...
}
}
break;
...
}
...
}
New SPP command handle can be added to this Function.
void app_ota_cmd_handle(uint16_t length, uint8_t *p_value, uint8_t app_idx)
{
...
switch (cmd_id)
{
...
}
}
Experimental Verification
After programming the application bin to the EVB board, testing can be done with a mobile phone.
Prepare the Image to Update
The OTA header generate tool and image pack tool are all integrated into the MPPG Tool.
Generate OTA Header
Load flash_map.ini
(e.g. RTL87x3E-SDK-VX.X.X.X\bin\flash_map_config\flash_4M\flash_map.ini
) and RSA key (e.g. RTL87x3E-SDK-VX.X.X.X\tool\Gadgets\default_rsa_key.pem
). Select bank0 or bank1 and fill in the version manually to generate the OTA header bin.
Pack Whole Images
Load flash_map.ini
(e.g. RTL87x3E-SDK-VX.X.X.X\bin\flash_map_config\flash_4M\flash_map.ini
), then select bank0 and bank1 to add files for packing the whole images in both banks (except System Config File and Boot Patch File).
Note
Please refer to MPPG Tool Chain User Guide in the tool/MPPG Tool directory for details.
iOS Tool User Guide
Both Audio Connect and OTA tool can perform OTA procedures on iOS phones.
iOS Audio Connect Tool User Guide
Enable LE advertising on the LE page in MCUConfig Tool.
Connect with the target device. The device information including the image version will be shown in the UI.
Select firmware and the firmware version will be shown below.
Start updating process.
iOS OTA Tool User Guide
Connect with the target device. The device information including the image version will be shown in the UI.
Enable LE advertising on the LE page in MCUConfig Tool.
Select firmware and the firmware version will be shown below.
Start updating process.
Android Tool User Guide
Both Audio Connect and OTA tool can perform OTA procedures on android phones.
Android Audio Connect User Guide
Let the device support the SPP profile and enter pairable mode.
Connect with the target device. The device information, including the image version, will be shown in the UI.
Select firmware and the firmware version will be shown below.
Start the updating process.
Android OTA Tool User Guide
Let the device support the SPP profile and enter pairable mode.
Connect with the target device. The device information, including the image version, will be shown in the UI.
Select firmware and the firmware version will be shown below.
Start updating process.