1
0

协议架构说明.md 13 KB

协议架构说明

1. 总体边界

小程序按“链路、协议、领域模型、功能服务、页面”分层。页面只做展示和事件转发;协议层只处理帧格式和响应解析;功能服务负责把协议动作组合成业务流程;领域模型负责参数组、结构体、数值编解码等纯数据逻辑。

BLE 透传链路
  transport/ble-core.js
  transport/ble-utils.js
  transport/ble-logs.js
  transport/ble-device-registry.js
  transport/protocol-helper-registry.js

协议层
  protocols/modbus-rtu/index.js
  protocols/storage-access/index.js
  protocols/bootloader/index.js
  protocols/transport-helpers.js

领域模型
  domain/parameter-groups/
  domain/storage-access/code-info-parser.js

功能服务
  features/communication/
  features/modbus-rtu/service.js
  features/storage-access/service.js
  features/parameter-groups/
  features/bootloader/
  features/tools/
  features/settings/
  features/home/service.js

页面
  pages/home/
  pages/communication/
  pages/params/
  pages/settings/

维护原则:

  1. 一个协议只保留一个协议入口文件,不再拆 frame.jsrequest.jsresponse.js 这类细粒度文件。
  2. 功能服务按页面或业务域聚合,不为每个按钮、每个弹窗再单独建模块。
  3. 领域模型可以按“值类型、编解码、结构体解析、参数组规范化”拆分,因为这些逻辑可测试且复用度高。
  4. 页面不直接拼协议帧,不直接读写本地存储格式。
  5. 设置页的协议模式只保留当前字段 protocolMode,不维护历史字段迁移逻辑。

2. 协议模式

协议模式常量由 domain/protocol-mode.js 统一定义,当前设置值由 store/settings-store.js 持久化维护:

key 页面名称 通讯页显示 参数页数据
none 无协议 串口发送卡片 + 日志 不显示协议参数组
storage-access 存储访问 同步、CodeInfo、特殊指令、读写卡片 + 日志 存储访问结构体组/单变量组
modbus-rtu 标准 Modbus 标准 Modbus 指令卡片 + 日志 Modbus 寄存器组

参数组按协议分别存储,切换协议时 features/parameter-groups/store.js 会切换当前参数组集合。自动读取/轮询运行时如果检测到协议切换,会停止当前协议的循环,避免用错误协议继续读写。

3. 传输层

目录:transport/

职责:

  • ble-core.js:蓝牙扫描、连接、通知订阅、发送队列、响应等待、收发日志、页面订阅。
  • ble-utils.js:BLE 设备识别、UUID 判断、包长推断、HEX/ArrayBuffer 转换、错误文案。
  • ble-logs.js:收发日志构造、裁剪和清空。
  • ble-device-registry.js:扫描设备合并、排序、连接标记和 RSSI 文案。
  • protocol-helper-registry.js:协议 helper 的懒加载和响应读取函数归一化。

传输层不知道业务含义,只通过 protocols/transport-helpers.js 调用当前协议的响应解析能力。

4. 协议层

4.1 标准 Modbus RTU

入口:protocols/modbus-rtu/index.js

职责:

  • 生成标准 Modbus RTU 请求帧。
  • 校验 Modbus CRC。
  • 解析标准 Modbus 响应和异常响应。
  • 计算单帧包长限制下的读取分片。
  • 支持功能码 0x010x020x030x040x050x060x10
  • 地址和数量按标准 Modbus 寄存器/线圈语义处理。
  • 不直接读取设置页从机地址,不直接调用 BLE 发送。

标准 Modbus 不解析 CodeInfo TLV 信息块,也不使用存储访问协议的 CMD/AREA

4.2 存储访问协议

入口:protocols/storage-access/index.js

职责:

  • 普通内存读写使用 CMD + ADDR + LEN + DATA + CRC16-CCITT-FALSE
  • LEN 固定 16 位,单位始终为字节。
  • CMD bit0~bit2 区分普通区域:0x00 为 CODEINFO 描述符,0x01..0x04 为 DATA/IDATA/XDATA/CODE 的 16 位地址,0x07 为 32 位地址,0x05..0x06 保留。
  • CMD bit3 为普通读写位,bit4/bit5 保留,bit6 为特殊指令位,bit7 为回帧故障标志。
  • 普通区域包括 CODEINFODATAIDATAXDATACODEADDR32,其中 CODEINFOCODE 只读。
  • 特殊指令使用 CMD=0x40 | special_code,当前仅定义 special_code=0x01 复位。
  • CodeInfo 同步先发送 00 + CRC 读取 area=0x00 CODEINFO,获取 TLV_ADDR32 + TLV_LEN16 + ADDR_WIDTH8 + MAX_PACKET16,再按 ADDR_WIDTH 用 CODE 或 ADDR32 读取完整信息块。
  • 协议控制字段始终固定大端;结构体字段和单独变量等目标内存值当前默认按大端编解码。
  • 不直接调用 BLE 发送,不负责弹窗;发包编排由 features/storage-access/service.js 处理。

完整帧格式和从机实现参考见 存储访问协议.md

4.3 Bootloader

协议入口:protocols/bootloader/index.js

功能服务:features/bootloader/

职责:

  • 保持独立升级协议,不依赖标准 Modbus 或存储访问协议。
  • protocols/bootloader/index.js 负责 Bootloader 帧构建、CRC、ACK/NAK 和响应解析。
  • features/bootloader/service.js 负责设置页升级状态、固件加载、握手、擦除、编程、校验流程。
  • features/bootloader/firmware.js 负责芯片型号识别、Flash 容量推断、固件大小校验和升级地址布局。
  • features/bootloader/transport.js 负责 Bootloader 原始帧发送、响应等待、断连中止和超时处理。

5. 领域模型

5.1 参数组模型

目录:domain/parameter-groups/

职责:

  • 定义参数组、寄存器、结构体字段、单变量的标准数据结构。
  • 规范化地址、数量、读写状态、显示值和来源元数据。
  • 支持标准 Modbus 寄存器/线圈组。
  • 支持存储访问字节地址组、结构体字段、单变量、数组、bit field。
  • 支持原始值到实际值的转换公式。

当前模块:

文件 职责
constants.js 寄存器类型、数据类型、布局类型、地址上限和导入导出字段白名单
model.js 参数组/寄存器规范化、地址布局、显示文案、导入克隆和领域 API
register-io.js 读缓存解码、写入编码、组级字节/字编码和分片辅助
value-types.js 数据类型元数据、字节/字长度、bit field 长度、类型分类
value-number.js 整数、HEX、float 的解析、范围校验和格式化
value-text.js ASCII/UTF-8 文本字段的编码和解码
value-codec.js 寄存器值编解码、显示值和输入校验
value-formula.js 读回标幺值到实际值的转换公式求值
struct-parser.js C 结构体与 enum 定义解析入口
struct-c-syntax.js C 注释剥离、typedef、struct、enum 和 declarator 解析
struct-layout.js 结构体字段布局、数组展开、ASCII 字段、enum 映射和 bit field 展开

5.2 CodeInfo 解析

入口:domain/storage-access/code-info-parser.js

职责:

  • 解析 CodeInfo 纯 TLV 信息块,未知 TLV 类型跳过。
  • 使用 CODEINFO 描述符返回的 TLV_LEN 决定 CodeInfo 总长度,并使用 ADDR_WIDTH/MAX_PACKET 作为同步上下文;内存入口地址宽度和区域由 TLV TYPE 自描述。
  • 解析 UTF-8/ASCII 电机型号、芯片型号和转换相关可选 TLV 参数。
  • 固定 TLV 0x01~0x08 映射真实存储区域、地址宽度和结构体/变量类型,并按结构体、单独变量成对排列;VALUE 固定为 addr(2/4) + byte_len16 + name[32]
  • 0x20~0x3F 为自定义 TLV,板卡参数从 0x40 开始递增。
  • 生成参数组初始结构,结构体未导入定义时按字节占位,单独变量按 TLV byte_len 显示为未配置原始字节,后续由 UI 或 enum 导入确定同长度的解释类型。

6. 功能服务

6.1 通讯页服务

目录:features/communication/

当前模块:

文件 职责
index.js 通讯页功能聚合入口,显式导出页面需要的 API
manual-rtu.js 标准 Modbus 指令表单、写多个寄存器输入、帧生成、发送和响应文案
service.js 串口原始发送、存储访问普通读写、特殊指令下发
view-model.js 日志展示、串口/存储访问表单状态、协议模式展示状态

无协议模式只显示串口发送和日志;标准 Modbus 模式只显示 Modbus 指令;存储访问模式只显示存储访问卡片。

6.2 存储访问服务

入口:features/storage-access/service.js

职责:

  • 包装 protocols/storage-access/index.js 的读写、特殊指令和 CodeInfo 同步能力。
  • 根据设置的最大包长决定分片长度。
  • 读取 area=0x00 CODEINFO 描述符,再按 ADDR_WIDTHarea=0x04 CODEarea=0x07 ADDR32 完整读取 CodeInfo。
  • 将解析结果转换为参数组。
  • 提供复位特殊指令。

6.3 标准 Modbus 服务

入口:features/modbus-rtu/service.js

职责:

  • 包装 protocols/modbus-rtu/index.js 的帧生成、响应期望和分片能力。
  • 读取设置页从机地址,并把地址错误统一转成浮层警告。
  • 通过 BLE 发送标准 Modbus 读写命令。
  • 聚合分片读取结果,供参数组读取、写入和自动读取复用。

6.4 参数组服务

目录:features/parameter-groups/

当前模块:

文件 职责
index.js 参数页功能聚合入口,显式导出页面需要的 API
service.js 参数组页面主 API、导入导出、结构体补全、读写调度
store.js 参数组状态容器、协议切换、本地持久化、CodeInfo 卡片状态
persistence.js 参数组 JSON 导入、导出和按协议本地存储
imports.js 导入合并、重复项识别、结构体/enum 定义补全和已有结构保留
io.js 标准 Modbus 和存储访问协议的参数组读写实现
poller.js 按设置自动读取当前协议的可读参数组
view-model.js 参数页展示态和弹窗状态
drag-view-model.js 参数页寄存器拖拽排序状态计算
dialog-handlers.js 新建/编辑参数组、寄存器信息弹窗、结构体解析交互

6.5 设置与工具服务

目录:features/settings/features/tools/

职责:

  • 设置页协议模式、主题、蓝牙状态、Bootloader 状态和工具页面状态聚合。
  • protocol-implementation.js 提供存储访问协议实现说明卡片和文件占位;从机源码暂未提供。
  • features/tools/index.js 聚合工具入口、工具导航、CRC/哈希、滤波、阻抗、贴片码、制冷、三相功率等工具状态和事件处理器。
  • 工具内部按工具域拆分,避免设置页脚本膨胀。

7. 页面职责

7.1 首页

目录:pages/home/

职责:蓝牙扫描、连接、断开、设备列表展示。

7.2 通讯页

目录:pages/communication/

职责:根据协议模式显示对应通讯卡片和收发日志。

7.3 参数页

目录:pages/params/

职责:展示参数组、读取、写入、导入导出、结构体补全、自动读取和拖拽排序。

7.4 设置页

目录:pages/settings/

职责:协议模式、从机地址、自动读取间隔、最大包长、协议实现说明、Bootloader 和工具入口。

8. 数据流

8.1 存储访问同步

用户点击同步
  -> pages/communication/communication.js
  -> features/parameter-groups/service.syncFromStorageAccessCodeInfo
  -> features/storage-access/service.syncCodeInfo
  -> features/storage-access/service.readCodeInfoBlock
  -> protocols/storage-access/index.js 构建普通读帧
  -> 发送 00 + CRC 读取 area=0x00 CODEINFO 描述符,获得 TLV_ADDR32 + TLV_LEN16 + ADDR_WIDTH8 + MAX_PACKET16
  -> 按描述符和设置页最大包长分片读取 CodeInfo TLV 信息块
  -> domain/storage-access/code-info-parser.parseCodeInfo
  -> domain/storage-access/code-info-parser.createGroupsFromCodeInfo
  -> features/parameter-groups/imports.mergeImportedGroups
  -> features/parameter-groups/store.setGroups

8.2 参数组读取

手动读取或自动读取
  -> pages/params/params.js
  -> features/parameter-groups/service.readGroup
  -> features/parameter-groups/io.readGroup
  -> 标准 Modbus: protocols/modbus-rtu/index.js
  -> 存储访问: features/storage-access/service.readMemory
  -> 读缓存映射回参数组显示态

8.3 参数组写入

输入完成或点击写入
  -> pages/params/params.js
  -> features/parameter-groups/service.writeRegister/writeGroup
  -> features/parameter-groups/io.writeRegister/writeGroup
  -> 标准 Modbus: 单寄存器/多寄存器写入
  -> 存储访问: 字节地址写入,bit field 使用读改写
  -> 写入快照映射回参数组显示态

9. 维护约束

  1. 不再按单个按钮、单个协议动作、单个导入步骤拆零碎模块,优先收敛到当前 feature service 和领域模型文件。
  2. 新增协议能力优先放入对应 protocols/*/index.js 和对应 feature service,不直接写进页面。
  3. 新增参数值类型时,同时更新 constants.jsvalue-types.jsvalue-codec.js 和必要的导入导出字段。
  4. 新增 CodeInfo 字段时,同时更新 domain/storage-access/code-info-parser.js存储访问协议.md
  5. 页面只通过 feature 入口或明确 service/view-model 文件调用业务逻辑。