# PLSR HSD/SFD 真机持久化验收 本测试验证 STM32F407 板上的真实 Backup SRAM/VBAT 和单 Bank Flash 行为。脚本默认使用 `COM5`,阶段之间由操作者真实断主电或硬复位,不用软件复位代替掉电。 ## 固件与诊断窗口 当前控制窗口为 D1200~D1537,D1470~D1499 是只读持久化快照;新增的D1516~D1537 USB诊断块不会移动持久化地址。固件只在 HSD/SFD 的加载、保存、擦除或显式破坏性诊断时计算 CRC;1ms 的 `PlsrModbusControlPoll()` 只复制缓存结果,不扫描 Backup SRAM/Flash,因此不会重新引入 P16 热点。 | 地址 | 内容 | | --- | --- | | D1470~D1471 / D1498~D1499 | 一致性 generation(首尾相同且为偶数) | | D1472 | 持久化诊断版本,当前 V1 | | D1473 | 低字节 HSD valid mask,高字节 SFD valid mask | | D1474 | 低字节 HSD newest mask,高字节 SFD newest mask | | D1475 | bit0 HSD dirty;bit1 SFD dirty;bit2 restored position valid(四轴位置均有效时才为1);bit3 restored last busy;bit4 破坏性诊断已编译启用 | | D1476~D1480 | HSD/SFD last load、last save、last erase 结果 | | D1482~D1489 | HSD A/B 与 SFD A/B generation | | D1490~D1493 | 本次上电后成功 HSD/SFD 实际保存次数 | | D1494~D1497 | 当前选中 HSD/SFD 记录的已存 CRC32 | `save_count` 只在真正完成记录提交时增加。SFD 为 clean 时执行 SAVE 是 no-op,不擦 Flash,也不增加次数。 ## 依赖与烧录 ```powershell py -m pip install -r HostComputer\requirements.txt & 'F:\IAR Systems\Embedded Workbench 8.3\common\bin\IarBuild.exe' ` 'EWARM\Modbus.ewp' -build Modbus -log warnings ``` 烧录后硬复位。先确认诊断可读: ```powershell python HostComputer\plsr_persistence_board_test.py --phase diagnostics ``` 阶段状态默认保存在系统临时目录的 `plsr_persistence_board_state.json`;可用 `--state-file` 指定别处。 ## 1. HSD + VBAT 正常停机恢复 ```powershell python HostComputer\plsr_persistence_board_test.py --phase hsd-prepare ``` 脚本自动给四轴写入互不相同的已知位置,等待 HSD 检查点真正完成,并保存期望值。看到 PASS 后关闭主电源,保持 VBAT,等待数秒,再上主电并执行: ```powershell python HostComputer\plsr_persistence_board_test.py --phase hsd-verify ``` 验收:四轴位置分别与脚本保存的期望值完全一致、四轴 `position_valid=1`、无脉冲输出、HSD load=OK、restored last busy=0。固件以四轴 `position_valid` 的保守 AND 写入全局元数据,单独校准一轴不会把其他未校准轴误判为可信。 ## 2. 运行中掉电/复位安全恢复 ```powershell python HostComputer\plsr_persistence_board_test.py --phase busy-prepare ``` 脚本启动一个约 500 秒的长任务并确认端子正在输出。看到“运行中掉电已就绪”后,直接断主电或硬复位,不要发送 STOP。重启后执行: ```powershell python HostComputer\plsr_persistence_board_test.py --phase busy-verify ``` 验收:所有轴 IDLE、无自动续跑、无输出、所有轴 `position_valid=0`,诊断显示 restored last busy=1。 ## 3. SFD Flash A/B + CRC 上电恢复 验证固件的 P14/P17 自测准备会在启动后写入确定的 SFD RAM 配置并置 dirty;正式固件也可由正常参数配置入口置 dirty。执行一次: ```powershell python HostComputer\plsr_persistence_board_test.py --phase sfd-save ``` 脚本只发送一次 SAVE_CONFIG。若 SFD dirty,要求 generation 前进、save_count 只增加 1、CRC 非零;若 SFD 已 clean,则要求 SAVE 正确 no-op,绝不重复擦写。随后硬复位或掉电重启,再执行: ```powershell python HostComputer\plsr_persistence_board_test.py --phase sfd-verify ``` 验收:启动时 SFD load=OK,选中槽的 generation 与 CRC 和保存阶段完全一致。 ## 4. 运动中禁止 Flash 擦写 ```powershell python HostComputer\plsr_persistence_board_test.py --phase motion-save-busy ``` 脚本启动长任务,只发送一次 SAVE_CONFIG,要求内核执行结果为 BUSY 且 SFD save_count 不增加,随后自动 `STOP_IMMEDIATE` 清理。该测试不要求逻辑分析仪,但应观察运动过程中没有因 Flash 擦除产生输出停顿。 ## 5. 可选 A/B 回退破坏性测试 正常构建的 `PLSR_ENABLE_DESTRUCTIVE_PERSISTENCE_DIAG=0`,请求一定返回 NOT_SUPPORTED。只有专用验证构建显式改为 1 时才允许使用。固件仍会同时检查: - 两个固定 magic; - 非零 sequence 及其 32 位反码; - 固定 arm 字; - 所有轴 idle 且无输出; - 目标介质必须已有两个 CRC 有效槽; - 只能失效 newest 槽,协议不接受任意 Flash/内存地址。 执行还需要主机侧双重显式确认: ```powershell python HostComputer\plsr_persistence_board_test.py ` --phase invalidate-sfd ` --allow-destructive ` --confirm INVALIDATE-NEWEST-SLOT ``` HSD 对应用 `--phase invalidate-hsd`。失效后应只剩一个有效槽;立即重启/LOAD,确认回退到旧 generation。测试结束务必恢复默认宏并重新烧录生产固件。 ## 记录要求 每个阶段保存完整终端输出,至少记录 valid mask、selected generation、CRC、save_count、last load/save 结果和 flags。掉电阶段同时记录 VBAT 是否保持、断电时长、复位方式与上电时间。不得把 Host 模拟测试替代为上述真实掉电证据。