feat: 完善Mesh继电器OTA与地址协议
- 增加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
This commit is contained in:
@@ -0,0 +1,468 @@
|
||||
# STM8 Mesh 继电器主机通信协议
|
||||
|
||||
本文档供主机、网关和上位机开发人员使用。通信分为两层:JDY-28M Mesh外层和设备业务内层。
|
||||
|
||||
## 1. Mesh外层帧
|
||||
|
||||
### 1.1 主机发送给设备
|
||||
|
||||
```text
|
||||
41 54 2B AA A1 | DST_H DST_L | A0 | BUSINESS | 0D 0A
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 长度 | 说明 |
|
||||
|---|---:|---|
|
||||
| `41 54 2B AA A1` | 5 | JDY-28M Mesh发送固定帧头 |
|
||||
| `DST_H DST_L` | 2 | 目标短地址,高字节在前 |
|
||||
| `A0` | 1 | Mesh数据通信标志,固定值 |
|
||||
| `BUSINESS` | 变长 | 本文档第2节定义的业务帧 |
|
||||
| `0D 0A` | 2 | Mesh帧尾,固定值 |
|
||||
|
||||
广播地址:
|
||||
|
||||
```text
|
||||
FFFF
|
||||
```
|
||||
|
||||
单播到短地址`000C`:
|
||||
|
||||
```text
|
||||
DST_H = 00
|
||||
DST_L = 0C
|
||||
```
|
||||
|
||||
### 1.2 设备发送给主机
|
||||
|
||||
```text
|
||||
F1 DD 09 00 0A | SRC_H SRC_L | BUSINESS | 0D 0A
|
||||
```
|
||||
|
||||
这里的两字节是 JDY-28M 外层携带的目标地址字段;设备发送方短地址不由该
|
||||
字段提供,而是放在业务帧 `BUSINESS` 的 `SRC_H SRC_L` 字段中。
|
||||
|
||||
### 1.3 长度限制
|
||||
|
||||
JDY-28M完整Mesh帧最大20字节。当前业务帧最大DATA长度为4字节:
|
||||
|
||||
```text
|
||||
BUSINESS = SRC_H SRC_L CMD LEN DATA CRC16_L CRC16_H
|
||||
```
|
||||
|
||||
业务帧长度为`6 + LEN`,完整外层发送帧长度为`16 + LEN`,因此`LEN`最大为4。
|
||||
|
||||
## 2. 业务帧格式
|
||||
|
||||
```text
|
||||
SRC_H SRC_L | CMD | LEN | DATA[0..LEN-1] | CRC16_L CRC16_H
|
||||
```
|
||||
|
||||
### 2.1 CRC16规则
|
||||
|
||||
```text
|
||||
算法:CRC-16/MODBUS
|
||||
多项式:0xA001
|
||||
初始值:0xFFFF
|
||||
输入反射:是
|
||||
输出反射:是
|
||||
计算范围:SRC_H、SRC_L、CMD、LEN和DATA
|
||||
发送顺序:CRC低字节在前,高字节在后
|
||||
```
|
||||
|
||||
CRC错误时设备直接丢弃整帧,不执行命令,也不返回错误应答。
|
||||
|
||||
## 3. 通用应答规则
|
||||
|
||||
普通请求的应答命令通常为:
|
||||
|
||||
```text
|
||||
应答CMD = 请求CMD | 0x80
|
||||
```
|
||||
|
||||
错误应答:
|
||||
|
||||
```text
|
||||
CMD = E0
|
||||
LEN = 01
|
||||
DATA[0] = 错误码
|
||||
```
|
||||
|
||||
当前常用错误码:
|
||||
|
||||
```text
|
||||
0x02:DATA长度错误
|
||||
0x03:DATA参数错误
|
||||
0x05:EEPROM或配置写入失败
|
||||
0x06:未知命令
|
||||
```
|
||||
|
||||
## 4. 主机下发的普通命令
|
||||
|
||||
### 4.1 `0x01` 继电器控制
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 01
|
||||
LEN = 01
|
||||
DATA[0] = 00:继电器断开
|
||||
DATA[0] = 01:继电器吸合
|
||||
```
|
||||
|
||||
业务帧结构示例:
|
||||
|
||||
```text
|
||||
SRC_H SRC_L 01 01 01 CRC16_L CRC16_H
|
||||
```
|
||||
|
||||
设备执行后返回:
|
||||
|
||||
```text
|
||||
CMD = 81
|
||||
LEN = 01
|
||||
DATA[0] = 当前继电器控制状态
|
||||
```
|
||||
|
||||
```text
|
||||
00:断开
|
||||
01:吸合
|
||||
```
|
||||
|
||||
注意:当前没有继电器触点反馈,设备只能确认PA1控制输出已经设置,不能确认触点机械动作是否真实成功。电流异常由故障检测功能另行上报。
|
||||
|
||||
### 4.2 `0x02` 查询继电器状态
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 02
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 82
|
||||
LEN = 01
|
||||
DATA[0] = 00:断开
|
||||
DATA[0] = 01:吸合
|
||||
```
|
||||
|
||||
### 4.3 `0x03` 查询实际电流
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 03
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 83
|
||||
LEN = 02
|
||||
DATA[0] = 电流低字节
|
||||
DATA[1] = 电流高字节
|
||||
```
|
||||
|
||||
单位为mA,无符号整数,低字节在前。例如实际电流为`1000mA = 0x03E8`:
|
||||
|
||||
```text
|
||||
DATA = E8 03
|
||||
```
|
||||
|
||||
### 4.4 `0x05` 查询设备短地址
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 05
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 85
|
||||
LEN = 02
|
||||
DATA[0] = 短地址高字节
|
||||
DATA[1] = 短地址低字节
|
||||
```
|
||||
|
||||
例如设备短地址为`000C`:
|
||||
|
||||
```text
|
||||
DATA = 00 0C
|
||||
```
|
||||
|
||||
### 4.5 `0x06` 配置电流阈值
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 06
|
||||
LEN = 02
|
||||
DATA[0] = 阈值低字节
|
||||
DATA[1] = 阈值高字节
|
||||
```
|
||||
|
||||
单位为mA,默认值为100mA,设备保存到内部EEPROM。例如设置100mA:
|
||||
|
||||
```text
|
||||
DATA = 64 00
|
||||
```
|
||||
|
||||
设备成功返回:
|
||||
|
||||
```text
|
||||
CMD = 86
|
||||
LEN = 02
|
||||
DATA = 原样返回设置的阈值
|
||||
```
|
||||
|
||||
## 5. 固件版本查询
|
||||
|
||||
### 5.1 `0x0E` 查询当前固件版本
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 0E
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 8E
|
||||
LEN = 02
|
||||
DATA[0] = 版本低字节
|
||||
DATA[1] = 版本高字节
|
||||
```
|
||||
|
||||
当前版本在主程序`include/app_config.h`中定义:
|
||||
|
||||
```c
|
||||
#define FIRMWARE_VERSION 0x0001u
|
||||
```
|
||||
|
||||
例如版本`0x0001`返回:
|
||||
|
||||
```text
|
||||
DATA = 01 00
|
||||
```
|
||||
|
||||
## 6. 故障与恢复上报
|
||||
|
||||
故障上报由设备主动发送:
|
||||
|
||||
```text
|
||||
CMD = 04
|
||||
LEN = 01
|
||||
DATA[0] = 故障码或恢复码
|
||||
```
|
||||
|
||||
故障码:
|
||||
|
||||
```text
|
||||
0x00:继电器吸合但持续无有效电流
|
||||
0x01:继电器断开但仍存在持续电流
|
||||
0x02:ACS712采样异常
|
||||
0x03:蓝牙初始化异常,仅LED指示,不通过Mesh上报
|
||||
0x04:电流故障恢复
|
||||
0x05:蓝牙故障恢复
|
||||
0x06:采样异常恢复
|
||||
0x07:继电器控制失败预留码
|
||||
```
|
||||
|
||||
主机确认故障或恢复上报:
|
||||
|
||||
```text
|
||||
CMD = 84
|
||||
LEN = 01
|
||||
DATA[0] = 被确认的故障码或恢复码
|
||||
```
|
||||
|
||||
故障产生和恢复都需要持续至少10秒确认。故障恢复上报未收到主机确认时,设备每10秒重复上报,直到收到确认。
|
||||
|
||||
## 7. OTA命令
|
||||
|
||||
主机发送的OTA固件是`mesh_relay.bin`裸二进制文件,不是HEX文本文件,也不包含Bootloader。
|
||||
|
||||
### 7.1 `0x08` 进入OTA
|
||||
|
||||
```text
|
||||
CMD = 08
|
||||
LEN = 04
|
||||
DATA[0] = 固件长度低字节
|
||||
DATA[1] = 固件长度高字节
|
||||
DATA[2] = 版本号低字节
|
||||
DATA[3] = 版本号高字节
|
||||
```
|
||||
|
||||
设备收到后擦除:
|
||||
|
||||
```text
|
||||
OTA固件区:0x020000~0x02FFFF
|
||||
OTA元数据:0x030000~0x030FFF
|
||||
```
|
||||
|
||||
成功应答:
|
||||
|
||||
```text
|
||||
CMD = 88
|
||||
LEN = 01
|
||||
DATA[0] = 00
|
||||
```
|
||||
|
||||
### 7.2 `0x09` 固件分包
|
||||
|
||||
正常数据包:
|
||||
|
||||
```text
|
||||
CMD = 09
|
||||
LEN = 04
|
||||
DATA[0] = OFFSET高字节
|
||||
DATA[1] = OFFSET低字节
|
||||
DATA[2] = 固件数据1
|
||||
DATA[3] = 固件数据2
|
||||
```
|
||||
|
||||
最后只有1字节固件数据时:
|
||||
|
||||
```text
|
||||
CMD = 09
|
||||
LEN = 03
|
||||
DATA[0] = OFFSET高字节
|
||||
DATA[1] = OFFSET低字节
|
||||
DATA[2] = 固件数据1
|
||||
```
|
||||
|
||||
设备只接受等于当前期待偏移的分包。成功后返回:
|
||||
|
||||
```text
|
||||
CMD = 89
|
||||
LEN = 03
|
||||
DATA[0] = 00:写入成功
|
||||
DATA[1] = 下一期待偏移高字节
|
||||
DATA[2] = 下一期待偏移低字节
|
||||
```
|
||||
|
||||
如果偏移错误、Flash写入失败或OTA状态错误,返回非0状态码。主机应根据返回的期待偏移重传。
|
||||
|
||||
### 7.3 `0x0A` 发送完整固件CRC16
|
||||
|
||||
```text
|
||||
CMD = 0A
|
||||
LEN = 02
|
||||
DATA[0] = 完整固件CRC16低字节
|
||||
DATA[1] = 完整固件CRC16高字节
|
||||
```
|
||||
|
||||
CRC16使用CRC-16/MODBUS,计算范围是整个裸二进制固件文件。
|
||||
|
||||
设备接收后返回:
|
||||
|
||||
```text
|
||||
CMD = 8A
|
||||
LEN = 01
|
||||
DATA[0] = 00:接收成功
|
||||
```
|
||||
|
||||
### 7.4 `0x0B` 请求校验并提交升级
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 0B
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备从W25Q64重新读取完整固件并计算CRC16。校验成功后写入OTA元数据:
|
||||
|
||||
```text
|
||||
0x030000:魔数
|
||||
0x030004:固件长度
|
||||
0x030008:固件版本
|
||||
0x03000A:CRC16
|
||||
0x03000E:镜像有效标志0xA5
|
||||
0x03000F:升级请求0xA5
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 8B
|
||||
LEN = 01
|
||||
DATA[0] = 00:校验成功,已提交升级
|
||||
DATA[0] = 01:校验失败
|
||||
```
|
||||
|
||||
之后设备复位,由Bootloader把OTA固件搬运到内部Flash的`0x8800`区域。
|
||||
|
||||
### 7.5 `0x0C` 取消OTA
|
||||
|
||||
主机发送:
|
||||
|
||||
```text
|
||||
CMD = 0C
|
||||
LEN = 00
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
CMD = 8C
|
||||
LEN = 01
|
||||
DATA[0] = 00:取消成功
|
||||
```
|
||||
|
||||
### 7.6 OTA传输顺序
|
||||
|
||||
```text
|
||||
查询版本:0E
|
||||
进入OTA:08
|
||||
等待应答:88
|
||||
发送分包:09
|
||||
每包等待应答:89
|
||||
发送完整CRC16:0A
|
||||
请求校验提交:0B
|
||||
等待校验结果:8B
|
||||
设备复位并升级
|
||||
主程序启动后主动上报升级结果:0D
|
||||
主机确认升级结果:8D
|
||||
```
|
||||
|
||||
## 8. OTA升级结果上报
|
||||
|
||||
设备启动后从`0x030010`读取升级结果,蓝牙初始化成功后主动广播:
|
||||
|
||||
```text
|
||||
CMD = 0D
|
||||
LEN = 01
|
||||
DATA[0] = 升级结果码
|
||||
```
|
||||
|
||||
结果码:
|
||||
|
||||
```text
|
||||
0x00:无结果
|
||||
0x01:升级成功
|
||||
0x02:固件CRC错误
|
||||
0x03:内部Flash写入失败
|
||||
0x04:写入后校验失败
|
||||
0x05:固件长度非法
|
||||
0x06:W25Q64读取失败
|
||||
```
|
||||
|
||||
主机确认:
|
||||
|
||||
```text
|
||||
CMD = 8D
|
||||
LEN = 01
|
||||
DATA[0] = 对应的升级结果码
|
||||
```
|
||||
|
||||
设备收到确认后清除`0x030010`。
|
||||
@@ -0,0 +1,302 @@
|
||||
# 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`,按键另一端接地,使用内部上拉:
|
||||
|
||||
```text
|
||||
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`,因此:
|
||||
|
||||
```text
|
||||
魔数: 0x030000~0x030003
|
||||
固件长度: 0x030004~0x030007
|
||||
固件版本: 0x030008~0x030009
|
||||
CRC16: 0x03000A~0x03000B
|
||||
有效标志: 0x03000E
|
||||
升级请求: 0x03000F
|
||||
升级结果: 0x030010
|
||||
```
|
||||
|
||||
出厂元数据区域起始地址为 `0x010000`,字段偏移相同,因此出厂镜像升级结果地址为 `0x010010`。
|
||||
|
||||
### 2.3 魔数
|
||||
|
||||
魔数是固定识别值,不是密码。当前约定:
|
||||
|
||||
```c
|
||||
FACTORY_METADATA_MAGIC = 0x46414331 /* FAC1,出厂镜像 */
|
||||
OTA_METADATA_MAGIC = 0x4F544131 /* OTA1,升级镜像 */
|
||||
```
|
||||
|
||||
Bootloader只有在魔数正确、有效标志正确、升级请求有效、固件长度合法且CRC16正确时,才允许使用镜像。
|
||||
|
||||
### 2.4 元数据写入规则
|
||||
|
||||
下载过程中不能提前写入有效标志。正确顺序为:
|
||||
|
||||
```text
|
||||
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` 启动主程序。
|
||||
|
||||
升级安全顺序必须是:
|
||||
|
||||
```text
|
||||
先完整校验W25Q64固件
|
||||
↓
|
||||
CRC正确
|
||||
↓
|
||||
擦除内部应用区
|
||||
↓
|
||||
写入应用程序
|
||||
↓
|
||||
回读校验
|
||||
↓
|
||||
记录升级成功
|
||||
↓
|
||||
清除升级请求
|
||||
```
|
||||
|
||||
### 3.1 出厂固件恢复
|
||||
|
||||
以下任一情况出现时,Bootloader使用 `0x000000` 开始的出厂镜像:
|
||||
|
||||
- 内部应用程序为空;
|
||||
- 内部应用程序入口无效;
|
||||
- OTA固件CRC16错误;
|
||||
- 内部Flash写入失败;
|
||||
- 内部Flash写入后校验失败;
|
||||
- 应用程序损坏导致无法正常启动。
|
||||
|
||||
出厂镜像必须预先写入W25Q64,并且出厂元数据中的镜像有效标志和CRC16必须正确。
|
||||
|
||||
## 4. PA3上电恢复按键
|
||||
|
||||
### 4.1 Bootloader阶段
|
||||
|
||||
上电后首先运行Bootloader:
|
||||
|
||||
```text
|
||||
检测PA3
|
||||
├── 未按下:执行正常Bootloader流程
|
||||
└── 已按下:开始计时,此期间不跳转主程序
|
||||
├── 5秒内释放:继续正常Bootloader流程
|
||||
└── 持续按住超过5秒:恢复出厂固件
|
||||
```
|
||||
|
||||
主程序不会参与本次上电按键判断,因此不存在Bootloader长按和主程序恢复参数重复触发的问题。
|
||||
|
||||
### 4.2 主程序阶段
|
||||
|
||||
主程序只处理正常运行期间的新按键:
|
||||
|
||||
```text
|
||||
短按:按下时间小于5秒,控制继电器
|
||||
长按:按下时间大于5秒,恢复主程序参数
|
||||
```
|
||||
|
||||
## 5. 主程序OTA职责
|
||||
|
||||
主程序负责:
|
||||
|
||||
- 通过JDY-28M接收OTA业务帧;
|
||||
- 校验业务帧CRC16/MODBUS;
|
||||
- 擦除OTA固件区域;
|
||||
- 将固件分包写入 `0x020000`;
|
||||
- 计算完整固件CRC16/MODBUS;
|
||||
- 写入OTA元数据;
|
||||
- 设置有效标志和升级请求;
|
||||
- 软件复位进入Bootloader;
|
||||
- 启动后读取Bootloader升级结果;
|
||||
- 通过Mesh主动上报升级结果;
|
||||
- 收到主机确认后清除升级结果。
|
||||
|
||||
## 6. 主程序业务帧格式
|
||||
|
||||
业务数据帧格式:
|
||||
|
||||
```text
|
||||
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`:
|
||||
|
||||
```text
|
||||
0x81:继电器控制应答
|
||||
0x82:继电器状态应答
|
||||
0x83:电流查询应答
|
||||
0x85:短地址查询应答
|
||||
0x86:阈值配置应答
|
||||
```
|
||||
|
||||
OTA内部控制命令建议保留:
|
||||
|
||||
```text
|
||||
0x08:进入OTA模式
|
||||
0x09:固件数据分包
|
||||
0x0A:固件发送完成并校验
|
||||
0x0B:查询OTA状态
|
||||
0x0C:取消OTA
|
||||
0x0E:查询当前固件版本
|
||||
```
|
||||
|
||||
## 8. 故障码和升级结果码
|
||||
|
||||
### 8.1 故障码
|
||||
|
||||
```text
|
||||
0x02:ACS712采样异常
|
||||
0x03:蓝牙初始化异常
|
||||
0x04:电流故障恢复
|
||||
0x05:蓝牙故障恢复
|
||||
0x06:采样异常恢复
|
||||
0x07:继电器控制失败预留码
|
||||
```
|
||||
|
||||
电流故障需要持续至少10秒确认,恢复也需要持续至少10秒确认。默认电流阈值为100mA,支持动态配置并保存到EEPROM。
|
||||
|
||||
故障恢复上报需要等待主机确认;未收到确认时每10秒重复上报,直到收到确认。
|
||||
|
||||
### 8.2 OTA升级结果码
|
||||
|
||||
```text
|
||||
0x00:无结果
|
||||
0x01:升级成功
|
||||
0x02:固件CRC错误
|
||||
0x03:内部Flash写入失败
|
||||
0x04:写入后校验失败
|
||||
0x05:固件长度非法
|
||||
0x06:W25Q64读取失败
|
||||
```
|
||||
|
||||
主程序启动后读取升级结果,并使用:
|
||||
|
||||
```text
|
||||
CMD = 0x0D
|
||||
LEN = 0x01
|
||||
DATA = 升级结果码
|
||||
```
|
||||
|
||||
发送给主机。主机确认后,主程序清除结果字段。
|
||||
Reference in New Issue
Block a user