OTA Update Guide

Last Updated on : 2024-11-20 02:13:27download

Upload firmware updates to the Tuya server via Tuya Developer Platform. Wi-Fi module transmits update files through Tuya protocols. The MCU receives an update package and writes it to flash memory. Thus, firmware updates can be performed on the device.

Note: Over-the-air (OTA) programming enables remote firmware and software updates.

SDK development

Preparation

  • Log in to Developer Platform, find Product on the left navigation bar, and click Entering to Develop. Go to Hardware Develop, find the development documents at the bottom of the page, and download MCU SDK, module serial port protocol, module debugging assistant, and function debugging file.
  • Migrate the code included in Tuya protocol SDK. For more information, see MCU SDK Migration.
  • You shall develop bootloader by yourself.

Protocol description

Relevant command definitions for the MCU update protocol are included in the Tuya Wi-Fi module serial protocol. For more information about the protocol format, see MCU upgrade service.

Note:

  • After the Wi-Fi module sends all update packets, it will reboot and resend the 0x01 command to query product information.
  • The MCU shall reply with the software version number and updated MCU version number within one minute. The version number shall be consistent with that configured and updated on the Tuya Developer Platform.

Function configuration

Grasping protocol interactions helps you smoothly understand SDK code logic. This section describes the MCU SDK functional configuration.

  • Find protocol.h from the path where the SDK is located and open it and change the MCU_VER value to the updated one.

    Note: For firmware to be updated, MCU_VER indicates the current firmware, such as 1.0.0. After updates, the MCU_VER shall be changed to the updated version number, such as 1.0.1.

                                1. Modify product information                
    ******************************************************************************/
    #define PRODUCT_KEY "xghwyjvd3ofo****"    // The 16-digit unique identifier of the product created on the Developer Platform.
    
    #define MCU_VER "1.0.0"                  // User's software version used for MCU firmware update, which shall be changed after MCU updates.
    
    
    /******************************************************************************
    
  • Open protocol.h and find update-related contents.

    /******************************************************************************
                            2. Whether to support MCU firmware updates                  
    To support MCU firmware updates, enable this macro.
    The MCU calls `mcu_firm_update_query()` function in `mcu_api.c` file to get MCU firmware update status.
                            ********WARNING!!!**********
    The current receiving buffer size is the one after disabling the firmware update function. You can choose the size of the firmware update package, which is 256 bytes by default.
    Enabling this function renders receiving buffer increased.
    
    ******************************************************************************/
    //#define         SUPPORT_MCU_FIRM_UPDATE                 // Enable MCU firmware update function, which is disabled by default.
    //Choose the size of firmware update package.
    #ifdef SUPPORT_MCU_FIRM_UPDATE
    #define PACKAGE_SIZE                   0        // The package is 256 bytes.
    //#define PACKAGE_SIZE                 1        // The package is 512 bytes.
    //#define PACKAGE_SIZE                 2       // The package is 1024 bytes.
    #endif
    /******************************************************************************
    
  • Enable macro definition SUPPORT_MCU_FIRM_UPDATE.

    /******************************************************************************
                            3. Define buffer for sending and receiving:
                        If the RAM of current MCU is insufficient, change it to 24.
    ******************************************************************************/
    #ifndef SUPPORT_MCU_FIRM_UPDATE
    #define WIFI_UART_RECV_BUF_LMT          16              // The size of serial data receiving buffer. If MCU's RAM is insufficient, it can be reduced.
    #define WIFI_DATA_PROCESS_LMT           24             // The size of serial data processing buffer, which is determined by the user's DP data size and shall be greater than 24.
    #else
    #define WIFI_UART_RECV_BUF_LMT          128           // The size of serial data receiving buffer. If MCU's RAM is insufficient, it can be reduced.
    
    // Choose the appropriate buffer size for MCU updates according to the size of the firmware update package.
    #define WIFI_DATA_PROCESS_LMT           300             // The size of the firmware update buffer shall be large. If a single package is 256, the buffer shall be greater than 260.
    //#define WIFI_DATA_PROCESS_LMT           600          // The size of the firmware update buffer shall be large. If a single package is 512, the buffer shall be greater than 520.
    //#define WIFI_DATA_PROCESS_LMT           1200        // The size of the firmware update buffer shall be large. If a single package is 1024, the buffer shall be greater than 1030.
    
    #endif
    
    #define WIFIR_UART_SEND_BUF_LMT         48              // It is determined by the user's DP data size and shall be greater than 48.
    /******************************************************************************
    

    Note: The length of data sent from the cloud has three types. Determine WIFI_DATA_PROCESS_LMT value according to the PACKAGE_SIZE. For example, #define PACKAGE_SIZE 1 corresponds to #define WIFI_DATA_PROCESS_LMT 600.

Relevant commands

#define         UPDATE_START_CMD                0x0a                            // Start updates.
#define         UPDATE_TRANS_CMD                0x0b                            // Transfer updates

Start updates (0x0a)

#ifdef SUPPORT_MCU_FIRM_UPDATE
  case UPDATE_START_CMD:                                // Start updates.
    // Get global variables of update package size.
    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;

Note: The above code processes receiving functions. Choose data package size according to the flag length and reply it with to the cloud. The cloud sends data on the received data package size.

Transfer updates (0x0b)

  case UPDATE_TRANS_CMD:                                // Transfer updates
    if(firm_update_flag == UPDATE_START_CMD)
    {
      //Stop reporting all data
      stop_update_flag = ENABLE;
      
      total_len = wifi_data_process_buf[offset + LENGTH_HIGH] * 0x100;
      total_len += 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 package.
        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,0);
      }
      //Restore reporting all data
      stop_update_flag = DISABLE;    
    }
    break;
#endif   

Update callback function

/*****************************************************************************
Function name: `mcu_firm_update_handle`.
Function description: MCU enters firmware update mode.
Input parameter: `value` indicates firmware buffer.

           position: The location of the data package.
           length: Length of the current firmware package. When the length is 0, it means the firmware package is sent successfully.

Return parameter: None.
Note: You need to implement this MCU function by yourself.
*****************************************************************************/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
  #error "Complete the MCU firmware update code and delete this line after completion."
  if(length == 0)
  {
    // The firmware data is sent successfully.
    
  }
  else
  {
    // Process firmware data.
  }
  
  return SUCCESS;
}
#endif

Configuration in Developer Platform

Note: Go to Hardware Development, find Selected Module, and click Add custom firmware to add firmware.

This section takes the heater as an example to describe the configuration steps in the Developer Platform.

  1. Log in to Developer Platform and click Product Management.

  2. Hover the mouse cursor over one of the products in Developing, and click Entering to Develop.

  3. Click Product Configuration.

    OTA Update Guide

  4. Find Firmware Updates Center and click Settings.

  5. In the upper left corner of the Firmware Version Management page, select firmware. OTA Update Guide

  6. Click Add Firmware Version in the upper right corner of the page to create a new firmware version.

    • Upload firmware: The update package is in .bin format.
    • Firmware version: Version number format is xx.xx.xx, such as 1.0.6.
    • Update methods:
      • Notification update: Users choose to update or not when the app prompts to update.
      • Forced update: Users shall update the firmware to continue using when the app prompts to update.
      • Detection update: Users click firmware updates to proactively update the firmware. No update prompt on the app.
  7. Add a test device.

    1. On Firmware Version Management page, click Common white list.
    2. On Whitelist Device page, click New Whitelist Device.
    3. On Verification Code page, enter Tuya Account and Verification Code and click OK to add test devices.
  8. Verify and publish firmware

    1. On Firmware Version Management page, click Verify.
      OTA Update Guide

    2. Select the service region in the upper right corner of the page.

      Note: Six regions are available for now, namely China, America, Europe, India, America Azure, and Europe MS.

    3. Click Verify that the upgrade is complete to check whether updates are completed.

      Note: Add test device by Choose to add from the whitelist or Add directly by device number.

      OTA Update Guide

Functional debugging

For more information about debugging, see Module Debugging Assistant.

FAQs

Q: If the update fails due to incorrect data in the update package, will the Wi-Fi module resend current data when an update is performed again? A: Yes. The data is sent three times. After that, the update is considered failed. Under this situation, when the update is restarted, the Wi-Fi module will send all data again.

Q: How can I get the device ID? A: You can find the device ID on Tuya’s all-in-one apps. Open the app, tap a device on the Home page and then tap Edit (pencil icon) in the top right corner. Find Device Information > Virtual ID.