跳转至

基于 Air5101 的 Air780EHV OTA 远程升级方案

作者:王世豪 | 最后修改:2026-04-13

一、概述

本演示项目展示了 Air780EHV 核心板通过 Air5101 蓝牙模块实现固件远程升级(FOTA)的完整解决方案。项目采用蓝牙低功耗(BLE)通信方式,支持两种升级模式:文件写入方式和分段写入方式,为不同应用场景提供灵活的升级方案。

通过本演示,开发者可以学习如何:

  • 使用 Air5101 蓝牙模块进行 BLE 通信
  • 实现基于蓝牙的固件升级功能
  • 处理升级过程中的数据传输和状态管理
  • 选择适合自己项目的升级方式

二、演示功能概述

本 demo 演示的核心功能为:

Air780EHV 模块通过 Air5101 蓝牙模块进行固件远程升级(FOTA)的完整实现方案,支持两种升级方式:

1、文件写入方式:将接收到的升级包数据先保存到本地临时文件,完成数据接收后再执行升级

  • 优点:适合完整固件升级,逻辑清晰,易于调试
  • 缺点:需要额外的文件系统分区存储空间保存完整固件
  • 适用场景:存储空间充足的设备

2、分段写入方式:直接将接收到的升级包数据通过 fota.run()函数处理,无需保存到本地文件

  • 优点:节省存储空间,适合差分升级
  • 缺点:对内存要求较高,需要足够的内存缓冲区实时处理数据
  • 适用场景:存储空间有限的设备

适用场景:

  • 智能硬件、可穿戴设备等蓝牙连接设备的固件升级
  • 需要自定义升级流程的应用场景
  • 无网络环境下的设备固件更新
  • 使用 Air5101 蓝牙模块的嵌入式设备

三、准备硬件环境

3.1 Air780EHV 核心板

使用 Air780EHV 核心板,如下图所示:

此核心板的详细使用说明参考:硬件手册和证书 中的 Air780EHV 核心板使用说明

3.2 Air5101S 开发板

3.3 PC 电脑

WINDOWS 系统,其他暂无特别要求;

3.4 数据通信线

USB 数据线(其一端为 Type-C 接口,用于连接 Air780EHV 核心板)。

Air780EHV 核心板和数据线的硬件接线方式为:

  • Air780EHV 核心板通过 TYPE-C USB 口供电,核心板正面的 ON/OFF 拨动开关 拨到 ON 一端;
  • TYPE-C USB 数据线直接插到核心板的 TYPE-C USB 座子,另外一端连接电脑 USB 口;

3.5 接线说明

Air780EHV
Air5101S
UART1_TX
RXD
UART1_RX
TXD
GND
GND
3.3V
VBAT

四、准备软件环境

4.1 软件环境

  1. 烧录工具:Luatools 下载调试工具

  2. 内核固件:

本demo开发测试时使用的固件为Air780EHV V2032 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;

  1. 脚本文件: https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/fota/ble_fota_5101

  2. LuatOS 运行所需要的 lib 文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件。

准备好软件环境之后,接下来查看如何烧录项目文件到 Air780EHV 核心板中,将本篇文章中演示使用的项目文件烧录到 Air780EHV 核心板中。

五、API 接口说明

详细 API 文档请参考:

exril_5101 扩展库:https://docs.openluat.com/osapi/ext/exril_5101/

fota:https://docs.openluat.com/osapi/core/fota/

六、蓝牙 GATT 服务设计

6.1 服务与特征值定义

类型
UUID
属性
功能描述
Service
0000ff00-f7e3-55b4-6c4c-9fd140100a16
-
FOTA服务主UUID,用于标识升级服务
Characteristic
0000ff02-f7e3-55b4-6c4c-9fd140100a16
Write, Write Without Response
写入特征值,用于发送升级命令和数据

报文格式

由于 Air5101 只有一个可写入的特征值(0000ff02),所以协议采用分层设计,第一字节为数据类型,用于区分命令数据和固件数据:

  • 0x01: 命令数据
  • 0x02: 固件数据

6.1.1 命令报文格式

开始升级命令

命令码:0x01

格式[数据类型(1字节)] + [命令码(1字节)] + [文件大小(4字节)]

示例01 01 75 15 00 00 表示开始升级,固件大小为 5493 字节

说明

  • 数据类型固定为 0x01,表示命令数据
  • 命令码固定为 0x01,表示开始升级
  • 文件大小为 4 字节小端序
  • 设备收到此命令后,初始化 FOTA 子系统并准备接收数据

结束升级命令

命令码:0x02

格式[数据类型(1字节)] + [命令码(1字节)]

示例01 02

说明

  • 数据类型固定为 0x01,表示命令数据
  • 命令码固定为 0x02,表示结束升级
  • 设备收到此命令后,验证固件完整性并执行升级

6.1.2 数据报文格式

数据类型: 0x02

格式[数据类型(1字节)] + [固件数据(n字节)]

默认长度:500 字节(可通过 ble_5101_fota_tool.py 配置调整,最大 MTU-3 字节,MTU 最大是 512)

说明

  • 数据类型固定为 0x02,表示固件数据
  • 固件数据为二进制格式
  • 每包数据大小不超过 BLE 数据包最大长度:Air5101 模块硬件支持最大 509 字节
  • 设备收到数据后,根据所选的 FOTA 方式进行处理:

  • (1)文件方式:将数据写入临时文件

  • (2)分段方式:直接通过 fota.run()处理数据

6.2 升级流程说明

用法

1、先把脚本和固件烧录到 Air780EHV 模块中,并确认设备正常启动

2、模块启动后会自动初始化 Air5101 并开启 BLE 广播,广播名称为"Air5101_FOTA"

3、电脑端操作:运行 ble_5101_fota_tool.py 脚本连接设备并发送升级固件(注意:确保升级文件名为正确格式,并且与 ble_5101_fota_tool.py 在同一目录下)

4、观察日志输出确认升级进度

5、模块接收并验证固件成功后,会自动重启并应用新固件

BLE 通讯过程说明

蓝牙 FOTA 升级通过 Air5101 的 GATT 特征值进行命令控制、数据传输和状态通知:

协议流程:

  1. 上位机通过 BLE 扫描并连接名为"Air5101_FOTA"的设备
  2. 上位机向写入特征值(0000ff02)发送开始升级命令(0x01)和固件大小
  3. 设备初始化 FOTA 功能并准备接收数据
  4. 上位机向写入特征值(0000ff02)分包发送固件数据
  5. 设备接收并保存数据到临时文件或直接处理
  6. 上位机向写入特征值(0000ff02)发送结束升级命令(0x02)
  7. 设备验证固件完整性并执行 FOTA 升级流程
  8. 升级成功后设备自动重启

6.3 蓝牙 FOTA 升级工具使用流程

本项目提供两种上位机升级工具,可根据实际需求选择使用:

6.3.1 Python 脚本工具 (ble_5101_fota_tool.py)

功能特点:

  • 通过命令行操作,适合自动化脚本集成
  • 支持自定义设备名称和固件文件路径
  • 实时显示升级进度和传输速度

使用方法:

  1. 确保 Air5101 模块处于蓝牙广播状态(设备名称为"Air5101_FOTA")
  2. 在命令行中运行脚本,指定升级包文件名
python ble_5101_fota_tool.py -f 升级包文件名

参数说明:

  • -d--device - 指定目标设备名称(默认值为"Air5101_FOTA")

  • -f--firmware - 指定固件文件路径(必需参数)

工作流程:

  1. 加载指定的固件文件

  2. 扫描并发现蓝牙设备

  3. 连接到目标设备

  4. 发送开始升级命令(包含固件大小)

  5. 分包发送固件数据

  6. 发送结束升级命令

  7. 等待设备处理升级

  8. 断开连接并完成升级过程

界面说明:

6.3.2 Web网页工具 (ble_fota_web.html)

功能特点:

  • 基于Web Bluetooth API,无需安装Python环境

  • 可视化界面操作,支持拖拽选择固件文件

  • 实时显示升级进度和日志输出

浏览器要求:

  • 必须使用支持Web Bluetooth API的浏览器:Chrome、Edge或Opera

  • 不支持Safari和Firefox浏览器

  • 需要电脑具备蓝牙功能

使用方法:

  1. 使用Chrome或Edge浏览器打开ble_fota_web.html文件

  2. 确保Air5101模块处于蓝牙广播状态,设备名称为"Air5101_FOTA"

  3. 点击"扫描并连接设备"按钮,选择"Air5101_FOTA"设备进行连接

  4. 点击固件选择区域,选择要升级的升级包文件

  5. 根据需要调整数据包大小和发送间隔(默认500字节/50毫秒)

  6. 点击"开始升级"按钮,等待升级完成

界面说明:

七、代码示例介绍

7.1 主要代码分析

7.1.1 ble服务主功能模块(ble_5101_main.lua)

本文件为 Air5101 蓝牙服务主功能模块,整个应用通过 sys.taskInitEx 启动主任务,实现了完整的 Air5101 蓝牙模块控制功能,核心业务逻辑为:

1、初始化与配置

(1) 加载依赖模块

exril_5101 用于 Air5101 蓝牙模块的 AT 指令封装, ble_5101_file_fota 或 ble_5101_packet_fota 用于 FOTA 业务逻辑处理。

(2) 定义 FOTA 升级模式选择机制,支持两种升级方式:

-- 选择FOTA升级方式:"file" 或 "packet"
-- 1. file方式:将升级包数据先写入本地文件,然后调用fota.file()进行升级
-- 2. packet方式:直接使用fota.packet()处理分段数据,不写入文件,适合差分升级
local fota_mode = "packet" -- 默认使用packet方式

-- 根据选择动态加载对应的FOTA模块
if fota_mode == "file" then
    current_fota_handler = require "ble_5101_file_fota"
else
    current_fota_handler = require "ble_5101_packet_fota"
end

(3) 定义配置参数:

local config = {
    device_name = "Air5101_FOTA",  -- 设备广播名称
}

(4) 调用 exril_5101.mode() 进行模块模式切换,完成 Air5101 蓝牙模块的初始化配置流程:

  • 获取当前工作模式
  • 切换到 AT 指令模式进行参数配置
  • 设置设备名称等参数
  • 切换到透传模式(UA 模式)用于数据接收

2、事件处理

通过 ble_event_cb 回调函数处理各类 Air5101 蓝牙事件:

(1) 连接成功("connected") - 蓝牙设备连接建立

(2) 连接断开("disconnected") - 蓝牙连接断开

(3) 数据接收("data") - 收到中心设备发送的数据

(4) 错误事件("error") - 处理 AE 或 UE 错误码

(5) 系统事件("system") - 检测设备重启等系统级事件

3、业务功能

FOTA 升级流程控制 :

(1) 连接建立时通知 FOTA 模块: current_fota_handler.proc_connect()

(2) 连接断开时通知 FOTA 模块: current_fota_handler.proc_disconnect()

(3) 数据接收时转发给 FOTA 模块: current_fota_handler.proc(payload.data)

4、异常处理

(1) 初始化失败 :配置初始化失败后,5 秒后自动重试初始化流程。

(2) 设备重启检测 :通过系统事件检测到设备重启后,自动触发重新初始化。

(3) 消息队列清理 :异常发生时清理任务绑定的未处理消息,避免消息堆积。

(4) 连接异常恢复 :连接断开后自动等待重连,保持服务可用性。

7.1.2 文件系统方式 FOTA 升级业务逻辑模块(ble_5101_file_fota.lua)

本文件为 Air5101 蓝牙 FOTA 升级功能模块(文件写入方式),实现了通过 Air5101 接收升级包数据并写入文件进行固件升级的完整业务逻辑,核心业务逻辑为:

1、初始化与状态管理

(1) 定义升级状态管理结构,用于跟踪升级进度和文件操作:

local upgrade_state = {
    is_upgrading = false,          -- 是否正在升级
    total_size = 0,                -- 总文件大小(字节)
    received_size = 0,             -- 已接收大小(字节)
    upgrade_file = "/ble_fota.bin" -- 临时升级文件路径
}

(2) 提供对外接口函数,供主模块调用:

-- 主要接口函数
ble_5101_file_fota.proc(data)           -- 处理接收到的BLE数据
ble_5101_file_fota.proc_connect()       -- 处理连接成功事件
ble_5101_file_fota.proc_disconnect()    -- 处理连接断开事件

2、协议解析与命令处理

数据协议格式:

  • 命令数据0x01 + [命令码(1字节)] + [文件大小(4字节)]
  • 固件数据0x02 + [固件数据块]

支持的命令码

  • 0x01:开始升级命令,包含文件大小信息
  • 0x02:结束升级命令,触发 FOTA 升级执行

命令处理流程

-- 开始升级命令处理
1. 解析文件大小
2. 初始化FOTA子系统
3. 等待FOTA底层准备就绪
4. 设置升级状态,准备接收数据

-- 结束升级命令处理  
1. 验证文件完整性
2. 执行fota.file()升级
3. 清理临时文件
4. 重启设备完成升级

3、文件操作与数据管理

文件写入机制

  • 使用追加模式("ab")写入接收到的数据块
  • 实时更新接收进度和文件完整性检查
  • 支持断点续传,连接断开后自动清理临时文件

进度跟踪

-- 实时计算并显示升级进度
local progress = math.floor((received_size / total_size) * 100)
log.info("FOTA_DATA", "接收进度:", progress, "%")

4、异常处理与容错机制

连接异常处理

  • 连接断开时自动终止升级流程
  • 清理临时文件,释放系统资源
  • 重置升级状态,准备重新开始

文件操作异常

  • 文件打开失败时终止升级
  • 文件写入失败时记录错误日志
  • 确保 FOTA 流程正确结束

数据完整性验证

  • 结束升级时验证接收文件大小与预期一致
  • 文件不完整时拒绝执行升级操作

5、FOTA 升级执行流程

升级执行步骤:

(1) 文件完整性检查:验证接收数据与预期大小匹配

(2) FOTA 升级执行:调用 fota.file(upgrade_file) 进行升级

(3) 结果验证:检查升级结果,确认是否成功

(4) 设备重启:延迟 2 秒后自动重启设备

升级结果处理:

if result and isDone then
    log.info("FOTA_CMD", "FOTA升级成功!")
    -- 延迟重启,给用户反应时间
    sys.timerStart(ble_reboot, 2000)
else
    log.error("FOTA_CMD", "FOTA升级失败")
end

7.1.3 分段写入方式 FOTA 升级业务逻辑模块(ble_5101_packet_fota.lua)

本文件为 Air5101 蓝牙 FOTA 升级功能模块(分段写入方式),实现了通过 Air5101 接收升级包数据并直接处理分段数据进行固件升级的完整业务逻辑,核心业务逻辑为:

1、初始化与状态管理

(1) 定义升级状态管理结构,用于跟踪升级进度和分段数据处理:

local upgrade_state = {
    is_upgrading = false,          -- 是否正在升级
    total_size = 0,                -- 总文件大小(字节)
    received_size = 0,             -- 已接收大小(字节)
    upgrade_packet = 0             -- 升级包计数器
}

(2) 提供对外接口函数,供主模块调用:

-- 主要接口函数
ble_5101_packet_fota.proc(data)           -- 处理接收到的BLE数据
ble_5101_packet_fota.proc_connect()        -- 处理连接成功事件
ble_5101_packet_fota.proc_disconnect()     -- 处理连接断开事件

2、协议解析与命令处理

数据协议格式

  • 命令数据0x01 + [命令码(1字节)] + [文件大小(4字节)]
  • 固件数据0x02 + [固件数据块]

支持的命令码

  • 0x01:开始升级命令,包含文件大小信息
  • 0x02:结束升级命令,触发 FOTA 升级完成检查

命令处理流程

-- 开始升级命令处理
1. 解析文件大小
2. 初始化FOTA子系统
3. 等待FOTA底层准备就绪
4. 设置升级状态,准备接收分段数据

-- 结束升级命令处理  
1. 验证数据完整性
2. 等待底层校验完成
3. 检查升级结果
4. 重启设备完成升级

3、分段数据处理机制

分段写入机制

  • 使用 fota.run(data) 直接处理接收到的数据块
  • 无需写入临时文件,节省存储空间

进度跟踪

-- 实时计算并显示升级进度
local progress = math.floor((received_size / total_size) * 100)
log.info("FOTA_DATA", "接收进度:", progress, "%")

数据包计数

  • 记录已处理的升级包数量
  • 便于调试和数据完整性验证

4、异常处理与容错机制

连接异常处理

  • 连接断开时自动终止升级流程
  • 清理升级状态,释放系统资源
  • 重置升级状态,准备重新开始

分段写入异常

  • fota.run() 失败时终止升级
  • 记录错误日志,便于问题排查
  • 确保 FOTA 流程正确结束

数据完整性验证

  • 结束升级时验证接收数据大小与预期一致
  • 数据不完整时拒绝完成升级操作

5、FOTA 升级执行流程

升级执行步骤:

(1) 数据完整性检查:验证接收数据与预期大小匹配

(2) 等待底层校验:等待 FOTA 底层完成数据校验

(3) 结果验证:检查升级结果,确认是否成功

(4) 设备重启:延迟 2 秒后自动重启设备

升级结果处理:

-- 等待底层校验完成
for i = 1, 30 do -- 最多等待3秒
    sys.wait(100)
    local succ, fotaDone = fota.isDone()
    if fotaDone then
        log.info("FOTA_CMD", "FOTA升级成功!")
        -- 延迟重启,给用户反应时间
        sys.timerStart(ble_reboot, 2000)
        break
    end
end

7.2 升级包制作

升级包制作是 FOTA 功能的关键步骤,确保按照升级包制作流程操作。

7.3 功能验证

7.3.1 文件系统方式

代码中修改 fota_mode 参数为"file"方式:

-- 选择FOTA升级方式:"file" 或 "packet"
-- 1. file方式:将升级包数据先写入本地文件,然后调用fota.file()进行升级
-- 2. packet方式:直接使用fota.packet()处理分段数据,不写入文件,适合差分升级
local fota_mode = "file" -- 默认使用file方式

模组 luatools 日志如下:

日志解读:

(1) 设备启动,蓝牙服务初始化成功

(2) 收到开始升级命令,初始化 FOTA 分区和缓冲区

(3) 开始分段接收升级数据保存到文件中

(4) 所有数据接收完成,验证固件完整性

(5) 运行升级流程,升级完成,设备重启

(6) 重启后新版本正常运行,确认升级成功

Web 网页工具:

代码文件夹中有个 html 文件,放到 Chrome 或者 Edge 浏览器打开:

然后等待升级完成即可。

Python 脚本工具:

进入到 ble_fota 目录下运行 cmd 命令进入命令行程序,然后等待设备运行并初始化蓝牙后运行下面命令:

python ble_fota_tool.py -f ble_fota.bin

7.3.2 分段写入方式

代码中修改 fota_mode 参数为"packet"方式:

-- 选择FOTA升级方式:"file" 或 "packet"
-- 1. file方式:将升级包数据先写入本地文件,然后调用fota.file()进行升级
-- 2. packet方式:直接使用fota.packet()处理分段数据,不写入文件,适合差分升级
local fota_mode = "packet" -- 默认使用packet方式

模组 luatools 日志如下:

日志解读:

(1) 设备启动,蓝牙服务初始化成功

(2) 收到开始升级命令,初始化 FOTA 分区和缓冲区

(3) 开始分段接收升级数据并通过 fota.run 接口写入 fota 分区

(4) 所有数据接收完成,验证固件完整性

(5) 运行升级流程,升级完成,设备重启

(6) 重启后新版本正常运行,确认升级成功

Web 网页工具:

代码文件夹中有个 html 文件,放到 Chrome 或者 Edge 浏览器打开:

然后等待升级完成即可。

Python 脚本工具:

进入到 ble_fota 目录下运行 cmd 命令进入命令行程序,然后等待设备运行并初始化蓝牙后运行下面命令:

python ble_fota_tool.py -f ble_fota.bin

八、常见问题与解决方案

8.1 蓝牙连接失败

  • 问题:Python 脚本无法找到或连接设备
  • 解决方案:
  • 确认设备已上电并正常启动
  • 检查设备名称是否为"Air5101_FOTA"
  • 确认电脑蓝牙功能已开启

8.2 数据传输中断

  • 问题:升级过程中数据传输中断
  • 解决方案:
  • 确保设备与电脑之间没有障碍物
  • 避免其他蓝牙设备的干扰
  • 检查设备电量是否充足
  • 重新运行升级工具

8.3 升级后版本未更新

  • 问题:升级完成后版本号未变化
  • 解决方案:
  • 检查升级包制作是否正确
  • 确认 VERSION 变量已修改
  • 查看设备日志确认升级是否成功
  • 尝试完全断电后重新上电

8.4 Python 环境问题

  • 问题:Python 脚本无法运行
  • 解决方案:
  • 确认已安装 Python 3.x
  • 安装必要的库:pip install bleak
  • 检查脚本文件路径是否正确
  • 确保有足够的权限运行脚本

九、总结

至此,本教程详细介绍了如何使用 Air5101 的蓝牙功能,来实现 Air780EHV 的无线固件升级。蓝牙 FOTA 提供了一种便捷、低功耗的固件更新方案,特别适合需要远程维护的物联网设备。