跳转至

UWB OTA 固件升级方案文档

1. 方案概述

本文档描述了基于QN9090芯片的UWB OTA固件升级解决方案,支持App固件和SR150固件的串口升级/支持串口和蓝牙两种方式的升级,通过外部Flash存储和内部Flash运行的双重架构实现可靠的固件更新机制。

1.1 系统架构

1.1.1 整体架构概览

本系统支持两种OTA升级方式:串口OTA蓝牙OTA,两种方式共享相同的存储架构和固件管理机制。 当前支持最大固件大小为512字节

┌───────────────────────────────────────────────────────────────────────────┐
│                              OTA升级方案                                   │
├─────────────────────────────┬─────────────────────────────────────────────┤
│         串口OTA方案         │              蓝牙OTA方案                      │
│                             │                                             │
│  ┌─────────────────────┐    │    ┌─────────────────────┐                  │
│  │     PC工具          │    │    │   Android App       │                   │
│  │   (固件升级工具)     │    │    │   (OTA客户端)       │                   │
│  └─────────────────────┘    │    └─────────────────────┘                  │
│            │                │              │                              │
│         串口连接             │           BLE连接                           │
│            │                │              │                              │
│  ┌─────────────────────┐    │    ┌─────────────────────┐                  │
│  │    UART接口         │    │    │    BLE接口          │                   │
│  └─────────────────────┘    │    └─────────────────────┘                  │
└─────────────────────────────┴─────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                             QN9090 UWB设备                                      │
├─────────────────┬───────────────────┬───────────────────┬───────────────────────┤
│   外部Flash     │   内部Flash        │        RAM        │      通信接口         │
│   (W25Q32JV)    │   (QN9090)        │     (QN9090)      │                       │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤ ├─────────────────────┤
│ 0x00280000      │ │ 0x00000000      │ │ 0x04000000      │ │ • UART (串口OTA)    │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ • BLE (蓝牙OTA)     │
│ │App固件头部   │ │ │ │Bootloader   │ │ │ │Stack        │ │ │ • APDU协议处理      │
│ ├─────────────┤ │ │ │(100KB)      │ │ │ ├─────────────┤ │ │ • 外部Flash操作     │
│ │App固件数据   │ │ │ └─────────────┘ │ │ │Heap         │ │ │ • 固件验证          │
│ │(最大512KB)   │ │ │ 0x00019000      │ │ ├─────────────┤ │ └────────────────────┘
│ └─────────────┘ │ │ ┌─────────────┐ │ │ │App Data     │ │
│ 0x00300000      │ │ │Application  │ │ │ │             │ │
│ ┌─────────────┐ │ │ │(540KB)      │ │ │ └─────────────┘ │
│ │CRC+长度     │ │ │ └─────────────┘ │ └─────────────────┘
│ ├─────────────┤ │ └─────────────────┘
│ │SR150固件数据 │ │           ↑
│ └─────────────┘ │    Bootloader验证并加载
└─────────────────┘

1.1.2 两种OTA方案对比

特性 串口OTA 蓝牙OTA
连接方式 UART串口线缆连接 BLE无线连接
传输速率 460800 bps ~2Mbps (BLE 2M PHY)
客户端 PC工具 Android应用
适用场景 开发调试、工厂烧录 现场升级、用户自助升级
协议基础 APDU协议 APDU协议 (通过BLE传输)
数据包大小 最大768字节/包 最大128字节/包 (MTU限制)
可靠性 有线连接,稳定性高 无线连接,需重发机制
用户体验 需要连接线缆 无线操作,便捷性高

2. 存储布局设计

2.1 外部Flash布局 (W25Q32JV - 4MB)

地址范围 大小 用途 说明
0x000000 - 0x27FFFF 2.5MB 预留区域 可用于其他数据存储
0x280000 - 0x2FFFFF 512KB App固件存储区 存储应用程序固件
0x300000 - 0x3FFFFF 1MB SR150固件存储区 存储SR150固件

App固件存储区详细布局 (0x280000 - 0x2FFFFF)

0x280000  ┌────────────────────────────────┐
          │        固件头部 (32字节)        │
          │  - 魔数 (4字节): 0x12345678     │
          │  - 版本号 (4字节)               │
          │  - 固件大小 (4字节)             │
          │  - CRC32校验值 (4字节)          │
           |  - 更新标识 (1字节)              |
          │  - 预留字段 (15字节)            │
0x280020  ├────────────────────────────────┤
          │                                │
          │        App固件数据区            │
          │      (最大 512KB - 32B)        │
          │                                │
0x2FFFFF  └────────────────────────────────┘

SR150固件存储区详细布局 (0x300000 - 0x3FFFFF)

0x300000  ┌────────────────────────────────┐
          │      配置信息页 (256字节)       │
          │  - CRC16校验值 (2字节)          │
          │  - 固件长度 (4字节)             │
          │  - 填充数据 (250字节,0xFF)      │
0x300100  ├────────────────────────────────┤
          │                                │
          │       SR150固件数据区           │
          │      (最大 1MB - 256B)          │
          │                                 │
0x3FFFFF  └─────────────────────────────────┘

2.2 内部Flash布局 (QN9090 - 640KB)

0x00000000 ┌─────────────────────────────────┐
           │       Bootloader区域            │
           │      (100KB = 0x19000)          │
0x00019000 ├─────────────────────────────────┤
           │      Application区域            │
           │      (540KB = 0x87000)          │
0x000A0000 └─────────────────────────────────┘

3. 固件头部结构

3.1 App固件头部结构

typedef struct {
    uint32_t magic;         // 魔数:0x12345678
    uint32_t version;       // 固件版本号
    uint32_t size;          // 固件大小(字节)
    uint32_t crc32;         // CRC32校验值
    uint32_t reserved[4];   // 保留字段
} app_firmware_header_t;

3.2 SR150固件配置结构

typedef struct {
    uint16_t crc16;         // CRC16校验值(CRC-XMODEM)
    uint32_t length;        // 固件长度(字节)
    uint8_t  padding[250];  // 填充数据(0xFF)
} sr150_config_info_t;

4. 通信协议

4.1 基础APDU协议结构

4.1.1 协议帧结构

typedef struct __attribute__((packed)) {
    uint8_t  header;           // 起始位 (0x00)
    uint8_t  preamble[2];      // 前导码 (0x00, 0xFF)
    uint16_t length;           // 数据长度
    ApduPayload_t payload;     // 协议负载
    // DCS校验码 (1字节) - 动态计算
    // 结束码 (1字节) - 0x00
} ApduProtocolFrame_t;

4.1.2 协议负载结构

typedef struct __attribute__((packed)) {
    uint8_t SADDR[6];    // 源地址
    uint8_t TADDR[6];    // 目标地址
    uint8_t SNQ;         // 序列号
    uint8_t cmd_type;    // 命令字
    uint8_t result;      // 结果状态
    uint8_t apdu_count;  // apdu数量
    uint8_t data[1080];  // 数据域
} ApduPayload_t;

4.2 OTA协议扩展

4.2.1 命令定义

命令字 命令名称 功能描述
0xCA RESET_MCU 设备重启命令
0xCB FIRMWARE_ERASE 固件擦除命令
0xCC FIRMWARE_PROGRAM 固件写入命令
0xCD FIRMWARE_READ_HEADER 固件头部读取命令

4.2.2 固件擦除命令 (0xCB)

固件擦除BLE和COM方案是相同的,但响应不同,具体参考6

请求格式:

data[0-3]: 擦除起始地址 (32位小端序)
data[4]:   擦除块数 (0=整片擦除, 1-N=块数)

响应格式:

result: 0x00=成功, 0x01=失败
无数据域

说明:

  • 每个块大小为64KB (W25Q32JV_BLOCK_64K)
  • blocks = 0时执行整片擦除
  • blocks > 0时从指定地址开始擦除指定数量的64KB块

4.2.3 固件写入命令 (0xCC)

COM请求格式:

data[0-3]: 写入起始地址 (32位小端序)
data[4]:   页数 (1-3页, 每页256字节)
data[5-N]: 固件数据 (最大768字节)

响应格式:

result: 0x00=成功, 0x01=失败
无数据域

BLE请求格式:

payload.result + payload.apdu_count:页号
data[0-3]: 写入起始地址 (32位小端序)
data[4]:   页数 (未使用,占位)
data[5-N]: 固件数据 (最大768字节)

BLE响应格式:

无响应.

说明:

  • 支持1-3页写入,每页256字节
  • 最大单次写入768字节
  • 数据长度必须与页数匹配
  • 使用多页写入接口优化性能

4.2.4 固件头部读取命令 (0xCD)

固件头部读取BLE和COM方案是相同的,但响应不同,具体参考6

请求格式:

data[0-3]: 读取起始地址 (32位小端序)

响应格式:

result: 0x00=成功, 0x01=失败
data[0-31]: 固件头部数据 (32字节)

说明:

  • 固定读取32字节固件头部信息
  • 默认从EXTERNAL_FLASH_APP_START地址读取
  • 失败时不返回数据域

4.3.3 错误码定义

pass

5. 校验机制

5.1 App固件校验

  • 算法: CRC32 (IEEE 802.3标准)
  • 范围: 固件数据部分(不包含头部)
  • 验证: Bootloader启动时验证
  • 同串口方式一致

5.2 SR150固件校验

  • 算法: CRC16 (CRC-XMODEM)
  • 范围: 完整固件数据
  • 验证: SR150芯片内部验证

6. 蓝牙OTA方案

6.1 方案概述

蓝牙OTA方案提供了一种无线固件升级解决方案,通过Android应用程序与UWB设备建立蓝牙连接,实现固件的无线传输和升级。该方案基于BLE (Bluetooth Low Energy) 技术,支持App固件和SR150固件(待定...)的远程升级。

6.2 系统架构

┌────────────────┐    BLE连接   ┌───────────────┐ 
│  Android App   │ <----------> │   UWB设备      │
│  (OTA客户端)   │               │  (QN9090)     │   
├────────────────┤              ├────────────────┤   
│ • 固件选择      │              │ • BLE服务      │  
│ • 设备扫描      │              │ • APDU协议处理 │   
│ • 固件传输      │              │ • 外部Flash操作│  
│ • 进度监控      │              │ • 响应发送     │   
└────────────────┘              └────────────────┘   

6.3 BLE通信协议

6.3.1 服务和特征定义

主服务UUID: D44BC439-ABFD-45A2-B575-925416129601

特征名称 UUID 属性 功能描述
TX特征 D44BC439-ABFD-45A2-B575-925416129603 Notify 设备向App发送数据
RX特征 D44BC439-ABFD-45A2-B575-925416129602 Write App向设备发送数据

6.3.2 数据传输格式

define gBleUseHSClock2MbpsPhy_c 1 //2Mbps PHY mode

APDU协议复用

  • 蓝牙OTA完全复用串口OTA的APDU协议格式,确保协议层的一致性
  • 每个BLE数据包都是完整的APDU帧结构,包含header、preamble、length、payload等字段
  • 支持4种OTA命令:RESET_MCU(0xCA)、FIRMWARE_ERASE (0xCB)、FIRMWARE_PROGRAM (0xCC)、FIRMWARE_READ_HEADER (0xCD)

数据分块传输机制

  • 单包限制: 受BLE MTU限制,每个数据包最大128字节固件数据
  • 缓冲区管理: 设备端维护1KB缓冲区,采用8包聚合机制
  • 拼接策略:
  • 第1包:完整APDU帧,包含地址信息,初始化缓冲区
  • 第2-8包:提取纯固件数据(跳过地址+pages字段),追加到缓冲区
  • 第8包后:触发Flash写入操作,重置缓冲区状态

响应机制

  1. 简化响应: 设备端通过BLE Notification发送简化响应 [phase, status]
  2. 阶段标识: phase值对应不同OTA阶段(1=擦除,2=编程,3=验证, 4=丢包)
  3. 状态码: status为0x00表示成功,0x01表示失败;
  4. CCCD要求: 客户端必须启用TX特征的通知功能才能接收响应

重发机制

  • 包结构中的status和apdu_num这两个相邻字段被用来表示当前包序号
  • 设备端监测包序号判断丢包,并向app发送丢包响应,通知重发
  • 由于速率不匹配,app每秒仅接收一次相同序号的丢包响应
  • 所有包发送完成后等待一秒,检查最后几包是否丢失,以免响应不及时导致异常

数据包结构示例

第1包 (初始化): [APDU Header][地址4B][Pages1B][固件数据123B]
第2包 (追加):   [APDU Header][地址4B][Pages1B][固件数据123B] -> 仅提取128B数据
...
第8包 (触发):   [APDU Header][地址4B][Pages1B][固件数据123B] -> 累计1KB写入Flash

6.4 Android应用架构

6.4.1 核心组件

┌─────────────────────────────────────────────────────────────┐
│                    MainActivity                             │
├─────────────────────────────────────────────────────────────┤
│ • UI控制和用户交互                                           │
│ • 固件文件选择和管理                                         │
│ • 升级进度显示                                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     OtaManager                              │
├─────────────────────────────────────────────────────────────┤
│ • OTA流程控制和状态管理                                      │
│ • APDU协议封装和解析                                         │
│ • 固件数据分包和传输                                         │
│ • 错误处理和重试机制                                         │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     BleManager                              │
├─────────────────────────────────────────────────────────────┤
│ • BLE设备扫描和连接管理                                      │
│ • GATT服务发现和特征操作                                     │
│ • 数据收发和MTU协商                                          │
│ • 连接状态监控和异常处理                                      │
└─────────────────────────────────────────────────────────────┘

6.5 OTA升级流程

6.5.1 App固件升级流程

1. 设备扫描和连接
   ├── 扫描附近的UWB设备
   ├── 选择目标设备并建立BLE连接
   ├── 发现GATT服务和特征
   └── 启用TX特征通知

2. 固件准备阶段
   ├── 选择App固件文件 (.bin)
   ├── 读取固件数据并计算CRC32
   ├── 构建固件头部信息
   └── 准备传输数据包

3. 擦除阶段
   ├── 发送擦除命令 (0xCB)
   ├── 指定擦除地址和块数
   ├── 等待擦除完成确认
   └── 验证擦除结果

4. 编程阶段
   ├── 分包发送固件数据 (0xCC)
   ├── 每包128字节固件数据
   ├── 实时进度更新
   ├── 错误检测和重试
   └── 完成确认

5. 验证阶段
   ├── 读取固件头部 (0xCD)
   ├── 验证CRC32校验值
   ├── 确认固件完整性
   └── 升级完成通知

6.5.2 SR150固件升级流程

pass

7 待办

7.1 串口OTA

  1. 缺少固件完整性验证
  2. 串口丢字节
  3. 串口接收数据后不触发回调
  4. 缺少重发机制

如果能解决2,3. 应该不用实现4

7.2 蓝牙OTA

添加了重发机制后,蓝牙OTA的成功率很高了(桌面环境).但还是缺少完整性验证兜底.