- 增加STM8 Bootloader工程及出厂固件恢复流程\n- 增加W25Q64外部Flash驱动和OTA分包接收、CRC16校验、断点续传状态管理\n- 增加固件版本查询、升级结果上报与主机确认机制\n- 将业务帧从55 AA帧头调整为发送方Mesh短地址+CMD+LEN+DATA+CRC16\n- 修正JDY-28M外层地址与业务发送方地址的职责划分,支持广播请求定向应答\n- 同步更新硬件引脚、存储分区、OTA流程和主机通信协议文档\n- 已使用SDCC重新编译,应用代码大小为5512字节,链接地址为0x8800
8.7 KiB
STM8 Mesh 继电器 OTA、Flash 分区与业务协议设计
本文档记录当前已经确认的外部 W25Q64 存储规划、Bootloader 启动策略、主程序 OTA 职责以及业务命令规则。
1. 硬件资源与程序分区
1.1 STM8S003F3P6TR 内部 Flash
STM8S003F3P6TR 内部程序 Flash 总容量为 8KiB,地址范围为 0x8000~0x9FFF。
当前 Bootloader 规划如下:
| 地址范围 | 容量 | 用途 |
|---|---|---|
0x8000~0x87FF |
2KiB | Bootloader |
0x8800~0x9FFF |
6KiB | Application 主程序 |
应用程序必须按照 0x8800 重新链接,不能使用默认的 0x8000 起始地址。
1.2 W25Q64JVSIQ 外部 Flash
W25Q64 总容量为 8MiB。当前固定分区如下:
| 地址范围 | 容量 | 用途 |
|---|---|---|
0x000000~0x00FFFF |
64KiB | 出厂固件镜像 |
0x010000~0x010FFF |
4KiB | 出厂固件元数据 |
0x020000~0x02FFFF |
64KiB | OTA升级固件镜像 |
0x030000~0x030FFF |
4KiB | OTA升级元数据 |
| 其余空间 | 约8056KiB | 后续日志、运行记录、故障记录等 |
元数据区域均独占一个4KiB扇区,避免擦除元数据时影响固件镜像。
1.3 SPI连接
| STM8引脚 | W25Q64信号 |
|---|---|
PC5 |
SCK |
PC6 |
MOSI/DI |
PC7 |
MISO/DO |
PD4 |
CS# |
3.3V |
VCC |
GND |
GND |
恢复/继电器按键连接到 PA3,按键另一端接地,使用内部上拉:
PA3 = 1:按键释放
PA3 = 0:按键按下
JDY-28M 控制脚当前分配为:PA2=PWRC、PD2=RESET。PA2 不再作为Flash片选。
蓝牙状态/故障指示灯连接到 PB5,低电平点亮;继电器状态指示灯连接到 PD3,高电平点亮。
程序运行/OTA状态灯连接到 PB4,低电平点亮:正常运行时按500ms节奏闪烁,OTA接收或校验时按约100ms节奏快速闪烁。
2. 元数据格式
出厂元数据和OTA元数据使用相同字段布局,只是存储区域不同。
2.1 元数据字段
相对于元数据区域起始地址的固定偏移如下:
| 偏移 | 字段 | 长度 | 说明 |
|---|---|---|---|
0x00 |
魔数 | 4字节 | 识别元数据类型 |
0x04 |
固件长度 | 4字节 | 实际固件字节数 |
0x08 |
固件版本 | 2字节 | 版本号,高低字节规则由打包工具固定 |
0x0A |
CRC16 | 2字节 | 完整固件镜像CRC-16/MODBUS |
0x0E |
镜像有效标志 | 1字节 | 0xA5表示有效 |
0x0F |
升级请求 | 1字节 | 非0表示请求Bootloader处理 |
0x10 |
升级结果 | 1字节 | Bootloader执行结果 |
0x11 |
保留 | 1字节 | 后续扩展 |
2.2 元数据绝对地址
OTA元数据区域起始地址为 0x030000,因此:
魔数: 0x030000~0x030003
固件长度: 0x030004~0x030007
固件版本: 0x030008~0x030009
CRC16: 0x03000A~0x03000B
有效标志: 0x03000E
升级请求: 0x03000F
升级结果: 0x030010
出厂元数据区域起始地址为 0x010000,字段偏移相同,因此出厂镜像升级结果地址为 0x010010。
2.3 魔数
魔数是固定识别值,不是密码。当前约定:
FACTORY_METADATA_MAGIC = 0x46414331 /* FAC1,出厂镜像 */
OTA_METADATA_MAGIC = 0x4F544131 /* OTA1,升级镜像 */
Bootloader只有在魔数正确、有效标志正确、升级请求有效、固件长度合法且CRC16正确时,才允许使用镜像。
2.4 元数据写入规则
下载过程中不能提前写入有效标志。正确顺序为:
1. 擦除OTA固件区域;
2. 接收并写入固件分包;
3. 计算完整固件CRC16/MODBUS;
4. 写入魔数、长度、版本和CRC16;
5. 校验元数据;
6. 最后写入image_valid = 0xA5;
7. 设置upgrade_request;
8. 软件复位进入Bootloader。
这样可以避免断电时把不完整固件误判为有效镜像。
3. Bootloader职责
Bootloader不处理JDY-28M Mesh通信,也不接收OTA分包。
Bootloader负责:
- 上电检测PA3上电恢复按键;
- 读取OTA元数据;
- 校验OTA固件CRC16/MODBUS;
- 擦除STM8内部应用区;
- 从W25Q64搬运固件到内部Flash;
- 回读校验内部Flash;
- 写入升级结果;
- 清除升级请求;
- 检查内部应用程序是否有效;
- 应用损坏时恢复出厂固件;
- 跳转到
0x8800启动主程序。
升级安全顺序必须是:
先完整校验W25Q64固件
↓
CRC正确
↓
擦除内部应用区
↓
写入应用程序
↓
回读校验
↓
记录升级成功
↓
清除升级请求
3.1 出厂固件恢复
以下任一情况出现时,Bootloader使用 0x000000 开始的出厂镜像:
- 内部应用程序为空;
- 内部应用程序入口无效;
- OTA固件CRC16错误;
- 内部Flash写入失败;
- 内部Flash写入后校验失败;
- 应用程序损坏导致无法正常启动。
出厂镜像必须预先写入W25Q64,并且出厂元数据中的镜像有效标志和CRC16必须正确。
4. PA3上电恢复按键
4.1 Bootloader阶段
上电后首先运行Bootloader:
检测PA3
├── 未按下:执行正常Bootloader流程
└── 已按下:开始计时,此期间不跳转主程序
├── 5秒内释放:继续正常Bootloader流程
└── 持续按住超过5秒:恢复出厂固件
主程序不会参与本次上电按键判断,因此不存在Bootloader长按和主程序恢复参数重复触发的问题。
4.2 主程序阶段
主程序只处理正常运行期间的新按键:
短按:按下时间小于5秒,控制继电器
长按:按下时间大于5秒,恢复主程序参数
5. 主程序OTA职责
主程序负责:
- 通过JDY-28M接收OTA业务帧;
- 校验业务帧CRC16/MODBUS;
- 擦除OTA固件区域;
- 将固件分包写入
0x020000; - 计算完整固件CRC16/MODBUS;
- 写入OTA元数据;
- 设置有效标志和升级请求;
- 软件复位进入Bootloader;
- 启动后读取Bootloader升级结果;
- 通过Mesh主动上报升级结果;
- 收到主机确认后清除升级结果。
6. 主程序业务帧格式
业务数据帧格式:
SRC_H | SRC_L | CMD | LEN | DATA | CRC16_L | CRC16_H
说明:
SRC_H SRC_L:发送方 Mesh 短地址,高字节在前;设备应答时将该地址作为 JDY-28M 外层目标地址,业务帧中的 SRC 改为设备自身短地址;CMD:命令;LEN:DATA长度;DATA:命令数据;CRC16:CRC-16/MODBUS,计算范围为 SRC、CMD、LEN、DATA,低字节在前;- CRC错误时静默丢弃,不执行继电器动作,不返回错误帧。
JDY-28M的Mesh外层帧负责目标地址、源地址、Mesh头和帧尾,业务帧本身不重复添加地址。
7. 已确定的业务命令
| CMD | 名称 | 方向 | DATA说明 |
|---|---|---|---|
0x01 |
继电器控制 | 主机→设备 | 0x00断开,0x01吸合 |
0x02 |
查询继电器状态 | 主机→设备 | 返回0x00断开或0x01吸合 |
0x03 |
查询实际电流 | 主机→设备 | 返回无符号mA,高字节在前 |
0x04 |
故障/恢复上报 | 设备→主机 | DATA为故障码或恢复码 |
0x05 |
查询设备短地址 | 主机→设备 | 返回2字节短地址 |
0x06 |
配置电流阈值 | 主机→设备 | 2字节,单位mA,低字节在前,保存到EEPROM |
0x0E |
查询当前固件版本 | 主机→设备 | 无DATA |
0x0D |
OTA升级结果上报 | 设备→主机 | DATA为升级结果码 |
应答命令使用请求命令加 0x80:
0x81:继电器控制应答
0x82:继电器状态应答
0x83:电流查询应答
0x85:短地址查询应答
0x86:阈值配置应答
OTA内部控制命令建议保留:
0x08:进入OTA模式
0x09:固件数据分包
0x0A:固件发送完成并校验
0x0B:查询OTA状态
0x0C:取消OTA
0x0E:查询当前固件版本
8. 故障码和升级结果码
8.1 故障码
0x02:ACS712采样异常
0x03:蓝牙初始化异常
0x04:电流故障恢复
0x05:蓝牙故障恢复
0x06:采样异常恢复
0x07:继电器控制失败预留码
电流故障需要持续至少10秒确认,恢复也需要持续至少10秒确认。默认电流阈值为100mA,支持动态配置并保存到EEPROM。
故障恢复上报需要等待主机确认;未收到确认时每10秒重复上报,直到收到确认。
8.2 OTA升级结果码
0x00:无结果
0x01:升级成功
0x02:固件CRC错误
0x03:内部Flash写入失败
0x04:写入后校验失败
0x05:固件长度非法
0x06:W25Q64读取失败
主程序启动后读取升级结果,并使用:
CMD = 0x0D
LEN = 0x01
DATA = 升级结果码
发送给主机。主机确认后,主程序清除结果字段。