# 协议架构说明 ## 1. 分层原则 小程序当前把链路、协议、功能服务和页面视图拆开处理: ```text BLE 透传链路 transport/ble-core.js transport/ble-utils.js 协议层 protocols/modbus-rtu/index.js protocols/storage-access/index.js protocols/bootloader/index.js 领域模型 domain/parameter-groups/ domain/storage-access/ 功能服务 features/manual-rtu/ features/storage-access/ features/parameter-groups/ features/communication/ features/bootloader/ features/tools/ 页面 pages/home/ pages/communication/ pages/params/ pages/settings/ ``` 协议层只负责帧格式、CRC、请求/响应解析和分片能力,不直接操作页面状态。 功能服务负责把协议层组合成业务动作,例如手动生成 Modbus 帧、同步 code 信息块、读取参数组、串口原始发送。 页面只负责展示、输入、按钮状态和用户反馈。 功能服务和传输层只依赖每套协议的入口文件: - `protocols/modbus-rtu/index.js` - `protocols/storage-access/index.js` - `protocols/bootloader/index.js` 协议层保持一个协议一个文件。`index.js` 内部可以继续暴露 `response`、`client` 这类逻辑分组对象,但不要重新拆出协议内部的 `frame.js`、`response.js`、`client.js` 给功能层引用。 协议模式配置由 `store/settings-store.js` 统一维护,内部 key 使用协议目录名: - `storage-access`:存储访问协议。 - `modbus-rtu`:标准 Modbus RTU。 页面层使用 `isStorageAccessProtocol`、`isModbusProtocol` 这类展示布尔字段,业务判断由 settings store 的协议判断函数生成。 历史配置字段只允许在 `store/settings-store.js` 的归一化入口迁移,例如旧的 `modbusProtocolMode`、`genericModbusMaxPacketLength` 会映射到新的 `protocolMode`、`parameterMaxPacketLength`。页面和功能服务不直接读取旧字段。 ## 2. 传输层 目录:`transport/` 职责: - `ble-core.js`:BLE 扫描、连接、通知订阅、发送队列、响应等待、收发日志和页面订阅状态。 - `ble-utils.js`:BLE 设备识别、目标 UUID 判断、包长推断、HEX/ArrayBuffer 转换、错误文案和特征值展示文本等纯工具。 - `ble-logs.js`:收发日志项构造、日志数量裁剪和清空日志状态。 - `ble-device-registry.js`:扫描设备合并、排序、清空、连接标记和 RSSI 展示更新。 - `protocol-helper-registry.js`:传输层协议 helper 的配置、懒加载和函数归一化。 传输层只处理蓝牙透传链路,不直接理解标准 Modbus 或存储访问协议的业务语义。响应解析通过 `configureProtocolHelpers` 注入协议 helper,由协议层决定如何识别完整回复帧。 ## 3. 协议层 ### 3.1 标准 Modbus RTU 入口:`protocols/modbus-rtu/index.js` 职责: - 生成标准 Modbus RTU 请求帧。 - 校验 Modbus CRC。 - 解析标准 Modbus 响应。 - 支持标准功能码 `0x01`、`0x02`、`0x03`、`0x04`、`0x05`、`0x06`、`0x10`。 - 地址和数量按标准 Modbus 寄存器或线圈语义处理。 标准 Modbus 不读取 `info` 区,也不解析 `Modbus_Code_Info_t`。 ### 3.2 存储访问协议 入口:`protocols/storage-access/index.js` 职责: - 普通读写生成 `CMD ADDR LEN DATA CRC` 格式的存储访问帧。 - `0x0F info` 也使用 `CMD ADDR LEN DATA CRC` 格式,按普通只读响应解析。 - 使用 `CRC16-CCITT-FALSE`。 - 地址单位始终是字节。 - 长度单位始终是字节。 - 普通读写支持区域: - `0x01 data` - `0x02 idata` - `0x03 xdata` - `0x04 code` - `0x0F info` 是只读同步区域,不作为普通变量区域写入。 - `code` 和 `info` 均为只读区域。 - `0x0F info` 当前读取 `ADDR=0x0000`、`LEN=0x0004`,返回数据为 code 区关键信息块的地址和长度。 - 读取完整 code 信息块时,通过 `AREA=0x04 code` 按最大包长分片读取。 完整帧格式见 `存储访问协议.md`。 ### 3.3 Bootloader 入口:`protocols/bootloader/index.js`、`features/bootloader/` 职责: - 保留独立升级协议。 - 不依赖 Modbus RTU。 - 不依赖存储访问协议。 - 升级工具仍在设置页的工具区入口中维护。 当前模块边界: - `protocols/bootloader/index.js`:Bootloader 帧构建、CRC、响应解析、ACK/NAK 校验。 - `features/bootloader/service.js`:设置页升级状态、握手流程、固件加载、擦除/编程/校验流程编排。 - `features/bootloader/firmware.js`:芯片型号识别、Flash 容量推断、固件大小校验和升级地址布局。 - `features/bootloader/transport.js`:Bootloader 原始帧发送、响应等待、断连中止和超时处理。 ## 4. 领域模型 ### 4.1 参数组 目录:`domain/parameter-groups/` 职责: - 定义参数组和寄存器/变量的标准数据结构。 - 支持标准 Modbus 寄存器组。 - 支持存储访问同步出来的结构体组。 - 支持字节地址变量、结构体字段、数组、bit field。 - 负责输入值、显示值、原始字节、原始字、数据类型转换。 参数组不是某一种协议的私有模型。标准 Modbus 和存储访问协议都会把可读写数据落到参数组模型上。 当前模块拆分: - `constants.js`:寄存器类型、数据类型、布局类型、地址上限和导入导出字段白名单。 - `model.js`:参数组/寄存器规范化、地址布局、导入克隆和对外领域 API。 - `register-io.js`:寄存器读缓存解码、写入值编码、组级字节/字编码和读写分片计算。 - `value-types.js`:数据类型元数据、字节/字长度、bit field 长度、类型分类和显示能力判断。 - `value-text.js`:ASCII/UTF-8 文本字段的字节编码、尾部 0 裁剪和解码。 - `value-number.js`:整数/HEX/float 的解析、范围校验、显示格式化和大端字节转换。 - `value-codec.js`:寄存器值编码解码、文本/数值/float/bit field 转换、显示值和输入校验。 - `struct-parser.js`:C 结构体定义和结构体实例目录解析的对外入口。 - `struct-c-syntax.js`:注释剥离、类型别名、结构体查找、声明和 declarator 解析。 - `struct-layout.js`:结构体字段到参数寄存器的字节布局、数组展开、ASCII 字段和 bit field 展开。 ### 4.2 存储访问信息解析 目录:`domain/storage-access/` 职责: - 解析 code 区中的 `Modbus_Code_Info_t`。 - 从 `struct_table` 生成参数组初始结构。 - 根据 `mem_type` 映射到真实存储区域: - `0x01 DATA` - `0x02 IDATA` - `0x03 XDATA` - `0x04 CODE` - 不把 `0x0F INFO` 当成普通变量区域写入;同步时按普通只读响应解析 `0x0F` 回复。 ## 5. 功能服务 ### 5.1 手动 Modbus 指令 目录:`features/manual-rtu/` 职责: - 维护通讯页标准 Modbus 指令表单状态。 - 根据输入生成 Modbus RTU 帧。 - 支持写多个寄存器的多值输入。 - 发送后等待并格式化响应。 - 未连接蓝牙时仍允许生成帧;点击发送时再提示连接状态。 当前模块拆分: - `service.js`:通讯页标准 Modbus 表单状态、弹窗开关和发送动作。 - `frame-builder.js`:功能码列表、HEX 参数解析、标准 Modbus 帧生成、期望响应描述和回复文本格式化。 - `multiple-registers.js`:写多个寄存器时的数量规范化、字段生成、数据类型切换、值编码和输入校验。 ### 5.2 存储访问同步 目录:`features/storage-access/` 职责: - 读取 `0x0F info` 的 `ADDR=0x0000`、`LEN=0x0004` 并解析返回数据。 - 根据返回的地址和长度分片读取 `0x04 code` 中的完整信息块。 - 调用 `domain/storage-access` 解析结构体表。 - 将解析出的结构体组导入 `features/parameter-groups`。 ### 5.3 参数组服务 目录:`features/parameter-groups/` 职责: - 参数组持久化、导入、导出。 - 标准 Modbus 参数组读写。 - 存储访问结构体组读写。 - 自动轮询。 - 修改后焦点切换自动写入。 - 结构体定义导入后的字段补全。 存储访问协议下,参数组按字节地址读写;标准 Modbus 下,参数组按 Modbus 寄存器/线圈地址读写。 当前模块拆分: - `service.js`:参数组页面入口 API、导入导出、结构体补全和协议读写调度。 - `store.js`:参数组状态容器、初始化、订阅通知和本地持久化触发。 - `persistence.js`:参数组 JSON 存储、导入、导出。 - `import-merge.js`:导入去重、重复变量更新、聚合组变量合并。 - `struct-completion.js`:结构体定义解析后的实例匹配、字段补全、数组和 bit field 展开。 - `storage-access-io.js`:存储访问协议参数组读写、data/idata/xdata/code 区域映射、字节地址缓存和 bit field 读改写。 - `modbus-io.js`:标准 Modbus 参数组读写、线圈写入、多寄存器编码和按最大包长拆分写入。 - `state-mappers.js`:读取缓存和写入快照映射回参数组寄存器展示态。 - `poller.js`:按设置间隔轮询参数组。 - `view-model.js`:参数页展示态转换。 - `drag-view-model.js`:参数页寄存器拖拽排序的索引、位移和行样式计算。 - `dialog-handlers.js`:参数页新建/编辑参数组、寄存器信息弹窗和结构体解析交互处理器。 ### 5.4 通讯页服务 目录:`features/communication/` 职责: - 串口原始发送。 - 通讯页存储访问指令卡片。 - 日志显示模式转换。 - 根据设置中的协议模式显示对应的指令控制卡片。 ### 5.5 工具页服务 目录:`features/tools/` 职责: - 设置页工具入口导航。 - 汇总 CRC/哈希、滤波器、阻抗、贴片码、制冷、三相功率等工具的初始状态。 - 按工具域拆分设置页事件处理器。 当前模块拆分: - `navigation.js`:设置页工具入口、标题和视图识别。 - `page.js`:工具初始状态与页面事件处理器聚合入口。 - `handlers/common.js`:工具结果复制等通用事件。 - `handlers/crc.js`:CRC/哈希配置、输入、文件加载、计算和清空。 - `handlers/filter.js`:滤波器输入、单位切换、网络/响应切换和归一化。 - `handlers/reactance.js`:阻抗输入、单位切换、模式切换和归一化。 - `handlers/smd-code.js`:贴片电阻/电容代码类型、格式和输入。 - `handlers/refrigeration.js`:制冷单位换算模式和输入。 - `handlers/three-phase-power.js`:三相接法、功率/电气量输入和驱动字段维护。 ## 6. 页面职责 ### 6.1 首页 目录:`pages/home/` 职责: - 蓝牙扫描。 - 蓝牙连接。 - 显示连接状态。 首页不再承载 Modbus 指令生成。 ### 6.2 通讯页 目录:`pages/communication/` 布局顺序: 1. 串口发送卡片。 2. 当前协议对应的指令卡片。 3. 收发日志。 标准 Modbus 模式显示 Modbus 指令卡片。 存储访问模式显示同步、读取、写入指令卡片。 ### 6.3 参数页 目录:`pages/params/` 职责: - 展示参数组列表。 - 存储访问模式下通过同步按钮生成结构体组。 - 存储访问模式下通过轮询读取结构体组。 - 修改字段后在焦点切换时自动下发。 - 标准 Modbus 模式下保留新建参数组、读组、写组能力。 参数页不再包含手动 Modbus 指令窗口。 ### 6.4 设置页 目录:`pages/settings/` 职责: - 协议模式选择。 - 从机地址配置。 - 参数轮询间隔和最大包长配置。 - Bootloader 升级。 - CRC、滤波、SMD、制冷、三相功率等工具入口。 ## 7. 数据流 ### 7.1 存储访问同步数据流 ```text 用户点击同步 pages/params 或 pages/communication -> features/storage-access/service.syncCodeInfo -> protocols/storage-access/index.js readCodeInfoBlock -> 读取 AREA=0x0F ADDR=0x0000 LEN=0x0004 -> 按普通读响应解析 DATA 中的 code 地址和长度 -> 读 AREA=0x04 ADDR=CODE_ADDR LEN=CODE_LEN -> domain/storage-access/code-info-parser.parseCodeInfo -> domain/storage-access/code-info-parser.createGroupsFromCodeInfo -> features/parameter-groups/service.mergeImportedGroups ``` ### 7.2 存储访问参数读取数据流 ```text 参数组轮询或手动读取 -> features/parameter-groups/service.readGroup -> features/storage-access/memory-service.readMemory -> protocols/storage-access/index.js readMemory -> AREA 使用结构体表中的 mem_type -> ADDR 使用结构体实例字节地址 -> LEN 使用结构体实例字节长度 ``` ### 7.3 标准 Modbus 指令数据流 ```text 通讯页填写指令 -> features/manual-rtu/service 生成标准 Modbus RTU 帧 -> transport/ble-core.js 下发 -> protocols/modbus-rtu/index.js 解析回复 -> 通讯页显示回复与日志 ``` ## 8. 维护约束 1. 不要把存储访问协议挂到 Modbus RTU 协议目录下。 2. `0x0F info` 只作为只读同步区域,必须按普通读响应校验 CMD、ADDR、LEN、DATA 和 CRC。 3. 存储访问协议的地址和长度始终按字节处理。 4. 标准 Modbus 的地址和数量始终按标准寄存器/线圈语义处理。 5. 参数组模型保持协议中立。 6. Bootloader 升级和工具页保持独立,不随参数协议重构删除。 7. 新功能优先放到对应协议或 feature 模块,不直接写进页面。