Skip to content

AliOS Things OTA Porting Guide

lyq0717 edited this page Oct 9, 2018 · 15 revisions

1 背景

OTA升级作为物联网设备的一项基础功能,可以快速修复软件漏洞,更新系统,对于快速迭代的物联网产品是刚性需求;目前IOT设备种类繁多,但并未提供统一的OTA升级方案,针对日益发展的IOT设备,开发者迫切需要一套云端一体化的OTA升级方案来满足快速迭代的产品开发周期,同时降低产品开发和部署的成本。

2 目标

对于接入AliOS Things的物联网设备,阿里巴巴云端和设备端OTA组件为用户提供云端一体化的OTA升级服务; 对于使用OTA升级服务的用户只需按照此文档实现移植层接口后就可以轻松使用阿里巴巴物联网OTA升级服务。

3 使用对象

使用AliOS Things 的开发者或用户,代码路径:https://github.com/alibaba/AliOS-Things.git 分支:rel_2.0.0

4 移植使用说明

AliOS Things OTA设备端软件架构如下图所示,OTA核心组件为通用组件,设备端OTA整体功能移植到不同的平台和操作系统,需分别实现如图标注为粉色的底层平台接口移植层操作系统接口移植层,AliOS Things操作系统移植接口已完成对接,因此使用时无需移植,新芯片或者模组导入只需简单实现底层平台移植层接口(5个回调函数接口)就可以正常使用AliOS Things云端一体化的OTA服务。差分升级需要配合修改boot移植差分还原模块,目前只在平台8266和3080平台上面支持。

image.png | left | 747x481

5 移植接口详细说明

5.1 启动服务接口

在设备连接上阿里云之后,可以通过调用ota_service_init(NULL)接口启动OTA服务,默认接口参数为空,将使用系统默认烧录的四元组,也可以手动传入四元组等参数启动,默认传输协议支持MQTT,固件下载协议支持HTTPs。

typedef struct {
    int   inited;  /*If is inted*/
    char  pk[PRODUCT_KEY_MAXLEN + 1];/*Product Key*/
    char  ps[PRODUCT_SECRET_MAXLEN + 1];/*Product secret*/
    char  dn[DEVICE_NAME_MAXLEN + 1];/*Device name*/
    char  ds[DEVICE_SECRET_MAXLEN + 1];/*Device secret*/
    char  uuid[64];
    int   trans_protcol;  /*default:0--> MQTT 1-->COAP*/
    int   dl_protcol;     /*default:3--> HTTPS 1-->COAP 2-->HTTP*/
    int   sign_type;      /*default:0--> sha256 1--> md5 2-->RSA*/
    int   firm_size;
    char* dl_url;         /*Dowdload URL*/
    void* h_coap;
} ota_service_manager;

int ota_service_init(ota_service_manager* context);

5.2 底层平台移植层接口

OTA回调函数的实现代码位于platform/mcu/xxx/hal/ota_port.c,init实现初始化OTA分区及分区固件大小检查擦除,ota_write实现对下载数据解释后分段写入OTA分区中,ota_read完成从flash读出数据,ota_set_boot用于升级成功时告诉boot下次启动到新升级的分区, ota_rollback用于乒乓升级升级时与bootloader共同完成回滚到老的分区,在平台初始化的时候会调用hal_ota_register_module(&ota_hal_module)注册上述回调接口。

struct hal_ota_module_s {
    hal_module_base_t base;

    /* Link to HW */
    int (*init)(hal_ota_module_t *m, void *something);
    int (*ota_write)(hal_ota_module_t *m, volatile uint32_t *off_set,
                     uint8_t *in_buf , uint32_t in_buf_len);
    int (*ota_read)(hal_ota_module_t *m,  volatile uint32_t *off_set,
                    uint8_t *out_buf , uint32_t out_buf_len);
    int (*ota_set_boot)(hal_ota_module_t *m, void *something);
    int (*ota_rollback)(hal_ota_module_t *m, void *something);
};

init

函数原型 int (*init)(hal_ota_module_t *m, void *something);
描述 实现初始化OTA分区及分区固件大小检查擦。

入参

参数
类型
描述
备注
m
hal_ota_module_t *
hal_module_base_t 结构体句柄
something
void *
传递初始化参数如偏移实现断点续传

返回值

描述
0
初始化成功
-1
初始化失败

ota_write

函数原型 int (*ota_write)(hal_ota_module_t *m, volatile uint32_t *off_set, uint8_t *in_buf , uint32_t in_buf_len);
描述 写入固件到flash

入参

参数
类型
描述
备注
m
hal_ota_module_t *
hal_module_base_t 结构体句柄
off_set
volatile uint32_t *
指定flash地址的偏移量(offset)
in_buf
uint8_t *
需要写入的数据
in_buf_len
uint32_t
需要写入的数据长度

返回值

描述
0
写入数据成功
-1
写入数据失败

ota_read

函数原型 int (*ota_read)(hal_ota_module_t *m, volatile uint32_t *off_set,uint8_t *out_buf , uint32_t out_buf_len);
描述 从flash中读取数据到buffer中

入参

参数
类型
描述
备注
m
hal_ota_module_t *
hal_module_base_t 结构体句柄
off_set
volatile uint32_t *
指定flash地址的偏移量(offset)
out_buf
uint8_t *
读取flash数据到该buf中
out_buf_len
uint32_t
需要读取的数据长度

返回值

描述
0
读取数据成功
-1
读取数据失败

ota_set_boot

函数原型 int (*ota_set_boot)(hal_ota_module_t *m, void *something);
描述 设置启动参数

入参

参数
类型
描述
备注
m
hal_ota_module_t *
hal_module_base_t 结构体句柄
something
void *
升级完成传递给boot的参数
参数请参考下面的说明

升级完成参数

typedef struct  {
    OTA_ENUM_UPDATE_TYPE update_type;
    OTA_ENUM_RESULT_TYPE result_type;
    OTA_ENUM_FIRMWARE_TYPE  firmware_type;
    uint32_t splict_size;
    uint8_t diff_version;
    uint8_t rollback;
} ota_finish_param_t;

详细说明:

update_type
OTA_KERNEL
更新内核
OTA_APP
更新app
OTA_ALL
更新内核和app
result_type
OTA_FINISH
更新完成
OTA_BREAKPOINT
更新中断
firmware_type
OTA_RAW
升级原始整包固件
OTA_DIFF
升级差分包固件
splict_size
差分升级分片大小
diff_version
差分升级版本标识
rollback
预留支持回滚标识

返回值

描述
0
设置成功
-1
设置失败

ota_rollback

函数原型 int (*ota_rollback)(hal_ota_module_t *m, void *something);;
描述 配合boot实现升级失败启动计数回滚到老的版本

入参

参数
类型
描述
备注
m
hal_ota_module_t *
hal_module_base_t 结构体句柄
something
void *
实现回滚参数如启动计数参数

6 OTA移植demo

以linux host上demo为例子,移植实现上述底层平台移植接口(以读写文件模拟读写存储设备)后,可通过在linux host上demo验证OTA下载通道逻辑,更详细的参见AliOS Things OTA用户使用说明文档。 1) 按照AliOS Things wiki文档按装好集成编译工具,并下载好源码 2) 在编译AliOS Things OTA Linux host  Demo程序      aos make clean;      aos make otaapp@linuxhost 3) Linuxhost下运行OTA Demo程序,确保PC正常联网并获取到IP地址     ./otaapp@linuxhost.elf

image | left | 706x90

4)从云端创建产品,获取产品信息pk,dn,ds, ps,执行命令行运行     OTA_APP "a16UKrlKekO" "gateway_test01" "AT2XFOPOIbJaKfXsKeaEhabJ8TLhMQYp" "RDluqbn3LQazrdqM"

image | left | 706x145

如上图打印显示对应的ota设备pk,dn注册OTA服务成功(注意确保设备信息PK,DN等正确):

5)通过云端界面选择验证固件,点击确认后可以看到设备端OTA升级开始:

image | left | 644x586

image | left | 726x142

升级完成,在Linux host下会将文件写入到当前目录的文件名字为alinkapp@linuxhost.elf文件中。

image | left | 726x96

  1. Linuxhost上验证完下载通道后可以编译运行对应设备端目标平台固件验证:    aos make otaapp@mk3060 烧录固件到对应设备平台后,运行和执行下载方式通linuxhost,区别在于平台移植接口的实现与对应平台存储接口对接,将对应固件更新写入对应的存储设备,并让更新设备正常启动。
Clone this wiki locally