本测试验证 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,也不增加次数。
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
烧录后硬复位。先确认诊断可读:
python HostComputer\plsr_persistence_board_test.py --phase diagnostics
阶段状态默认保存在系统临时目录的 plsr_persistence_board_state.json;可用 --state-file 指定别处。
python HostComputer\plsr_persistence_board_test.py --phase hsd-prepare
脚本自动给四轴写入互不相同的已知位置,等待 HSD 检查点真正完成,并保存期望值。看到 PASS 后关闭主电源,保持 VBAT,等待数秒,再上主电并执行:
python HostComputer\plsr_persistence_board_test.py --phase hsd-verify
验收:四轴位置分别与脚本保存的期望值完全一致、四轴 position_valid=1、无脉冲输出、HSD load=OK、restored last busy=0。固件以四轴 position_valid 的保守 AND 写入全局元数据,单独校准一轴不会把其他未校准轴误判为可信。
python HostComputer\plsr_persistence_board_test.py --phase busy-prepare
脚本启动一个约 500 秒的长任务并确认端子正在输出。看到“运行中掉电已就绪”后,直接断主电或硬复位,不要发送 STOP。重启后执行:
python HostComputer\plsr_persistence_board_test.py --phase busy-verify
验收:所有轴 IDLE、无自动续跑、无输出、所有轴 position_valid=0,诊断显示 restored last busy=1。
验证固件的 P14/P17 自测准备会在启动后写入确定的 SFD RAM 配置并置 dirty;正式固件也可由正常参数配置入口置 dirty。执行一次:
python HostComputer\plsr_persistence_board_test.py --phase sfd-save
脚本只发送一次 SAVE_CONFIG。若 SFD dirty,要求 generation 前进、save_count 只增加 1、CRC 非零;若 SFD 已 clean,则要求 SAVE 正确 no-op,绝不重复擦写。随后硬复位或掉电重启,再执行:
python HostComputer\plsr_persistence_board_test.py --phase sfd-verify
验收:启动时 SFD load=OK,选中槽的 generation 与 CRC 和保存阶段完全一致。
python HostComputer\plsr_persistence_board_test.py --phase motion-save-busy
脚本启动长任务,只发送一次 SAVE_CONFIG,要求内核执行结果为 BUSY 且 SFD save_count 不增加,随后自动 STOP_IMMEDIATE 清理。该测试不要求逻辑分析仪,但应观察运动过程中没有因 Flash 擦除产生输出停顿。
正常构建的 PLSR_ENABLE_DESTRUCTIVE_PERSISTENCE_DIAG=0,请求一定返回 NOT_SUPPORTED。只有专用验证构建显式改为 1 时才允许使用。固件仍会同时检查:
执行还需要主机侧双重显式确认:
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 模拟测试替代为上述真实掉电证据。