7.18. UPDATE

Overview

杰理提供了多种固件升级的方法,包括:SD卡升级,U盘升级,HTTP OTA升级和FTP OTA升级等用户可以根据实际需求进行选择。

升级方式

单备份升级

双备份升级

预留区升级

SD卡升级

支持

支持

支持

U盘升级

支持

支持

支持

HTTP升级

不支持

支持

支持

FTP升级

不支持

支持

支持

虚拟U盘升级

不支持

支持

支持

7.18.1. DEMO

工程demo

apps/demo/demo_DevKitBoard

示例

  • HTTP升级 : apps/common/example/update/http_upgrade/, 测试时需要在 apps/demo/demo_DevKitBoard/include/demo_config.h ,开启宏 USE_HTTP_UPDATE_DEMO1USE_HTTP_UPDATE_DEMO2

  • SD卡/U盘升级: apps/common/example/update/sd_udisk_upgrade/main.c, 测试时需要在 apps/demo/demo_DevKitBoard/include/demo_config.h ,开启宏 USE_SD_UPGRADE_DEMO

  • FTP升级 : apps/common/example/update/ftp_upgrade/main.c, 测试时需要在 apps/demo/demo_DevKitBoard/include/demo_config.h ,开启宏 USE_FTP_UPDATE_DEMO

  • 虚拟U盘升级:设备作为USB从机,并虚拟为一个假U盘,让电脑识别为U盘后,通过从电脑端拷贝升级文件到对应U盘中对设备进行升级。使用方法和配置如下:

使用方法
1、在app_config.h使用USB从机的读卡器功能和开启虚拟U盘升级相关配置。
- #define TCFG_PC_ENABLE                1     //使能USB从机功能
- #define TCFG_VIR_UDISK_ENABLE         1     //使能虚拟U盘功能
- #define TCFG_VIR_UPDATE_ENABLE        1     //使能虚拟U盘升级功能
- #define TCFG_USER_VIRTUAL_PLAY_ENABLE 0     //不使用虚拟 U 盘播放音频数据的功能时,可以关闭

2、在版籍board_xxx.c声明:extern const struct device_operations ram_disk_dev_ops;
3、在版籍board_xxx.c添加
在REGISTER_DEVICES(device_table) = {
        //数组中添加
{"vir_udisk",  &ram_disk_dev_ops, NULL},

4.烧录程序,将升级文件update-ota.ufw拷贝到虚拟U盘中对设备进行升级

注:wifi_story_machine 工程中已经加入了相关配置,如果其他工程需要此功能,按上述步骤进行添加

7.18.2. 双备份升级

双备份分区结构

升级流程

双备份存储结构有两个app code区域,当运行app code 0时,升级时将新固件写入app code 1区域, 反之亦然升级时对app code N区域数据校验成功后,更新启动标志,复位后即可运行app code N代码, 当升级中断或者新写入固件校验不成功,不会影响原来app code 的运行。

双备份升级特点

优点:

  • 升级流程在app_code运行时执行,可以不影响正常功能使用,容易做到无感升级

  • 升级意外中断仍有一份可运行代码,容灾体验好

  • 无需update loader参与升级,客户可灵活在APP层自定义升级协议格式

缺点:

  • 需要占用比固件大小接近多一倍flash空间

  • 升级流程与app_code同步运行,升级可能受运行环境影响

适用场合:

  • 对升级体验有要求的用户

  • 方案的flash空间充裕

  • 需要客制化升级协议格式

双备份配置

  • 使用双备份架构时,需要在 app_config.h 中进行如下配置:

#define  CONFIG_DOUBLE_BANK_ENABLE 1 //使能双备份功能

升级文件生成方法

  • OTA升级

    编译工程后,在tools目录下双击运行 生成升级固件.bat 批处理,等待一定时间后会弹出第二个窗口,在第二个窗口中选择升级方式,在窗口中输入2,然后回车。然后在 cpu\wl82\tools\upgrade 目录中会生成用于网络升级的 update-ota.ufw 文件

  • SD卡/U盘升级

    编译工程后,在tools目录下双击运行 生成升级固件.bat 批处理,等待一定时间后会弹出第二个窗口,在第二个窗口中选择升级方式,在窗口中输入1,然后回车。然后在 cpu\wl82\tools\upgrade 目录中会生成用于SD卡/U盘升级的 update.ufw 文件

Important

注意事项一:

用于OTA升级和SD卡/U盘升级必须使用对应的升级固件,否则会导致升级失败。同时需要注意的是,编译完工程后,需要点击对应的批处理文件来更新升级固件 ,否则有可能出现升级失败或升级的是旧的固件,可以通过固件的修改时间确认固件是否得到更新。

注意事项二:

BR22_TWS_VERSION 为固件版本号,即每次需要对设备进行升级时,需要将该值加1。初次烧录时该值为BR22_TWS_VERSION=0,需要对设备进行升级时,需要将该值加1,即此时 BR22_TWS_VERSION=1,然后编译生成升级固件对设备进行升级,以此类推,需要再次对设备升级的时,该值在原来的基础上进行递增1,因此多次升级后该值应该依次递增,0,1,2,3,…, 否则会遇到这样一个情况,设备进行OTA之后,再使用SM01-DFU.exe工具对设备烧录bin文件时,会出现设备运行的还是旧程序的情况,因为一些工具会利用到这个设置参数。 设置时请在对应 ``cpu/(wl80或wl82)/tools/isd_config_rule.c``文件下修改BR22_TWS_VERSION参数;

7.18.3. 单备份升级

单备份分区结构

升级流程

SDK加载otaloader程序到flash —>system reset—>uboot 检测升级状态,跳转到otaloader,运行otaloader程序,完成升级—> system reset—>uboot 检测升级状态,如果升级完成跳转到app,检测到之前没升级完成就继续跳转到otaloader进行升级;

单备份升级特点

优点:

  • 存储固件的flash容量仅需要一份固件的容量,节省flash空间

  • 单备份主要升级过程在update loader中实现,与sdk流程无关,相对稳定,单一线程升级速度相对较快

缺点:

  • update loader已编译二进制方式提供,客制化难度大,暂时无法支持二次开发

  • 单备份升级出现意外中断时,无法正常开机

  • 需在loader中等待重新升级成功方能开机使用,影响用户体验

适用场合:

  • flash空间紧张方案

  • 成本敏感客户

单备份配置

  • app_config.h 中进行如下配置:

#define  CONFIG_DOUBLE_BANK_ENABLE 0 //关闭双备份功能

升级文件生成方法

  • OTA升级

    单备份架构不支持OTA升级

  • SD卡/U盘升级

    编译工程后,在tools目录下双击运行 生成升级固件.bat 批处理,等待一定时间后会弹出第二个窗口,在第二个窗口中选择升级方式,在窗口中输入1,然后回车。然后在 cpu\wl82\tools\upgrade 目录中会生成用于SD卡/U盘升级的 update.ufw 文件

ota loader工程说明

单备份升级由loader来完成app code更新,地址为:”https://gitee.com/Jieli-Tech/fw-AC79_AIoT_SDK/tree/AC791N_OTA_loader/”;使用说明:

(1)打开wl82_ota_loader.cbp工程

(2)如果需要打开调试打印,需要进行如下配置:

  • 修改”cpu/wl82/tools/isd_config_rule.c”文件,配置打印串口:UTTX=PXXX(根据自己的串口进行配置)

  • 在wl82_ota_loader.cbp中也需要开启对应的配置,增加UART_DEBUG

(3)修改”uboot\apps\post_build\wl82\download.bat”文件,更改配置为set PROJECT_TYPE=sd_update2

(4)rebuild工程,编译完成后会在”uboot\apps\post_build\wl82”目录下生成ota.bin和sd_update2.bin文件,替换SDK工程tools目录下的这两文件。

7.18.4. 预留区升级

概述

资源文件先升级到备份区,数据校验成功后,在将其搬运到预留区,在搬运过程中断电可以在备份区进行恢复。但是如果升级的资源文件大小大于备份区域时 就不能通过备份区进行升级。这里可以提供强刷预留区的方式进行升级,即不通过备份区,直接将资源升级到对应的预留区中。但是缺点是升级过程中断电, 预留区资源数据会导致损坏。SD卡升级和U盘升级默认打开预留区强刷升级功能,即当备份区空间不够时,直接进行预留区强刷升级。HTTP OTA升级和FTP OTA 升级可以通过配置是否打开预留区强刷升级功能。开启支持强刷升级功能时,需要修改对应工程中的配置文件 lib_update_config.c, 设置 const int support_reserved_zone_forced_update = 1

Note

预留区升级适用于只需要更改预留区资源而无需升级整个固件的情况。需要注意的是使用预留区升级功能需要在 [RESERVED_CONFIG] 中配置预留区,在 [RESERVED_EXPAND_CONFIG] 中进行 配置的预留区时无法进行升级的。

SD卡/U盘升级配置

步骤一:配置cpu/wl82/tools/isd_config_rule.c文件,在[RESERVED_CONFIG]区域下设置可用于资源升级的预留区(如何配置预留区请查阅参考文档)
[RESERVED_CONFIG]
UPDATE_FILE=fixed_res/UPDATE; //其中UPDATE为升级文件
UPDATE_ADR=AUTO;
UPDATE_LEN=0x4000;
UPDATE_OPT=1;

步骤二:配置lib_update_config.c文件,使能预留区可升级功能。
设置const int support_reaserved_zone_file_dual_bank_update_en = 1;
设置const int support_passive_update_new_file_structure = 1;

步骤三:编译工程,烧写程序,此时在flash空间中会升级一个名为UPDATE的预留区

步骤四:当像升级UPDATE预留区时,如升级资源文件为UPDATE2,进行如下配置
UPDATE_FILE=fixed_res/UPDATE2; //其中UPDATE为升级文件
UPDATE_ADR=AUTO;
UPDATE_LEN=0x4000;
UPDATE_OPT=1;

步骤五:双击运行 ``升级文件.bat`` 批处理生成升级固件 update.ufw

注意:当下次升级不想对该预留区进行升级时,需要注释升级文件配置
[RESERVED_CONFIG]
#UPDATE_FILE=fixed_res/UPDATE; //其中UPDATE为升级文件
UPDATE_ADR=AUTO;
UPDATE_LEN=0x4000;
UPDATE_OPT=1;

HTTP/FTP升级配置

步骤一:配置download.c文件,配置-update_files参数,如:
        isd_download.exe isd_config.ini -tonorflash -dev wl82 -boot 0x1c02000 -div1 -wait 300 -uboot uboot.boot -app app.bin cfg_tool.bin -res %AUDIO_RES% %UI_RES% %CFG_FILE% -reboot 500 %KEY_FILE% -update_files normal
        其中,参数定义为:
        -update_files normal //生成只包含code升级文件
        -update_files embedded_only $(files) //生成只包含资源升级文件,其中$(files)为需要添加的资源文件
        -update_files embedded $(files) //生成包含code和资源的升级文件

步骤二:配置cpu/wl82/tools/isd_config_rule.c文件,在[RESERVED_CONFIG]区域下设置可用于资源升级的预留区
UPDATE_ADR=AUTO;
UPDATE_LEN=0x4000;
UPDATE_OPT=1;

步骤三:配置lib_update_config.c文件,使能预留区可升级功能。
设置const int support_reaserved_zone_file_dual_bank_update_en = 1;
设置const int support_passive_update_new_file_structure = 1;

步骤四:编译工程

步骤五:双击运行 ``升级文件-OTA.bat`` 生成升级文件 ``update-ota.ufw``

通过网络升级资源文件例子

示例说明:
        将test1.txt、test2.txt和test3.txt文件升级更新到UPDATE预留区,并读取test1.txt文件中的数据。

(1)利用文件cpu/$(cpu)/tools/packres目录下打包工具packres.exe,将这三个文件打包为UPDATE文件,如:
        packres.exe -n tone -o UPDATE test1.txt test2.txt test3.txt
        其中,参数定义为:
        -n,参数为需要把文件打包在那个文件目录下,目录名用于可以自定义。这里起名为tone目录名
        -o,输出的打包文件,名字用户可以自定义。注意:需要升级的打包文件名字需要和预留区名字保持一致。

(2)配置cpu/wl82/tools/isd_config_rule.c文件,在[RESERVED_CONFIG]区域下设置可用于资源升级的预留区
        UPDATE_ADR=AUTO;
        UPDATE_LEN=0x4000;//这里设置预留区大小为16k,需要注意的是用户要根据可能需要存储的最大资源上限进行设定,设定后升级的资源大小必须小于该值。
        UPDATE_OPT=1;

(3)设置好预留区后,需要烧写一次程序使得flash生成对应的预留区空间。

(4)配置download.c文件,这里采用只升级资源,其配置为:
        isd_download.exe isd_config.ini -tonorflash -dev wl82 -boot 0x1c02000 -div1 -wait 300 -uboot uboot.boot -app app.bin cfg_tool.bin -res %AUDIO_RES% %UI_RES% %CFG_FILE% -reboot 500 %KEY_FILE% -update_files embedded_only UPDATE

(5)编译工程

(6)双击运行“升级文件-OTA.bat” 批处理,生成升级文件 ``update-ota.ufw``

(7)升级成功后,打开test1.txt文件读取其中的数据,示例代码如下:
#include "system/includes.h"
#include "app_config.h"
#include "fs/fs.h"
static void fs_test_task(void *priv)
{
        int rlen = 0;

        FILE *f = fopen("mnt/sdfile/app/update/tone/test1.txt", "r");
        if(!f)
        {
                printf("fopen err \n");
                return;
        }

        rlen = flen(f);

        u8 *r_buf = (u8 *)malloc(rlen);

        int len = fread(r_buf, 1, rlen, f);
        if (len != rlen) {
                fclose(f);
                return;
        }

        printf("fread data : %s\n", r_buf);
        fclose(f);
        free(r_buf);
}

static void c_main_t(void *priv)
{
        if (thread_fork("fs_test", 10, 512, 0, NULL, fs_test_task, NULL) != OS_NO_ERR) {
        printf("thread fork fail\n");
        }
}

late_initcall(c_main_t);

7.18.5. 常见问题

(1) 预留区与res资源区有什么区别?

答:预留区位于reserved区域,由用户自行配置,一旦生成其在flash中的位置和大小不能改变。 res资源区位于app code区,在flash空间允许的范围内,res资源区大小没有限制。在双备份升级中, res资源区也会进行双备份处理,因此res资源在flash中会占用两倍的空间。而预留区作为资源区时, 升级时资源文件大小不能超过对应预留区的空间大小。

(2) 预留区备份升级与强刷升级有什么区别?

答:预留区备份升级时,借用app code备份区作为临时区(前提是备份区空间必须大于资源文件大小), 先将资源写入该区,等数据校验成功后,再将资源从备份区覆盖到预留区,这样当意外断电时,也可以从 备份区恢复到预留区。而强刷升级则是直接将资源覆盖到预留区,当意外断电时,原来的预留区资源会造 成损坏。因此当使能强刷功能时,建议用户把重要的资源放在res资源区,如:一些开机时使用到的资源。

(3)资源升级预留区的大小如何选取?

答:预留区设置后,其空间大小不能改变,因此用户一开始就必须评估好以后可能存放最大资源上限,超 出预留区空间的资源可以存放到res区域。

(4) 在usb下载或OTA升级时需要擦除或保留对应reserved区域,该如何设置?

答:需要修改 cpu/wl82/tools/isd_config_rule.c, 擦除对应区域时XX_OPT设置为0,不操作指定区域时XX_OPT设置为1。如:vm区默认配置VM_OPT=0,因此在 每次烧录程序或ota升级时都会清除掉改区域,需要保留原来的vm数据需要配置VM_OPT=1。

[RESERVED_CONFIG]
#升级之后需要保留VM数据,在生成升级文件时需要设置VM_OPT=1
VM_ADR=0;
VM_LEN=16K;
VM_OPT=1;

(5) 采用单备份升级时,显示“head crc err”和“not found ufw code file”这样的错误提示信息?

答:主要原因是配置错误造成的,需要根据单备份升级配置进行正确配置。

(6) 单备份和双备份可以交替使用吗?

答:不行

(7) 升级失败,如何确认具体原因?

答:CONFIG_RELEASE_ENABLE定义后会屏蔽一些log信息,因此需要去掉后才能看到具体报错原因。操作如下图:

(8) 双击“生成升级固件.bat”没反应、没有生成“upgrade”文件夹?

答:部分文件上传到Git,文件编码会被改成UINX,使用打包成压缩包的方式下载会导致运行异常。用 Notepad++ 打开 生成升级固件.bat ,转换文档格式后保存即可。(详情查看 下载压缩包,编译不成功