3.1.7.5 Wi-Fi OTA Service Interface
The OTA service role is to enable the module firmware update over the network link. The
OTA service has the HTTP based file download and RNWF Device Firmware Update (DFU)
implementation. The OTA service open ups a TCP tunnel to receive the OTA server and
firmware image details. Any device (say PC or Mobile) in the network can initiate the
firmware download process. Once the OTA service receives all the necessary details, it
starts downloading the firmware image and reports each downloaded chunk to user
application over the callback. The user application needs to store the firmware in the
local memory. After the successful download the user application can use the OTA service
API's to flash new image into the RNWF module. The OTA service API call syntax is
provided
below:
RNWF_RESULT_t RNWF_OTA_SrvCtrl( RNWF_OTA_SERVICE_t request, void *input)
The following table provides the list of OTA services available:
Option/Command | Input | Description |
---|---|---|
RNWF_OTA_ENABLE | Buffer of 4096 (to align with DFU max write size) bytes | Enable OTA service and opens a TCP tunnel to receive the OTA server and Image details |
RNWF_OTA_SET_CALLBACK | Callback handler | Register callback function for the OTA service to report the status |
RNWF_OTA_DFU_INIT | None | Generates the DFU pattern and places the RNWF module in firmware update mode |
RNWF_OTA_DFU_WRITE | chunk_addr, chunk_size, chunk_ptr | Writes the given chunk into the RNWF module. Max chunk size can be 4096 bytes. |
RNWF_OTA_DFU_ERASE | chunk_addr, chunk_size, chunk_ptr | Erases the provided size of memory (chunk_ptr can be NULL) |
RNWF_OTA_DISABLE | None | Not used in V1.0.0 release |
RNWF_OTA_REQUEST | Structure containing details of image to be downloaded | Request OTA Service to setup a connection with OTA server to start image download |
RNWF_OTA_SET_SRVC_CALLBACK | Callback handler | Register callback function from any service using OTA Service |
RNWF_OTA_AUTO_MODE | None | Not used in V1.0.0 release |
RNWF_OTA_RESET | None | Request reset of RNWF11 |
The following table captures the OTA Callback event codes and event data:
Event | Response Component | Description |
---|---|---|
RNWF_EVENT_DWLD_START | Total size of the image file to be downloaded | Given image file download has started |
RNWF_EVENT_DWLD_DONE | Total size of downloaded Image file | Firmware download process completed, the application can initialize the DFU and start flle |
RNWF_EVENT_FILE_CHUNK | chunk_addr, chunk_size, chunk_ptr | Received image file chunk, the received data chunk must be saved in non-volatile memory |
RNWF_EVENT_DWLD_FAIL | None | Firmware download failed |
RNWF_EVENT_MAKE_UART | None | Not used in V1.0.0 release |
RNWF_EVENT_CONFIG_INFO | None | Not used in V1.0.0 release |
RNWF_EVENT_IMAGE_INFO | Structure containing detailed information about Image like File Name, Image Type etc | Event used to notify customer application about image details |
The sequence chart for the OTA process is provided below:
The example code for OTA DFU is provided below:
/* OTA application */ extern uint8_t app_buf[OTA_BUF_LEN_MAX]; uint32_t gOta_file_size = 0; void APP_OTA_Program(uint32_t flash_addr, uint32_t flash_size) { RNWF_OTA_CHUNK_t ota_chunk = { .chunk_addr = 0x60000000, .chunk_ptr = app_buf, .chunk_size = flash_size}; printf("Triggering DFU %lu\r\n", flash_size); RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_INIT, (void *)NULL); while(RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_ERASE, (void *)&ota_chunk) != RNWF_PASS); while(flash_size) { ota_chunk.chunk_size = (flash_size < OTA_BUF_LEN_MAX)?flash_size:OTA_BUF_LEN_MAX; /* User needs to read the stored OTA image and pass-in to RNWF_OTA_SrvCtrl() */ HighSpeed_Read_Cont(flash_addr, ota_chunk.chunk_size, (char *)app_buf); RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_WRITE, (void *)&ota_chunk); flash_size -= ota_chunk.chunk_size; ota_chunk.chunk_addr += ota_chunk.chunk_size; flash_addr += ota_chunk.chunk_size; printf("Remaining %lu bytes\r\n", flash_size); } } void APP_OTA_Callback(RNWF_OTA_EVENT_t event, void *p_str) { static uint32_t flash_addr = OTA_FLASH_IMAGE_START; switch(event) { case RNWF_EVENT_MAKE_UART: break; case RNWF_EVENT_DWLD_START: { printf("Total Size = %lu\r\n", *(uint32_t *)p_str); printf("Erasing the SPI Flash\r\n"); WREN(); Chip_Erase(); Wait_Busy(); SPI_Global_Block_Protection_Unlock(); printf("Erasing Complete!\r\n"); } break; case RNWF_EVENT_DWLD_DONE: { printf("Download Success!= %lu bytes\r\n", *(uint32_t *)p_str); /* Completed the Image download, start the DFU */ APP_OTA_Program(OTA_FLASH_IMAGE_START, *(uint32_t *)p_str); APP_SW_RESET_Handler(); } break; case RNWF_EVENT_FILE_CHUNK: { volatile RNWF_OTA_CHUNK_t *ota_chunk = (RNWF_OTA_CHUNK_t *)p_str; /* Save the received Image chunk into the serial SST flash*/ Sector_Program(flash_addr, ota_chunk->chunk_ptr, ota_chunk->chunk_size); flash_addr += ota_chunk->chunk_size; } break; case RNWF_EVENT_DWLD_FAIL: { /* Erase the Serial SST flash*/ WREN(); Chip_Erase(); Wait_Busy(); } break; default: break; } } void APP_WIFI_Callback(RNWF_WIFI_EVENT_t event, uint8_t *p_str) { switch(event) { case RNWF_DHCP_DONE: { printf("DHCP IP:%s\n", &p_str[2]); // Enable OTA by passing the OTA buffer space if(RNWF_OTA_SrvCtrl(RNWF_OTA_ENABLE, (void *)app_buf) == RNWF_PASS) { printf("Successfully Enabled the OTA\r\n"); } else { printf("Failed to enable the OTA\r\n"); } break; } default: { break; } } } void RNWF_APP_Initialize(void) { /* Wi-Fii Connectivity */ RNWF_WIFI_PARAM_t wifi_sta_cfg = {RNWF_WIFI_MODE_STA, HOME_AP_SSID, HOME_AP_PASSPHRASE, HOME_AP_SECURITY, 1}; printf("Connecting to %s\r\n", HOME_AP_SSID); RNWF_WIFI_SrvCtrl(RNWF_WIFI_SET_CALLBACK, APP_WIFI_Callback); RNWF_WIFI_SrvCtrl(RNWF_SET_WIFI_PARAMS, &wifi_sta_cfg); /* RNWF Application Callback register */ RNWF_OTA_SrvCtrl(RNWF_OTA_SET_CALLBACK, (void *)APP_OTA_Callback); while(1) { RNWF_EVENT_Handler(); } }