OTA Firmware Updates

Last Updated on : 2021-09-18 13:58:14download

You can upload the update file to the Tuya IoT Platform. The Wi-Fi module can download the file from Tuya’s server and transmit the update file to the MCU through the serial protocol. This way, the MCU gets the file, writes it to the local flash memory, and performs updates.

An over-the-air (OTA) update is the wireless delivery of new software, firmware, or other data to connected IoT devices.

SDK development

Preparation

  1. Create a product on the Tuya IoT Platform.
  2. In the third step of Hardware Development, scroll down the page and download the MCU SDK, General Serial Protocol, Module Debugging Assistant, and Function Debugging File.
  3. Port the SDK to your platform. For more information, see Port HomeKit MCU SDK.
  4. Develop a bootloader.

Protocol description

The commands and definition used for MCU updates are specified in the Wi-Fi Serial Protocol. For more information, see Update MCU firmware.

  • After the module has sent all update packages, it will send the command 0x01 to query the product information.
  • The MCU must reply with the new MCU firmware version number within one minute. The new version number should be consistent with that configured on the Tuya IoT Platform.

Feature configuration

This section describes how to configure essential features with the MCU SDK.

  • Open the SDK and find protocol.h. Change the value of MCU_VER to the new firmware version number.

    MCU_VER is the firmware version number. For example, if its value is 1.0.0 before updates, you should change the value of MCU_VER to the new version number after updates, such as 1.0.1.

    /******************************************************************************
                1: Edit the product information. /             
    ******************************************************************************/
    #define PRODUCT_KEY "xghwyjvd3ofo****"    // The 16-digit product ID (PID) is the unique identifier of the product you have created on the Tuya IoT Platform.
    
    #define MCU_VER "1.0.0"                  // The MCU firmware version number, which must be changed to the new one after MCU updates.
    
    /******************************************************************************
    
  • Open protocol.h and find the part for MCU updates.

    /****************************************************************************** 2: Specify whether to enable support for MCU firmware updates. If so, enable this macro. The MCU can call `mcu_firm_update_query()` in the `mcu_api.c` to get the update information.
                 ******** Important **********
    The current size of the receive buffer is specified when the MCU update feature is disabled. The size of the update package defaults to 256 bytes and can be set as needed.
    You need to increase the receive buffer if you enable the MCU update feature.
    
    ******************************************************************************/
    //#define         SUPPORT_MCU_FIRM_UPDATE                 // Enable the MCU update feature, which is disabled by default.
    // Specify the size of the update package.
    #ifdef SUPPORT_MCU_FIRM_UPDATE
    #define PACKAGE_SIZE                   0        // One update package is 256 bytes.
    //#define PACKAGE_SIZE                 1        // One update package is 512 bytes.
    //#define PACKAGE_SIZE                 2       // One update package is 1024 bytes.
    #endif
    /******************************************************************************
    
  • Enable the macro SUPPORT_MCU_FIRM_UPDATE.

    /******************************************************************************
        3: Define the transmit and receive buffer: If your MCU has insufficient RAM, you can change the buffer size to 24 bytes.
    ******************************************************************************/
    #ifndef SUPPORT_MCU_FIRM_UPDATE
    #define WIFI_UART_RECV_BUF_LMT          16              // The serial receive buffer size, which can be reduced if your MCU has insufficient RAM.
    #define WIFI_DATA_PROCESS_LMT           24             // The buffer size for serial data processing. It depends on the amount of DP data but must be greater than 24 bytes.
    #else
    #define WIFI_UART_RECV_BUF_LMT          128           // The serial receive buffer size, which can be reduced if your MCU has insufficient RAM.
    
    // Set the proper buffer size for MCU updates depending on the defined size of the update package.
    #define WIFI_DATA_PROCESS_LMT           300             // The buffer size for MCU updates. If you set the size of a single update package to 256 bytes, the buffer size must be greater than 260 bytes.
    //#define WIFI_DATA_PROCESS_LMT           600          // The buffer size for MCU updates. If you set the size of a single update package to 512 bytes, the buffer size must be greater than 520 bytes.
    //#define WIFI_DATA_PROCESS_LMT           1200        // The buffer size for MCU updates. If you set the size of a single update package to 1024 bytes, the buffer size must be greater than 1030 bytes.
    
    #endif
    
    #define WIFIR_UART_SEND_BUF_LMT         48              // It depends on the amount of DP data but must be greater than 48 bytes.
    /******************************************************************************
    

    The length of data sent from the cloud comes with three types. You need to specify WIFI_DATA_PROCESS_LMT based on PACKAGE_SIZE.
    For example:

    #define PACKAGE_SIZE                 1
    

    Corresponds to

    #define WIFI_DATA_PROCESS_LMT           600
    
  • Single backup: Use the backup partition of the Wi-Fi module to receive and store the MCU firmware updates.

    If the MCU has only one firmware partition due to insufficient flash memory, in this case, the single backup is a reliable solution to deliver OTA updates.

    1. After an OTA update is initiated, the Wi-Fi module downloads the update file from the server and stores the file on its flash memory.
    2. When the update file is ready to install, the module sends the file to the MCU in packages.
    3. The MCU’s bootloader helps to write data while erasing the written data until the installation is completed.
    4. The module is restarted to complete the OTA update.
    /******************************************************************************/
    /*  Types of firmware partition */
    #define MCU_FIRMWARE_BACKUP_AREA_TYPE   0       // The MCU has two firmware partitions. 0 is the default value.
    //#define MCU_FIRMWARE_BACKUP_AREA_TYPE   1       // The MCU has one firmware partition.
    #endif
    /******************************************************************************
    

    If the device is powered off during updating, the module would report a failed OTA update. When the device is powered on, the module will send a command to notify the MCU to start updating. This process will be repeated until the update succeeds.

Commands

#define         UPDATE_START_CMD                0x0a                            // Start the update.
#define         UPDATE_TRANS_CMD                0x0b                            // Transmit the update file.

Start the update (0x0a)

#ifdef SUPPORT_MCU_FIRM_UPDATE
  case UPDATE_START_CMD:         // The update is started.
	// Get the size of the update file.
	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 module sends the cloud an appropriate size of the update package according to the flag. Then, the cloud will send the update package accordingly. The code above implements the receiving function. The expected number of packets to be received.

Transmit the updates (0x0b)

case UPDATE_TRANS_CMD:    // Start updates transmission.
	if(firm_update_flag == UPDATE_START_CMD)
	{
	    // Stop data reporting.
	  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 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,0);
	  }
	    // Resume data reporting.
	  stop_update_flag = DISABLE;
	}
	break;
#endif

Update callback

/*****************************************************************************
Function name: `mcu_firm_update_handle`
Description: The MCU enters update mode.
Input parameters: value: indicates the firmware buffer.

		position: indicates where the package is located.
	    length: the length of the current update package. When the length is zero, the transmission is completed.

Return parameter: none
Note: This function is intended to be implemented by you.
*****************************************************************************/
unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
  #error "Complete the code and then delete this line"
  if(length == 0)
  {
	// Transmission of updates is completed.

  }
  else
  {
	// Process updates.
  }

  return SUCCESS;
}
#endif

Upload updates

You can upload the update file to the Tuya IoT Platform to deploy a firmware update. For more information, see Update Firmware.

Debugging

For more information, see Module Debugging Assistant.

FAQs

Will the Wi-Fi module resend the data when an update is initiated again after an update failure?

Yes. The module will resend data three times. If it receives no response, the update failed. When an update is initiated again after an update failure, the Wi-Fi module will send all the data to the MCU.

How to get the virtual ID?

Open the Tuya Smart app and select a product. Tap the editing icon in the top right corner > Device Information > Virtual ID and tap Copy.

OTA Firmware Updates