1. 概述
本文介绍在 ING918xx 上移植、实现一种客户私有 OTA Service 过程。INGCHIPS OTA Service 的开发和演示请参考 空中固件升级(FOTA)的快速演示。
2. ING918xx OTA 实现方式
- 下载新的程序(下图中的 Application 2)到 Flash 的空闲区域。
- 提供新程序的启动地址
- 重启,BootLoader 会自动搬移并完成更新
3. 实现细节
创建新文件 ota_private_service.c。
3.1 准备状态记录信息结构体
// 包含必须的头文件 #include <stdio.h> #include <stdint.h> #include <string.h> #include "ingsoc.h" #include "platform_api.h" #include "rom_tools.h" #include "eflash.h" #include "ota_service.h" |
// 创建状态记录信息结构体
#define PAGE_SIZE (8192)//static size for one flash page
typedef enum
{
OTA_SERVICE_DISABLED = 0,
OTA_SERVICE_START = (1 << 0),
OTA_SERVICE_END = (1 << 1)
} ota_service_flag_e;
typedef struct
{
ota_ver_t ota_ver;//place to save app version
ota_service_flag_e ota_service_flag;//start/end
// static data from controller
uint32_t ota_load_addr;//load address of new app
uint32_t ota_flash_base_addr;//flash address to save ota data
uint32_t ota_file_size;//total size of new app bin
// dynamic variables to hold downloading progess
uint32_t ota_curr_page_addr;
uint32_t ota_curr_page_size;
uint8_t page_buffer[PAGE_SIZE];
uint32_t ota_total_size;//size that has been program to flash
} ota_service_data_s;
ota_service_data_s ota_service_data =
{
.ota_service_flag = OTA_SERVICE_DISABLED,
.ota_ver = { .app = {.major = 0, .minor = 0, .patch = 0} },
.ota_curr_page_addr = 0,
.ota_total_size = 0
};
|
3.2 创建初始化接口
在开始下载之前,有三个信息需要提供:
- load addr:新程序的启动地址。
- flash addr:重启之前,用来放置新程序的 Flash 基地址。
- file size: 新程序的大小。
|
接口返回为0, 代表初始化失败。
3.3 创建初始化接口
准备 OTA 数据的下载接口:
|
|
|
3.4 创建重启接口
|
4. 实现细节
调用流程如下:
-
在profile.c中找到以下 API,以及确定 OTA 使用到的 handle(eg. HANDLE_OF_OTA_DATA)
static int att_write_callback(……) { switch (att_handle) { case HANDLE_OF_OTA_DATA: // add your ota code return 0; default: return 1; } }
-
主设备发送 start cmd,启动 OTA,并传递相关信息(load_addr, flash_addr, file_size)
case HANDLE_OF_DATA: ... if(start cmd) { ret = ota_service_init(load_addr, flash_addr, file_size); //check ret } return 0;
-
主设备发送 data cmd,开始 OTA 下载
case HANDLE_OF_DATA: ... if(data cmd) { ret &= ota_service_handle(buffer, buffer_size); //check ret } return 0;
-
主设备发送 reboot cmd,重启设备,完成 OTA 下载
case HANDLE_OF_DATA: ... if(reboot cmd) && (ret == 1) { ota_service_reboot(); } return 0;
5. 可能的问题
- 下载程序没有添加应用层的校验,视情况可以自行实现,比如CRC。
- 没有验证功能(将下载后的程序读取到主设备,对比验证),读取部分可以用memcpy实现,可以根据情况自行添加。