LV01-01-AliOSThings-08-OTA

本文主要是OTA功能功能的分析与体验的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu22.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
点击查看本文参考资料
分类 网址 说明
官方网站 阿里云 阿里云官网主页
阿里生活物联平台 生活物联网平台(飞燕平台)主页
AliGenie 天猫精灵开放平台AliGenie主页
阿里物联网平台 阿里物联网平台主页
Bluetooth 技术网站 蓝牙协议规范什么的可以来这里找
Telink Telink | Chips for a Smarter IoT (telink-semi.com)
Telink中文官网
开发手册 AliOS Things开发指南 AliOS Things开发指南,这里是最新版本,可以直接从官网找到
AliOS Things开发指南 AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档
AliOS Things开发指南(3.0) AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档
生活物联网平台开发文档 生活物联网平台(飞燕平台)开发文档
《设备端开发指南》
Wi-Fi IoT品类定义与功能开发 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发
硬件平台 mk3080 WiFi开发板 WiFi开发板使用指南-阿里云开发者社区
esp8266开发板 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com)
TLSR8258 Datasheet Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258
参考资料 AliOS Things 3.0 应用开发指南 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考
IP知识百科 - 华为 (huawei.com) IP的一些相关知识点
点击查看相关文件下载
分类 网址 说明
蓝牙规范相关文档 Core Specification 5.2 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。
《Core_v5.2.pdf》
Mesh Model(v1.1) 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。
本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。
《MshMDL_v1.1.pdf》
Mesh Profile(v1.0.1) 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。
《MshPRFv1.0.1.pdf》
Mesh Device Properties 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。
但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》
GATT Specification Supplement GATT Specification Supplement | Bluetooth® Technology Website。
好像可以在线看:《GATT Specification Supplement》
Assigned Numbers GATT的一些类型定义可以在这里找。
AliOS Things alios-things/AliOS-Things Gitee上的AliOSThings SDK源码仓库
alibaba/AliOS-Things GitHub上的AliOSThings SDK源码仓库
天猫精灵蓝牙Mesh协议栈 alibaba-archive/genie-bt-mesh-stack GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。
之前是在alibaba/genie-bt-mesh-stack这个仓库。
写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a
蓝牙Mesh设备开发指南 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容

一、OTA简介

OTA(Over-The-Air)移动终端的空中下载软件升级,指通过云端升级技术,为具有连网功能的设备:例如手机、平板电脑、便携式媒体播放器、移动互联网设备等提供固件升级服务,用户使用网络以按需、易扩展的方式获取智能终端系统升级包,并通过FOTA进行云端升级,完成系统修复和优化。

timg (1)

二、mk3080-OTA原理

1. mk3080 flash分区

我们来看一下mk3080的flash分区情况:

image-20200708165718169

为什么会有这么多的分区?

对于mk3080来说,上面的那些bin文件都是存在于硬件的外部flash中。mk3080使用的芯片是rtl8710bn,芯片厂商在芯片出厂的时候,厂商已经在芯片上固化了一部分的程序,这部分程序包括厂商自己的bootloader(据我的理解,应该是做芯片启动和程序烧录的那部分代码,因为厂商不可能做一款芯片,不给下载程序的功能吧)和厂商自己的一些system程序(具体的不清楚,没有了解过,只知道与厂商的系统相关)。

然后AliOS-Things在厂商给的这个芯片上做二次开发,AliOS-Things想要做OTA功能,实现在线升级程序,厂商自己的bootloader又是不开源的,没法修改,那怎么办?只能在上层自己再实现一个自己的带有OTA功能的bootloader喽。这就是之前我们编译出来的文件中有一个image2_2ndboot.bin的原因啦。

image-20231117073546487

所以现在的基本的运行情况是怎样的?首先,芯片上电,开始运行厂商自己的boot_all.bin,然后运行system.bin的部分,再跳转到image2_2ndboot.bin运行,最后是image2app(while循环中不断打印helloworld)程序的运行。最后的image2App_ota其实就是OTA升级的新的功能应用程序,那么怎么进入这个ota的应用程序?正常就是直接运行自己的image2app,所以这个时候就需要image2_2ndboot.bin啦,当我们接收完oat应用程序后,把它存放在image2App_ota这个区域,然后会有一个标志位,重启设备的时候2ndboot就会根据这个标志直接跳转image2App_ota执行。(总觉得怪怪的,按照我自己的理解,这里应该是开机进入2ndboot,这个2ndboot实现ota程序的接收和写入功能,直接将ota升级的程序写入到原来的应用程序处,因为升级ota程序后,下次重启,程序直接是ota程序了,而不再是原来的程序,所以我不是很理解课程中老师为什么多加了个image2App_ota,后面确定了再更新这里吧)。

怎么知道是这样分区的?

主要是从一个makefile配置文件中分析得到的,我们可以看一下AliOS-Things源码目录中的 platform/mcu/rtl8710bn/gen_inage_bin.mk 这个文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 上面部分省略......
#bootloader
BOOT_BIN_FILE := $(OUTPUT_DIR)/binary/boot_all.bin ## 指定了boot_all.bin输出路径
BOOT_OFFSET := 0x0 ## 偏移地址 基于flash基地址 偏移多少

#application
SYSTEM_BIN_FILE := $(SYSTEMBIN_DIR)/system.bin ## system.bin输出路径
SYSTEM_OFFSET:= 0x9000 ## 偏移地址 基于flash基地址 偏移0x9000

#2ndboot
2NDBOOT_BIN_FILE :=$(OUTPUT_DIR)/binary/image2_2ndboot.bin ## 2ndboot.bin输出路径
2NDBOOT_OFFSET:= 0xB000 ## 偏移地址 基于flash基地址 偏移0xB000

#ate firmware
ATE_BIN_FILE := $(AMEBAZ_DIR)/ate.bin #ate firmware 这个是厂商的 是基于AT执行的代码
ATE_OFFSET:= 0xD0000

#app
APP_BIN_FILE := $(OUTPUT_DIR)/binary/image2_app.bin ## image2_app.bin输出路径 helloworld 实现的.bin文件
APP_OFFSET := 0x19000 ## 偏移地址 基于flash基地址 偏移0x19000

# 下面部分省略......

2. 链接脚本

在最后一步进行程序链接的时候会用到链接脚本,mk3080的相关链接脚本是什么?其实这个可以从编译打印信息中看出,但是默认的打印信息

都是简化了的,写这篇笔记的时候还没有详细去研究,那我们直接找吧。这个链接脚本在两个地方有:

1
2
3
4
5
# 1. mk3080的工程目录
helloworld_mk3080/board/mk3080/ld

# 2. AliOS-Things源码目录
AliOS-Things-SDK/platform/board/mk3080/ld/

它们都有以下四个文件:

1
2
3
4
5
6
7
8
hk@vm:~/6AliOS/helloworld_mk3080/board/mk3080/ld$ tree
.
├── rlx8711B-symbol-v02-img2-2ndboot.ld # aos 二次引导程序的链接脚本
├── rlx8711B-symbol-v02-img2.ld # 厂商bin文件的链接脚本
├── rlx8711B-symbol-v02-img2_xip1.ld # aos app链接脚本
└── rlx8711B-symbol-v02-img2_xip2.ld # aos app_ota的链接脚本

0 directories, 4 files
image-20231118092758542

后面两个ld链接脚本就是我们的应用程序所用到的链接脚本,xip是表示程序放在外部flash。我们来看一下rlx8711B-symbol-v02-img2_xip1.ld中都有什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ENTRY(Reset_Handler)

INCLUDE "script/export-rom_symbol_v01.txt"

GROUP (
libgcc.a
libc.a
libg.a
libm.a
libnosys.a
)

MEMORY
{
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 /* ROM: 512k */
ROMBSS_RAM (rw) : ORIGIN = 0x10000000, LENGTH = 0x2000 /* ROM BSS RAM: 8K */
BOOTLOADER_RAM (rwx) : ORIGIN = 0x10002000, LENGTH = 0x3000 /* BOOT Loader RAM: 12K */
BD_RAM (rwx) : ORIGIN = 0x10005000, LENGTH = 0x38000 /* MAIN RAM: 228 */
ROM_BSS_RAM (rwx) : ORIGIN = 0x1003D000, LENGTH = 0x1000 /* ROM BSS RAM: 4K */
MSP_RAM (wx) : ORIGIN = 0x1003E000, LENGTH = 0x1000 /* MSP RAM: 4k */
RDP_RAM (wx) : ORIGIN = 0x1003F000, LENGTH = 0xFF0 /* RDP RAM: 4k-0x10 */

XIPBOOT (rx) : ORIGIN = 0x08000000+0x20, LENGTH = 0x04000-0x20 /* XIPBOOT: 32k, 32 Bytes resvd for header*/
XIPSYS (r) : ORIGIN = 0x08009000, LENGTH = 0x1000 /* XIPSYS: 4K system data in flash */
XIPCAL (r) : ORIGIN = 0x0800A000, LENGTH = 0x1000 /* XIPCAL: 4K calibration data in flash */
XIP1 (rx) : ORIGIN = 0x08019000+0x20, LENGTH = 0xE2000-0x20 /* XIP1: 904k, 32 Bytes resvd for header */
}

PROVIDE(app_download_addr = 0xffffffff);
PROVIDE(kernel_download_addr = 0x8100000);

这里是截取了一小部分,链接脚本是有自己的语法的,前面学习单片机的时候起始都了解过,这里不再详细说了,我们看最后一个XIP1这一行,看到这个19000,会发现它与makefile文件中 APP_OFFSET 偏移地址是一致的,那么前面还有个 0x08000000 是为什么?这是因为rtl8710bn 内核为ARM cortex -M4 外部挂载flash映射到CPU地址 0x8000000开始。

三、esp8266-OTA原理

1. esp8266 flash分区

我们来看一下esp8266的flash分区情况:

image-20200708164623382

分区说明

可以看到esp8266的flash一共分为两个区域,分区1和分区2,在分区1前面有一个Boot信息,这个boot信息来决定是执行分区1的user1.bin程序还是分区2的user2.bin程序。就比如说,user1.bin就是我们的app程序,user2.bin就是我们的ota程序,那么开机的时候执行哪个,就是由boot来决定。在esp8266 flash的最后部分区域,有wifi参数的、系统参数的一些分区,所以其实esp8266其实已经把flash区域的划分给定死了,这也就导致了AliOS-Things没有办法去实现像mk3080一样的一个2nd_boot,esp8266的boot就完全由芯片厂商自己决定,并且还不开源,但是芯片厂商会提供给我们,所以前面烧录esp8266的helloworld程序的话,我们使用软件烧录了两个程序,一个是boot,一个是我们的helloworld应用程序。其实这里我还是有些不理解,但是由于学习的主要是mk3080,所以这里先这样,后边有机会再补充吧。

怎么知道是这样分区的?

那上面的分区为什么是那样?我们怎么知道的?我们可以看一下esp8266的链接脚本。

2. 链接脚本

和mk3080一样,都有两个地方有链接文件,它们其实是一样的,我们看一下工程目录下的链接文件:

1
2
3
4
5
6
7
8
9
hk@vm:~/6AliOS/helloworld_esp8266/board/esp8266/ld$ tree
.
├── eagle.app.v6.common.ld # 链接脚本的公共文件
├── eagle.app.v6.new.1024.app1.ld # app链接脚本
├── eagle.app.v6.new.1024.app2.ld # app_ota 链接脚本
├── eagle.app.v6.new_8285.1024.app1.ld
└── eagle.rom.addr.v6.ld

0 directories, 5 files
image-20231118094737636

我们来看一下这个 eagle.app.v6.new.1024.app1.ld文件:

image-20231118094913582

在这个链接脚本开始的时候为我们画出了flash分区情况,着一股脑其实我们就可以理解为什么前面烧写的时候,文件后面的地址为什么是0x0000,为什么是0x1000了。

image-20231118095051408

四、在mk3080上体验OTA

我这里只有mk3080的开发板,这里用这个开发板来体验吧。

1. 修改工程源码

我们先修改 工程目录下的 helloworld_mk3080/appdemo.c文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "aos/init.h"
#include "board.h"
#include <k_api.h>

int application_start(int argc, char *argv[])
{
int count = 0;

printf("nano entry here!\r\n");

//fd = board_lcd_create("name");
//board_lcd_write(fd,buffer,len);

while(1) {
printf("hello ssq! count %d \r\n", count++);

aos_msleep(2000);
};
}

然后通过下面的命令编译程序:

1
aos make

编译完成后我们会得到下面这些文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
hk@vm:~/6AliOS/helloworld_mk3080/out/helloworld_mk3080@mk3080/binary$ ll
总用量 5404
drwxrwxr-x 2 hk hk 4096 11月 18 09:55 ./
drwxrwxr-x 8 hk hk 4096 11月 18 09:23 ../
-rw-rw-r-- 1 hk hk 4496 11月 18 09:55 boot_all.bin
-rw-rw-r-- 1 hk hk 1077968 11月 18 09:55 helloworld_mk3080@mk3080.bin
-rwxrwxr-x 1 hk hk 1388828 11月 18 09:55 helloworld_mk3080@mk3080.elf*
-rw-rw-r-- 1 hk hk 162839 11月 18 09:55 helloworld_mk3080@mk3080.hex
-rw-rw-r-- 1 hk hk 2822462 11月 18 09:55 helloworld_mk3080@mk3080.map
-rw-rw-r-- 1 hk hk 1700 11月 18 09:55 helloworld_mk3080@mk3080_map.csv
-rw-rw-r-- 1 hk hk 57952 11月 18 09:55 helloworld_mk3080@mk3080_ota.bin
-rw-rw-r-- 1 hk hk 36304 11月 18 09:55 helloworld_mk3080@mk3080_ota.bin.xz
-rwxrwxr-x 1 hk hk 221364 11月 18 09:55 helloworld_mk3080@mk3080.stripped.elf*
-rwxrwxr-x 1 hk hk 17640 11月 18 09:55 image2_2ndboot.bin*
-rw-rw-r-- 1 hk hk 2078 11月 18 09:23 link.opts
-rw-rw-r-- 1 hk hk 277 11月 18 09:55 readme.txt

这一次我们要烧写ota程序,所以我们要用的就是这个 helloworld_mk3080@mk3080_ota.bin文件了,可以看到这个文件与helloworld_mk3080@mk3080.bin相比,小了很多,这是因为后者包含了boot,2nd_boot和app,而ota文件就只有app_ota啦。

2. 烧录工具与硬件配置

还记得之前烧录的时候我们需要用抓专门的烧录软件,硬件上也要配置一下进入烧写模式,但是这里我们烧写的是ota程序,可以不用前面的工具,我们直接通过串口升级,也就是后边要说的ymodem模式烧写,这样我们就只需要一个串口工具啦。

3. Ymodem协议烧写OTA程序

我们先来看一下开机的时候的提示信息:

image-20231118101103395

这里其实已经提醒我们了,我们按下w键就可以进入AliOS-Things的2nd_boot中,这个怎么按?就跟进电脑的bios一样,开机后迅速快按启动按键即可,只是这里我们在mk3080复位后,重新启动时要按下w,但是我们只有100ms的时间,所以我们直接长按,然后就会出现下面的打印信息:

image-20231118101400689

然后我我们就进入了一个命令行终端,前面会有 aos boot # 的提示,然后我们根据提示,按下1,也就是启动串口的Ymodem协议更新:

image-20231118101551086

然后会提示我们输入flash地址,看上面是有提示的,我们可以通过Ymodem协议将ota程序下载到os part或者OTA part,我们只需要输入后面的起始偏移地址就可以了,我们想要开机就运行新烧录的ota应用程序的话,我们就将它直接烧录到os part去,也就是输入0x19000即可:

image-20231118101855192

然后就会一直停在这里等待我们发送ota应用程序啦,怎么发送?我们在MobaXterm中【右键】→【Send file using Z-modem】→【选择ota程序】然后确认即可。注意:不是用的Ymodem嘛,是的,但是这只是一种传输协议,我也不是很清楚我用的MobaXterm中为什么没见这个Ymodem协议,只有一个Z-modem协议,但是我实际试了一下,Z-modem也是可以的,2nd_boot也是可以正常接收和解析的,具体它们有什么区别,暂时没有细细研究。

image-20231118102348347

传输完成后,会有以下提示:

image-20231118102755088

然后我们重启开发板,就可以看到如下打印信息:

image-20231118102855521

当然也可以使用SecureCRT,它是有Y-modem的:

image-20200630165512276