跳转至

Apus OTA*

GX830X芯片支持通过蓝牙升级固件,区别于硬件连接升级,OTA升级方案基于双app分区切换的升级机制,升级内容为app.bin。即使升级过程有异常,机器重新上电后仍能正常工作。

1. apus OTA例程*

1. flash 固件存放配置*

依据芯片内置或者外挂flash大小不同,固件存放配置也不一样,下面以512KB flash为例

512K flash:

Zone Addr Length
bootloader 0x0 ~ 0x0fff 0x1000(4KB)
bootenv 0x1000 ~ 0x1fff 0x1000(4KB)
app bank A 0x2000 ~ 0x3FFFF 0x3E000(248KB)
app bank B 0x40000 ~ 0x7DFFF 0x3E000(248KB)
kv env 0x7E000 ~ 0x7FFFF 0x2000(8KB)
  • bootloader: 启动代码
  • bootenv: app bank信息;可扩展OEM信息:

    typedef struct {
        unsigned int tag;
        unsigned int version;
        unsigned int app_bank_a_addr;
        unsigned int app_bank_b_addr;
    
        unsigned int reserved[12];
    
        // offset 64 bytes
        boot_env_oem_t oem_data;
    }boot_env_t;
    
  • app bank A/B: 可更新的app bin, 包含64字节的app header:

    typedef struct
    {
        unsigned int hdr_magic;        /* bin header magic: "ABIN" */
        unsigned int hdr_version;      /* image header version */
        unsigned int hdr_buildtime;    /* bin creation timestamp */
    
        unsigned int bin_payload_size;        /* bin size exclude header */
        unsigned int bin_payload_crc;    /* bin crc exclude header*/
    
        unsigned int bin_jump_entry;       /* jump entry */
    
        unsigned int bin_load_offset;     /*  offset of flash bank*/
        unsigned int bin_load_size;        /* load size */
        unsigned int bin_load_addr;        /* load address of ram */
    
        unsigned int bin_boot_ver;          /* higher version means activate app*/
    
        unsigned int reserved[3];     /* reserved */
    
        unsigned int dfu_flag : 1;
        unsigned int kvs_env_bank : 3;    /* kvs env bank num, 4KB per bank */
        unsigned int flash_size : 21;    /* main flash size; KB */
    
        unsigned int active_app_bank;    /* write by boot*/
    
        unsigned int hdr_crc;         /* header crc */
    
        unsigned char bin_payload[0];    /*bin payload content*/
    }app_bin_hdr_t;
    
  • kv env: key-value存储区域

2. 上电固件加载过程*

  • ROM代码(固化在芯片中)将flash中的bootloader加载到sram并运行
  • bootloader固定从flash 0x1000的位置读取bootenv信息
  • 根据bootenv app bank信息,分别读取app bank A/B的app bin header并校验
  • 如果app bank A/B均有合法的app bin,则加载bin_boot_ver版本较高的app并运行(OTA升级的时候会将旧app的bin_boot_ver置0,将新app的bin_boot_ver置1,确保下一次启动加载的是新app)

3. OTA 启用方式*

在app目录下的config/sdk_config.h中配置:

#define CONFIG_USING_DFU    (1)

4. OTA API*

详见: subsys/dfu/dfu.h

开始升级*

int dfu_upgrade(dfu_fmw_stream_ops_t *fmw_stream_ops, dfu_event_cb event_cb, unsigned int timeout_ms)
  • fmw_stream_ops: 固件数据读取接口
  • event_cb: 事件回调
  • timeout_ms: 固件读取超时时间

退出升级*

int dfu_upgrade_cancel(void)

OTA参考app例子*

可参考apps/dfu_sample/apps/ble_remote_control/app_ota/

5. Apus OTA传输协议*

用于Apus方案OTA主机和从机交互过程

ble数据通道*

  • 从机实现指定gatt service,包含用于接收数据的可写characteristic RX,以及用于发送数据的notify characteristic TX
  • 主机访问该gatt service,通过写characteristic RX实现数据发送,通过订阅characteristic TX实现数据接收
  • Apus Demo Service实例:
  • service UUID: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
  • RX characteristic UUID: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
  • TX characteristic UUID: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E

协议帧*

addr code data checksum
0xFF 1 byte n bytes 2 bytes
  • 数据域均为小端格式

OTA协议*

开始升级*
  • code: 0x64
  • data:
  • 主机: 16字节; 其中:
    • byte0: 控制字,当前默认0x01
    • byte1 ~ 2(2字节): 传输固件时每包数据长度N,N=16*n(n: 1~256)
    • byte3 ~ 15(13字节): 保留
  • 从机: 1字节; status code

对于ble,主机根据ATT MTU确定固件数据包长度N

传输固件*
  • code: 0x68
  • data:
  • 主机: N字节固件数据,N由"开始升级"命令指定
从机上报状态*
  • code: 0x70
  • data:
  • 从机: 1字节,status code
状态码*
status
0x00 ok
0x01 接收固件header成功
0x02 写chunk成功
0x03 升级成功
0x80 error
0x81 超时
0x82 系统忙
0x83 数据长度错误
0x84 数据校验错误
0x84 flash错误

6. OTA升级过程*

  1. apus启动广播,以ble_remote_control这个app为例,如下通过串口shell命令输入"ble_pair"即可开启广播 注意:如果要通过串口shell命令开启广播,需要同步使能下面的配置:

        #define CONFIG_USING_COMMAND_LINE   (1)
    

  2. 主机使用apus OTA工具连接上apus的蓝牙即可开始OTA,OTA工具使用说明见 2.上位机OTA例程

  3. 主机发送"开始升级"命令,并在协议帧data中指定传输固件的数据包长度,该长度为16的整数倍,最大4096
  4. 从机收到升级命令,如满足升级条件,则回复status 0,并确定当前的backup bank用于下载新app固件,即非当前活动的app bank,准备接收固件数据;否则回复对应状态码,结束升级.
  5. 主机发送64字节固件header,根据数据包长度N,可能分为多包传输
  6. 从机接收完64字节固件header,检查ok则上报"接收固件header成功"状态,并继续接收固件payload;否则回复对应异常状态,结束升级擦除backup bank
  7. 主机发送固件payload chunk,每个chunk长度为4096,可分为多包传输
  8. 从机每接收到4096字节数据,则写入backup bank一次,成功上报"写chunk成功"状态;否则回复对应状态码,结束升级
  9. 重复过程7.8,直至完整固件传输完成并写入flash
  10. 从机校验写入flash的完整固件,更新固件的header,将新app固件的header写入backup bank头部,同时更新旧固件的header,将bin_boot_ver置为0,校验没问题则上报"升级成功"状态并执行reboot;否则回复对应异常状态,结束升级

2. 上位机OTA例程*

安卓apus OTA工具gxble下载地址: http://yun.nationalchip.com:10000/l/bFlmMa

安卓apus OTA工具gxble源码下载地址: http://yun.nationalchip.com:10000/l/eFDUnM

工具使用说明: