本项目在同一条 BLE 透传链路上支持四种工作模式。模式由设置页 protocolMode 控制,通讯页和参数页会按当前模式切换 UI、参数分组和自动读取协议。
| 模式 | key | 通讯页 | 参数页 | 说明 |
|---|---|---|---|---|
| 无协议 | none |
串口发送卡片、日志卡片 | 不显示协议参数组 | 只做原始字节透传和日志观察 |
| 标准 Modbus | modbus-rtu |
标准 Modbus 指令卡片、日志卡片 | Modbus 寄存器组 | 使用从机地址、功能码和 Modbus CRC |
| 存储访问 | storage-access |
同步、CodeInfo、特殊指令、读写卡片、日志卡片 | 存储访问结构体组/单变量组 | 按字节访问 DATA、IDATA、XDATA、CODE 或 32 位统一地址空间 |
| Bootloader | 设置页升级工具 | Bootloader 工具卡片 | 不参与参数页 | 独立升级协议,不和 Modbus/存储访问混用 |
切换协议时,参数页会同步切换对应协议的分组集合。自动读取运行中如果检测到协议变化,会停止当前读取循环,避免用旧协议继续访问新模式下的参数组。
所有协议均通过 BLE 透传发送原始字节。发送队列、响应等待、日志和超时由 transport/ble-core.js 统一处理。
| 项目 | 规则 |
|---|---|
| 发送单位 | 原始字节数组 |
| 日志显示 | HEX 或文本两种显示方式 |
| 响应识别 | 由 protocols/transport-helpers.js 根据待响应协议调用对应解析器 |
| 包长限制 | 设置页最大包长用于 Modbus 和存储访问分片,0 表示不限制 |
| 参数自动读取 | 由设置页“自动轮询”开关控制,参数页“读取”只执行一次全量读取 |
无协议模式不解析帧格式,也不绑定参数页分组。
| 功能 | 行为 |
|---|---|
| 发送 | 通讯页原始串口发送卡片支持 HEX 或文本 |
| 日志 | 显示发送和接收日志 |
| 响应 | 不要求特定响应帧 |
| 参数页 | 不显示标准 Modbus 或存储访问参数组 |
适用场景:临时调试私有串口命令、观察设备透传输出、验证蓝牙链路连通性。
标准 Modbus 使用常规 RTU 帧格式:
SLAVE FUNC DATA... CRC_L CRC_H
CRC 使用 CRC16-Modbus,低字节在前。
| 参数 | 值 |
|---|---|
| 多项式 | 0x8005 反射形式 |
| 初值 | 0xFFFF |
| 输入反转 | 是 |
| 输出反转 | 是 |
| 结果异或 | 0x0000 |
| 输出顺序 | 低字节在前 |
支持功能码:
| 功能码 | 名称 | 方向 | 参数页用途 |
|---|---|---|---|
0x01 |
读线圈 | 读 | bit/coil 类型参数组 |
0x02 |
读离散输入 | 读 | 只读 bit 类型参数组 |
0x03 |
读保持寄存器 | 读 | 可读写寄存器组 |
0x04 |
读输入寄存器 | 读 | 只读寄存器组 |
0x05 |
写单线圈 | 写 | 单个 bit 写入 |
0x06 |
写单寄存器 | 写 | 单个 16 位寄存器写入 |
0x10 |
写多个寄存器 | 写 | 连续寄存器批量写入 |
数量限制按当前最大包长计算。默认 64 字节包长下,0x03/0x04 单帧最多读取 29 个寄存器,0x10 单帧最多写入 27 个寄存器。超过限制时参数页会按连续片段分片读取或写入。
异常响应格式:
SLAVE (FUNC | 0x80) EXCEPTION_CODE CRC_L CRC_H
标准 Modbus 与存储访问完全独立,不解析 CodeInfo TLV 信息块,也不使用存储访问的 CMD/AREA。
存储访问协议不带从机地址,不属于标准 Modbus。普通内存访问帧格式为:
CMD ADDR LEN DATA... CRC_H CRC_L
CRC 使用 CRC16-CCITT-FALSE,高字节在前。所有多字节协议字段均为大端序。
CMD 位定义:
bit7 ERR 故障标志,仅回帧出现
bit6 SPECIAL 特殊指令标志位
bit5~bit4 RSV 保留,普通读写保持 0
bit3 RW 普通读写标志,0=读,1=写
bit2~bit0 MODE 普通读写区域码
地址模式与存储区域:
| MODE | 名称 | 地址宽度 | 读 | 写 | 说明 |
|---|---|---|---|---|---|
0x00 |
CODEINFO | 16 位 | 支持 | 禁止 | 同步时读取一次,返回 TLV 起始地址与长度 |
0x01 |
DATA | 16 位 | 支持 | 支持 | 内部直接寻址 RAM |
0x02 |
IDATA | 16 位 | 支持 | 支持 | 内部间接寻址 RAM |
0x03 |
XDATA | 16 位 | 支持 | 支持 | 外部数据空间或扩展 RAM |
0x04 |
CODE | 16 位 | 支持 | 禁止 | 程序存储区 |
0x05..0x06 |
保留 | - | 禁止 | 禁止 | 保留 |
0x07 |
ADDR32 | 32 位 | 支持 | 支持 | 统一 32 位字节地址 |
普通读请求:
CMD ADDR_3 ADDR_2 ADDR_1 ADDR_0 LEN_H LEN_L CRC_H CRC_L
或
CMD ADDR_H ADDR_L LEN_H LEN_L CRC_H CRC_L
普通读响应回显 CMD、ADDR、LEN,然后携带 LEN 字节数据。
普通写请求:
CMD ADDR_3 ADDR_2 ADDR_1 ADDR_0 LEN_H LEN_L DATA... CRC_H CRC_L
或
CMD ADDR_H ADDR_L LEN_H LEN_L DATA... CRC_H CRC_L
普通写响应只回显 CMD、ADDR、LEN。写 CODEINFO 或 CODE 区必须返回写保护异常。
特殊指令使用 CMD bit6=1:
请求: CMD DATA... CRC_H CRC_L
响应: CMD DATA... CRC_H CRC_L
异常: CMD_ERR EXCEPTION_CODE CRC_H CRC_L
特殊指令表:
| 指令码 | CMD | 名称 | 请求 DATA | 成功响应 DATA | 用途 |
|---|---|---|---|---|---|
0x01 |
0x41 |
RESET | 无 | 无 | 复位 |
完整帧细节、异常码、示例和从机参考见 存储访问协议.md。
存储访问同步固定分两步:
00 CRC_H CRC_L 读取 area=0x00 CODEINFO 描述符,数据区为 TLV_ADDR32 + TLV_LEN16 + ADDR_WIDTH8 + MAX_PACKET16。ADDR_WIDTH=16 使用 CODE 区 16 位地址,ADDR_WIDTH=32 使用 ADDR32。多字节协议控制字段始终固定大端,包括 CMD、ADDR、普通读写 LEN、描述符 TLV_LEN 和 MAX_PACKET;TLV LEN 为单字节字段,不涉及大小端。当前目标内存变量的多字节值默认按大端解码和写入。
CodeInfo 信息块使用纯 TLV 格式,不再包含固定头、format_version、board_info_format、struct_entry_len 或 struct_table:
TYPE LEN VALUE...
常用 TLV:
| TYPE | 名称 | VALUE |
|---|---|---|
0x01 |
DATA 结构体实例 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x02 |
DATA 单独变量 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x03 |
IDATA 结构体实例 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x04 |
IDATA 单独变量 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x05 |
XDATA 结构体实例 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x06 |
XDATA 单独变量 | byte_addr16 + byte_len16 + name[32],LEN=0x24 |
0x07 |
ADDR32 结构体实例 | byte_addr32 + byte_len16 + name[32],LEN=0x26 |
0x08 |
ADDR32 单独变量 | byte_addr32 + byte_len16 + name[32],LEN=0x26 |
0x20..0x3F |
自定义 TLV | 上位机保留原始项,当前跳过业务解析 |
0x40.. |
板卡参数 | 0x40 起按 cave_freq/ref_volt/... 递增 |
TLV LEN 为 1 字节,表示单项 VALUE 字节数;整段 CodeInfo 总长度仍由 CODEINFO 描述符 TLV_LEN16 决定。内存入口 TLV 的地址宽度和区域由 TYPE 决定,名称字段固定 32 字节。
同步到参数页后的规则:
| 条件 | 处理 |
|---|---|
TYPE=0x01/0x03/0x05/0x07 且未导入结构体定义 |
创建结构体组,每个字节按 00、01、02 命名 |
TYPE=0x01/0x03/0x05/0x07 且导入定义名、长度匹配 |
按 C 结构体字段展示,保留多字节字段整体值;字段类型为 enum 时按枚举项显示 |
TYPE=0x02/0x04/0x06/0x08 |
创建单变量组,byte_len 只定义长度;未配置前显示原始字节,UI 需选择同长度的有符号/无符号整数或 float,匹配 enum 后按枚举项显示 |
| 相同名称但地址或区域不同 | 视为不同参数组 |
| 当前已有同区域、同地址、同名称、同长度且已导入定义 | 保留当前导入结构,只更新同步来源信息 |
未知 TLV TYPE |
跳过 |
结构体和 enum 可在同一个 .h/.c/.txt 定义文件中导入。单独变量的 enum 匹配支持两种方式:入口 name 直接等于 enum 类型名,或导入文件中存在 EnumType variable_name; 且变量名等于入口 name。enum 只影响显示与输入映射,不改变底层字节读写协议。
CodeInfo 卡片始终显示在通讯页存储访问协议卡片内。板卡信息 TLV 不存在时对应字段不显示;电机型号优先按 UTF-8 解析,也兼容纯 ASCII。
参数页读回的数据先按字段类型解码为原始值,再根据可选转换公式显示实际值。公式由参数配置自定义,适合标幺值转实际值、比例缩放和偏置换算。
存储访问参数组的多字节变量值当前默认按大端解码和写入。标准 Modbus 寄存器仍保持 Modbus 字/字节规则,不受该字段影响。
公式支持变量:
| 变量 | 含义 |
|---|---|
x、value、rawValue |
当前字段原始值 |
caveFreq |
CodeInfo 载波频率 |
refVolt |
CodeInfo 参考电压实际值 |
ampGain |
CodeInfo 运放倍数 |
rsShunt |
CodeInfo 采样电阻 |
busDiv |
CodeInfo 母线电压分压比 |
alongDiv |
CodeInfo 模拟输入电压分压比 |
maxPacketLength |
当前同步上下文的最大完整协议帧长度,未声明时为 0 |
addressWidth |
CodeInfo 本体读取地址长度,当前固定为 32 |
memoryEndian |
当前目标内存变量字节序,默认 big |
公式只支持数字、括号和 + - * /,不执行任意脚本。
Bootloader 协议用于固件升级,独立于标准 Modbus 和存储访问。帧头固定为:
46 54 PAYLOAD... CRC_H CRC_L
CRC 使用 CRC16-CCITT-FALSE,高字节在前。
主要命令:
| 命令 | 载荷 | 响应长度 | 用途 |
|---|---|---|---|
| 握手 | 39 42 4C |
15 | 读取 Bootloader 版本和芯片 ID |
| 解锁 | 08 4E 00 |
8 | 进入可编程状态 |
| 编程 | 44 ADDR_L ADDR_H DATA(128B) |
8 | 写入 128 字节程序块 |
| 全 Flash 校验 | 19 43 43 |
9 | 读取 Flash 校验值 |
| 页擦除开关 | 08 50 45/44 |
8 | 开启或关闭页擦除 |
| 退出 | 08 42 42 |
8 | 退出 Bootloader |
ACK 为 0x06,NAK 为 0x15。固件文件加载、芯片型号识别、升级地址和 Flash 容量由 features/bootloader/ 处理。
protocols/modbus-rtu/index.js、protocols/storage-access/index.js、protocols/bootloader/index.js。features/communication/,参数页业务聚合在 features/parameter-groups/,存储访问业务聚合在 features/storage-access/service.js。domain/parameter-groups/ 和 domain/storage-access/。