# 0x43 奇数地址任意数量读取实现计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 让私有功能码 `0x43` 从第一个不小于起始基准地址的奇数地址开始,按地址 `+2` 读取 `1..123` 个寄存器,并允许请求数量为奇数或偶数。 **Architecture:** 保持现有 `0x43` 帧格式和从站地址步进算法不变,只移除主从两端“数量必须为奇数”的限制。PLC 从站负责最终的数量、地址范围和响应容量校验;TouchWin 在发送前执行同样的边界校验,并按实际数量解析响应。 **Tech Stack:** C、STM32F407、uC/OS-II、IAR EWARM 8.3、TouchWin C 函数、Modbus RTU 私有功能码 `0x43`。 ## Global Constraints - `0x43` 是本项目私有功能码,不属于标准 Modbus 功能码。 - 起始基准地址为偶数时先加 `1`,为奇数时保持不变。 - 后续读取地址每次增加 `2`。 - 数量范围为 `1..123`,奇数和偶数均合法。 - 数量为 `0` 或大于 `123` 返回异常码 `0x03`;最后一个读取地址越过 `0x270F` 返回异常码 `0x02`。 - 不恢复或新增仓库内的测试工程和测试文件。 --- ### Task 1: 主从数量校验修正 **Files:** - Modify: `Core/Modbus/modbus.c:730` - Modify: `document/TouchWin自组Modbus功能码函数.md:13` - Modify: `document/TouchWin自组Modbus功能码函数.md:151` **Interfaces:** - Consumes: `0x43 ` 请求 PDU。 - Produces: `0x43 ` 响应 PDU,数据地址依次为 `firstOddAddress + registerOffset * 2`。 - [x] **Step 1: 运行修改前的失败检查** 运行以下 PowerShell 检查,确认当前 TouchWin 代码仍包含偶数数量拒绝条件,同时从站还残留已注释的旧条件: ```powershell $slave = Get-Content -Raw -Encoding UTF8 Core/Modbus/modbus.c $hmi = Get-Content -Raw -Encoding UTF8 document/TouchWin自组Modbus功能码函数.md if (($slave -match 'registerCount & 0x0001U') -or ($hmi -match 'registerCount & 1')) { throw '仍存在奇数数量限制' } ``` Expected: FAIL with `仍存在奇数数量限制`。 - [x] **Step 2: 清理从站旧条件并保持地址算法** 将从站数量校验保留为: ```c if ((registerCount == 0U) || (registerCount > MODBUS_MAX_ODD_COUNT_REGISTER_COUNT)) { return MODBUS_REQUEST_ILLEGAL_VALUE; } ``` 保留以下奇数地址计算: ```c firstOddAddress = (uint16_t)(startAddress | 0x0001U); readAddress = (uint16_t)(firstOddAddress + (registerOffset * 2U)); ``` - [x] **Step 3: 移除 TouchWin 偶数数量拒绝条件** 发送条件改为: ```c if ((registerCount != 0) && (registerCount <= MODBUS_ODD_COUNT_MAX) && (firstOddAddress <= MODBUS_ADDRESS_MAX) && (registerCount <= (((MODBUS_ADDRESS_MAX - firstOddAddress) / 2) + 1))) ``` 同时把数量说明改为 `1..123`,奇数和偶数均可;示例中明确数量 `4` 返回地址 `1、3、5、7`,数量 `122` 为合法请求。 - [x] **Step 4: 运行无持久测试文件的通过检查** 重新运行 Step 1 命令。 Expected: PASS,命令退出码为 `0`。 ### Task 2: 项目说明同步 **Files:** - Modify: `docs/项目设计.md:112` **Interfaces:** - Consumes: Task 1 确认的 `0x43` 行为。 - Produces: 与生产代码一致的项目设计说明。 - [x] **Step 1: 更新功能表** 将 `0x43` 说明改为:从不小于起始基准地址的第一个奇数地址开始,每隔 `2` 读取一个值;数量允许 `1..123`,奇偶均可。 - [x] **Step 2: 检查项目文档冲突** ```powershell Get-ChildItem docs,document -Recurse -File -Include *.md | Where-Object FullName -NotLike '*superpowers\\plans*' | Select-String -Pattern '数量必须为奇数|只能输入奇数|数量为偶数.*异常码' ``` Expected: 项目交付文档中没有旧规则命中。 ### Task 3: 构建与边界验证 **Files:** - Verify: `Core/Modbus/modbus.c` - Verify: `Core/Modbus/modbus.h` - Verify: `EWARM/Modbus.ewp` **Interfaces:** - Consumes: Task 1 和 Task 2 的完整修改。 - Produces: 可由 IAR 构建并可供 TouchWin 联调的固件。 - [x] **Step 1: 检查关键边界** 核对以下结果: ```text start=0, count=2 -> 1, 3 start=0, count=4 -> 1, 3, 5, 7 start=5, count=2 -> 5, 7 start=0, count=123 -> 1, 3, ..., 245 count=0 -> exception 0x03 count=124 -> exception 0x03 start=0x270E,count=1 -> 0x270F start=0x270E,count=2 -> exception 0x02 ``` - [x] **Step 2: IAR 全量构建** ```powershell & 'E:\IAR\common\bin\iarbuild.exe' ` 'D:\xinjiedianqi\Study\TrainCamp_zengbingjie_Modbus\Modbus\EWARM\Modbus.ewp' ` '-build' 'Modbus' '-log' 'info' '-parallel' '4' ``` Expected: `Total number of errors: 0` and `Total number of warnings: 0`。 - [x] **Step 3: 审查最终差异** ```powershell git diff -- Core/Modbus/modbus.c document/TouchWin自组Modbus功能码函数.md docs/项目设计.md git diff --cached -- Core/Modbus/modbus.c ``` Expected: 只包含本次 `0x43` 规则修正以及用户已有的相关暂存修改,不恢复 `test/`。