Last Updated on : 2024-05-10 08:08:19download
An over-the-air (OTA) update is the wireless delivery of new software, firmware, or other data to connected devices.
The MCU SDK supports OTA updates for the MCU. You can upload the update file to the Developer Platform. The Wi-Fi module can download the update from the server and send it to the MCU through the serial port. This way, the MCU gets the update and writes it to the local flash memory for installation. For more information, see Update Firmware and Select and Change the Firmware Version.
The OTA update consumes the memory of the MCU. After a device is paired, an OTA update can be initiated through the preset configuration or check for updates. Here is how the OTA update works:
After the Wi-Fi module completes the update transmission, it will send the MCU the command 0x01
to request the product information. The MCU must reply with the new MCU software version number within one minute. The new version number should be consistent with that configured on the Developer Platform.
A successful OTA update can only be declared once the module completes the update transmission, and the MCU reports the latest firmware version number to the module after a restart.
In debugging phase or after product delivery, you can deploy MCU updates over OTA to fix issues and add new features. The OTA update feature is recommended if your MCU has enough memory resources.
Firmware management: You must upload the verified firmware updates to the Developer Platform for OTA update deployment. For more information, see Update Firmware.
Description: You can implement the serial communication between your MCU and the Tuya module by porting the MCU SDK or interfacing with the protocol without the SDK. Either approach requires you to develop a bootloader on your own.
Porting MCU SDK: With the OTA-related functions provided in the SDK, the MCU can respond with the size of a single packet, start the update process, and receive and process the update package. See the examples in the following sections.
Interfacing without SDK: You need to implement the OTA-related protocols, and file transfer and processing.
The RAM of your MCU must be greater than 260 bytes. You must implement the basic features of the protocol before working on the OTA feature.
You can specify how an OTA update is triggered. The module only serves as the channel for update transmission, without any data parsing operation.
Three trigger mechanisms are available:
The commands used in the MCU OTA update process.
Command | Description |
---|---|
0x0a | Start MCU OTA update |
0x0b | Transfer update package |
The module sends the command 0x0a
to tell the MCU the size of the update file. The MCU returns the maximum size of each packet.
Maximum transmission unit
Return value | Size |
---|---|
0x00 | 256 bytes. It is the default value and is compatible with legacy firmware. |
0x01 | 512 bytes |
0x02 | 1,024 bytes |
The module sends the following data.
Field | Bytes | Description |
---|---|---|
Header | 2 | 0x55aa |
Version | 1 | 0x00 |
Command | 1 | 0x0a |
Data length | 2 | 0x0004/0x0008 |
Data | 4 | The size of the update file in bytes. The data type is an unsigned integer, and the data is transmitted in big-endian format. |
Data | 1 | The MCU type, ranging from 10 to 19. |
Data | 3 | Reserved for future use. |
Checksum | 1 | Start from the header, add up all the bytes, and then divide the sum by 256 to get the remainder. |
Example: 55 aa 00 0a 00 04 00 00 68 00 75
It indicates the size of the update is 26624 bytes, namely 26 KB.
The MCU returns the following data.
Field | Bytes | Description |
---|---|---|
Header | 2 | 0x55aa |
Version | 1 | 0x03 |
Command | 1 | 0x0a |
Data length | 2 | 0x0001 |
Data | 1 | The options for the maximum size of each packet:
|
Checksum | 1 | Start from the header, add up all the bytes, and then divide the sum by 256 to get the remainder. |
Example: 55 aa 03 0a 00 01 00 0d
The module sends the update to the MCU in multiple packets. If the MCU fails to respond to the update transfer command within five seconds, the module will resend the command, and declare a failed update after three unsuccessful attempts.
The module sends the following data.
Field | Bytes | Description |
---|---|---|
Header | 2 | 0x55aa |
Version | 1 | 0x00 |
Command | 1 | 0x0b |
Data length | 2 | 0x0004 + N |
Data | 4 + N |
|
Checksum | 1 | Start from the header, add up all the bytes, and then divide the sum by 256 to get the remainder. |
Example:
Assume that the size of the update is 530 bytes, and the MCU does not need to respond to the last packet.
0x00000000
, and the packet length is 256 bytes.55 aa 00 0b 01 04 00000000 xx…xx XX
0x00000100
, and the packet length is 256 bytes.55 aa 00 0b 01 04 00000100 xx…xx XX
0x00000200
, and the packet length is 18 bytes.55 aa 00 0b 00 16 00000200 xx…xx XX
0x00000212
, and the packet length is 0 bytes.55 aa 00 0b 00 04 00000212 xx…xx XX
The MCU returns the following data.
Field | Bytes | Description |
---|---|---|
Header | 2 | 0x55aa |
Version | 1 | 0x03 |
Command | 1 | 0x0b |
Data length | 2 | 0x0000 |
Data | 0 | None |
Checksum | 1 | Start from the header, add up all the bytes, and then divide the sum by 256 to get the remainder. |
Example: 55 aa 03 0b 00 00 0d
Enable SUPPORT_MCU_FIRM_UPDATE
to turn on the MCU OTA update feature.
#define SUPPORT_MCU_FIRM_UPDATE // Enable the OTA update feature, which is disabled by default.
/* Firmware package size selection */
#ifdef SUPPORT_MCU_FIRM_UPDATE
#define PACKAGE_SIZE 0 // Maximum 256 bytes per packet
//#define PACKAGE_SIZE 1 // Maximum 512 bytes per packet
//#define PACKAGE_SIZE 2 // Maximum 1,024 bytes per packet
#endif
The serial data handler data_handle()
receives the MCU OTA update request from the module.
/**
* @brief Data frame processing.
* @param[in] {offset} The start bit.
* @return Null
*/
void data_handle(unsigned short offset)
{
......
case UPDATE_START_CMD: // Initiate an OTA update
// Get the global variable of the maximum transmission unit.
firm_flag = PACKAGE_SIZE;
if(firm_flag == 0) {
firm_size = 256;
}else if(firm_flag == 1) {
firm_size = 512;
}else if(firm_flag == 2) {
firm_size = 1024;
}
firm_length = wifi_data_process_buf[offset + DATA_START];
firm_length <<= 8;
firm_length |= wifi_data_process_buf[offset + DATA_START + 1];
firm_length <<= 8;
firm_length |= wifi_data_process_buf[offset + DATA_START + 2];
firm_length <<= 8;
firm_length |= wifi_data_process_buf[offset + DATA_START + 3];
upgrade_package_choose(PACKAGE_SIZE);
firm_update_flag = UPDATE_START_CMD;
break;
......
}
The MCU SDK calls upgrade_package_choose()
from protocol.c
to return the maximum size of each packet. You need to set the maximum transmission unit with the above macro for packet fragmentation.
/**
* @brief Select the maximum transmission unit.
* @param[in] {package_sz} Maximum transmission unit
* @ref 0x00: 256 bytes (default)
* @ref 0x01: 512 bytes
* @ref 0x02: 1,024 bytes
* @return Null
* @note To be implemented by you.
*/
void upgrade_package_choose(unsigned char package_sz)
{
#error "Complete the code for setting the maximum transmission unit and then delete this row"
unsigned short send_len = 0;
send_len = set_wifi_uart_byte(send_len, package_sz);
wifi_uart_write_frame(UPDATE_START_CMD, MCU_TX_VER, send_len);
}
Module Debugging Assistant
The module sends the update packet as per the specified maximum transmission unit, and the MCU receives it from the data_handle()
.
/**
* @brief Data frame processing.
* @param[in] {offset} The start bit.
* @return Null
*/
void data_handle(unsigned short offset)
{
......
case UPDATE_TRANS_CMD: //Start update file transfer.
if(firm_update_flag == UPDATE_START_CMD) {
//Stop data reporting.
stop_update_flag = ENABLE;
total_len = (wifi_data_process_buf[offset + LENGTH_HIGH] << 8) | wifi_data_process_buf[offset + LENGTH_LOW];
dp_len = wifi_data_process_buf[offset + DATA_START];
dp_len <<= 8;
dp_len |= wifi_data_process_buf[offset + DATA_START + 1];
dp_len <<= 8;
dp_len |= wifi_data_process_buf[offset + DATA_START + 2];
dp_len <<= 8;
dp_len |= wifi_data_process_buf[offset + DATA_START + 3];
firmware_addr = (unsigned char *)wifi_data_process_buf;
firmware_addr += (offset + DATA_START + 4);
if((total_len == 4) && (dp_len == firm_length)) {
// The last packet.
ret = mcu_firm_update_handle(firmware_addr,dp_len,0);
firm_update_flag = 0;
}else if((total_len - 4) <= firm_size) {
ret = mcu_firm_update_handle(firmware_addr,dp_len,total_len - 4);
}else {
firm_update_flag = 0;
ret = ERROR;
}
if(ret == SUCCESS) {
wifi_uart_write_frame(UPDATE_TRANS_CMD, MCU_TX_VER, 0);
}
//Resume data reporting.
stop_update_flag = DISABLE;
}
break;
......
}
The MCU SDK calls mcu_firm_update_handle()
to send the data, address, and data length to the MCU for processing the firmware update. This function needs to be implemented by you.
/**
* @brief The MCU enters the update mode.
* @param[in] {value} The buffer.
* @param[in] {position} The address of the current packet.
* @param[in] {length} The length of the firmware update. When it is zero, the update file transfer is completed.
* @return Null
* @note To be implemented by you.
*/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
#error "Complete the implementation for OTA update and then delete this row."
if(length == 0) {
// The update file transfer is completed.
}else {
//Process the received update file.
}
return SUCCESS;
}
Module Debugging Assistant
When mcu_firm_update_handle()
receives a packet length of 0
, the transmission is completed, and the MCU can begin update installation. This function needs to be implemented by you.
/**
* @brief The MCU enters the update mode.
* @param[in] {value} The buffer.
* @param[in] {position} The address of the current packet.
* @param[in] {length} The length of the firmware update. When it is zero, the update file transfer is completed.
* @return Null
* @note To be implemented by you.
*/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
#error "Complete the implementation for OTA update and then delete this row"
if(length == 0) {
//The update file transfer is completed.
}else {
//Process the received update file.
}
return SUCCESS;
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback