25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

44 KiB

PLSR 2026 重写测试报告

测试日期:2026-08-12

测试分支:codex/plsr-2026-minimal

测试代码基线:bf314a2343002a3df78bce5049badb29d11eae2e

PLSR 实现提交:c7b851659ea26f9af8563e146bf5332c3c8d6dfd

分支起点:e35595aae18690a46a03445865bd6218a166bd89

结论口径:只记录本次 2026 PLSR 最小重写实际执行过的测试

1. 总结

本次重写的 Host 回归、Python 离线自检、IAR 全量构建、固件烧录、真实 Modbus RTU 板测、Y0~Y3 逐路选择、X4/X5 实体回环、硬复位持久化和最终默认状态复核均通过。

类别 最终结果 数量或关键结果
C Host 回归 PASS 44 个测试组,1,694,007 次断言,0 失败
Python 产品测试脚本离线自检 PASS 未打开串口
Python 控制面板离线自检 PASS 未打开 GUI 或串口
IAR EWARM 全量构建 PASS 0 errors,0 warnings
固件烧录和校验 PASS Verification...OK,SHA256 与板测固件一致
Modbus RTU/运动板测 PASS 9 组
X4/X5 实体回环板测 PASS 9 个用例
硬复位持久化 PASS 配置和位置恢复,运动不自动续跑
最终默认状态复核 PASS 位置、配置、输入和夹具输出均恢复
逻辑分析仪测试 未执行 不在本轮验收范围内

这里的“Y0~Y3 验证”是同一个逻辑 PLSR 依次选择 Y0、Y1、Y2、Y3 作为脉冲输出,不是四轴同时运动或四轴联动。

1,694,007 assertions 是逐脉冲检查、边界检查和随机算术比对产生的断言总数,不代表 169 万个独立测试场景。

2. 测试范围和口径

2.1 纳入本报告

  • 本次重写新增的固定产品寄存器区:0x1000~0x11970x2000~0x20060x3000
  • 单个逻辑 PLSR 的配置、状态、控制、运动、短段曲线、动态调频和停止。
  • 单个逻辑 PLSR 对 Y0~Y3 的逐路选择。
  • X4/X5 的 WAIT、EXT 和 EXT_OR_COMPLETE 实体输入回环。
  • 产品配置与逻辑位置的保存、硬复位恢复和默认值恢复。
  • 最小 Modbus RTU 的真实串口访问和异常响应。
  • 当前代码基线的 Host、Python、IAR 和固件产物复核。

2.2 不纳入本报告

旧工程曾做过的四轴并发、双 AB、软限位、长稳、USB CDC 并发和逻辑分析仪波形测试属于另一套实现,不能作为本次重写的通过证据,因此没有合并到本报告。

3. 环境与产物

项目 实际环境或结果
目标板 信捷 XDM-60T4-E,STM32F407IG
RTOS uC/OS-II
串口 COM5,9600 bit/s,8E1,从站 1
Host 编译器 GCC 4.9.2 (tdm64-1)
Host 编译选项 C99,-Wall -Wextra -WerrorPLSR_HOST_TEST
IAR EWARM 8.3.4,配置 Modbus
IAR 工程 EWARM/Modbus.ewp
HEX EWARM/Modbus/Exe/Modbus.hex
HEX 文本文件大小 142,131 B
Intel HEX 有效数据 50,513 B
HEX 地址范围 0x08000000..0x0800C550
SHA256 97956D9EF30A9B274140B9B82F412EDD77F9637F563FCC3F552BB4B140772343

IAR 链接结果:

49,004 bytes of readonly code memory
 1,509 bytes of readonly data memory
18,660 bytes of readwrite data memory
Errors: none
Warnings: none

4. 最终自动化回归

4.1 C Host 回归

执行命令:

powershell.exe -NoProfile -ExecutionPolicy Bypass `
  -File .\tests\plsr_host\run_tests.ps1

最终输出:

SUMMARY tests=44 assertions=1694007 failures=0

44 个测试组全部 PASS:

# 测试组 实际验证内容
1 u64_by_u32_division 用 8 个边界被除数、9 个边界除数和 250,000 组确定性伪随机数据,比对 64 位除 32 位算法与 C 原生除法的商和余数。
2 protocol_boundaries 覆盖区间外、跨区、地址溢出、零长度、空缓冲、只读区、保留字、32 位字段不完整写入、非法值和控制字宽度,并确认失败写入不破坏原值。
3 wait_zero_one_ms 验证 WAIT_TIME=0 按最小 1 ms 处理,先进入 WAITING,1 ms 后才进入下一段。
4 act_zero_no_pulse 验证 ACT_TIME=0 的段不产生脉冲并在下一次 1 ms 调度跳过,后续段正常执行。
5 relative_absolute_zero 验证相对位移 0、相对位移 +5,以及当前位置等于绝对目标时的零位移完成。
6 self_jump_stop 验证单段自跳转可循环运行,并能由 STOP 正常终止。
7 stop_deceleration 验证 STOP 从 1000 Hz 按 1000 ms 减速至 100 Hz 后停止;重复 STOP 不重启减速,最终位置 902。
8 stop_pending_boundary 验证最后脉冲已完成但 Poll 尚未处理时收到 STOP,最终为 STOPPED 而非 COMPLETED。
9 direction_delay_one_ms 验证 1 ms 方向建立延时结束前不输出脉冲,满 1 ms 后启动。
10 ext_edge_at_natural_boundary 验证 EXT 边沿和自然末脉冲同时发生时只处理一次,不重复切段或计数。
11 ext_cut_natural_boundary_interleavings 覆盖 EXT 切断与自然边界的两种临界交错顺序,均正确进入后续 2000 Hz 段。
12 ext_edge_during_direction_delay 验证方向延时期间的 EXT 边沿不会在首脉冲前错误切段。
13 stopped_clears_pending_ext 验证 STOP 清除方向延时期间挂起的 EXT 边沿,重新 START 不消费旧边沿。
14 ext_edge_seamless_epoch 验证上一段的 EXT 竞态不会误切无缝衔接后的下一段。
15 ramp_seamless_epoch 验证上一段遗留的调速更新不会重定向无缝衔接后的下一段。
16 short_profile_boundary_matrix 覆盖直线、平滑、正弦三曲线与 1、2、10、99、100、101 脉冲,检查频率范围、升降趋势、对称性、计数和理论时长。
17 short_final_no_poll 验证三种曲线的 10 脉冲最终短段在脉冲间无 1 ms Poll 时仍逐脉冲减速并准确完成。
18 zero_to_maximum_ramp_duration 验证三种曲线从 0 加速到 100 kHz、1000 脉冲、20 ms 配置的单调性、峰值和总时长。
19 maximum_pulse_ramp_duration 验证三种曲线在 65,535 脉冲和 1311 ms 加速条件下采用可达峰值并准确计数。
20 maximum_single_ramp_no_poll 验证三种曲线的 65,535 脉冲单段在无 Poll 时持续逐脉冲更新并准确完成。
21 short_timer_failure 注入短段频率更新失败,验证立即关闭输出并进入 ERROR/TIMER,位置保留为 1。
22 stop_after_subsequent_handoff 验证无缝切入第二段后立即 STOP 能从新段频率正常减速并停止。
23 short_zero_speed_edges 验证起始/停止速度均为 0 时,1 脉冲和 2 脉冲短段仍以有效非零硬件频率准确执行。
24 short_dynamic_retarget 验证 50 脉冲短段中把目标频率由 1000 改为 2000 Hz 后安全上升,随后 STOP 正常停止。
25 short_ext_cut 验证短段执行 3 脉冲后触发 EXT,在下一脉冲边界切断,最终位置 4。
26 current_frequency_dynamic 验证当前段动态频率按安全脉冲边界生效,状态反映实际输出,运行中改脉冲数不改变启动快照。
27 poll_mailbox_failure 注入动态调频失败,验证 Poll 仅提交更新,失败在脉冲边界转为 ERROR/TIMER
28 future_frequency_on_arrival 普通逐段模式中修改未来第二段频率,当前段不受影响,到达第二段时采用新值。
29 subsequent_future_frequency_handoff 无缝模式中修改未来段频率,验证预装衔接重建并以新频率无缝进入第二段。
30 future_frequency_last_pulse_race 验证未来段调频与当前段最后脉冲竞态时,第二段仍以新频率启动并准确完成。
31 latched_update_before_future_frequency_commit 验证屏蔽中断期间锁存的物理脉冲先消费旧衔接,再提交新的未来频率预装。
32 subsequent_no_poll_gap 验证两段只靠 ISR 无缝衔接,中间不依赖 Poll,输出不停止,最终位置 7。
33 three_single_pulse_no_poll 验证三个各 1 脉冲、1000/2000/3000 Hz 的段在无 Poll 时连续衔接。
34 handoff_queue_failures 两种时序下注入下一段频率排队失败,均关闭输出并转为 ERROR/TIMER
35 command_state_restrictions 验证 IDLE/RUNNING 状态下 START、STOP、CLEAR、静态/动态配置写入及非法组合的限制。
36 command_mailbox_start_snapshot 验证 START 延迟执行与配置快照,后续写入和重复 START 不覆盖首个快照。
37 command_mailbox_stop_clear_deferred 验证重复 STOP/CLEAR 可幂等入队,状态变化延迟到 Poll,冲突命令返回 BUSY。
38 command_mailbox_validation 验证 START 入队前检查起始段和绝对位置有效性,非法配置不启动。
39 command_mailbox_start_failure 注入底层启动失败,验证 Poll 后进入 ERROR/INVALID_RESOURCE,CLEAR 可恢复。
40 wait_signal_positive 验证段后进入 WAITING,选定输入有效后由下一次 Poll 结束等待。
41 persistence_reinit 在 Host 存储模拟中验证输出、方向、2345 Hz 配置和位置 4 跨 PlsrInit() 恢复,CLEAR 后位置保持 0。
42 position_flash_save 验证位置稳定约 1000 ms 后仅保存一次,CLEAR 后延时产生第二次保存。
43 busy_reset_absolute_gate 模拟运动中复位,保留位置但取消绝对位置可信标志;CLEAR 后恢复绝对运动。
44 position_overflow 验证 INT32_MAX 正向溢出时立即停脉冲并进入 ERROR/COUNT

说明:Host 测试直接调用寄存器 API 和平台替身,不能代替真实 RTU 串口板测;真实 RTU 结果见第 7 节。

4.2 Python 产品测试脚本离线自检

执行命令:

py -B HostComputer\plsr_modbus_product_test.py --self-test

结果:

Self-test passed; no serial port was opened

覆盖:

  • Modbus CRC16 参考向量及线上低字节在前的字节序。
  • 6 组有符号 32 位数的双 WORD 拆分与合并。
  • 1200 Hz 请求的 1 Hz 容差边界。
  • ST-LINK GPIO 位读回文本解析。

4.3 Python 控制面板离线自检

执行命令:

py -B HostComputer\plsr_control_panel.py --self-test

结果:

PLSR control panel self-test passed; no GUI or serial port was opened

覆盖 9600 波特率、X4/X5 选项、10 段地址步进、整数解析和越界拒绝、公共区 20 WORD 编码、段区 8 WORD 编码、负脉冲补码及跳转段范围校验。

5. IAR 构建

执行命令:

& 'F:\IAR Systems\Embedded Workbench 8.3\common\bin\IarBuild.exe' `
  'EWARM\Modbus.ewp' -build Modbus -log warnings

最终结果:

Total number of errors: 0
Total number of warnings: 0

EWARM/Modbus/List/Modbus.map 同时报告 Errors: noneWarnings: none,内存数据见第 3 节。

6. 烧录与固件产物校验

6.1 烧录

最终烧录使用 EWARM/Modbus/Exe/Modbus.hex,只擦除并写入应用占用的 Sector 0~3。ST-LINK 最终输出:

Verification...OK

开发过程中还用 STM32CubeProgrammer 执行过两次下载校验,用于确认当时固件可以下载和校验。它们属于中间版本的烧录链路记录,不是功能测试,也不作为最终交付固件的产物证据;最终结论以上述 ST-LINK 烧录、最终 SHA256 和后续完整板测为准。

6.2 持久化区保护

烧录前后均读取并检查 Sector 10/11。应用 HEX 地址上限为 0x0800C550,不覆盖持久化区;烧录流程也没有擦除 Sector 10/11。该检查用于确认后续持久化板测不是由重新烧录清空后伪造出的初始状态。

6.3 产物一致性

板测烧录件和当前分支重新构建产物的 SHA256 均为:

97956D9EF30A9B274140B9B82F412EDD77F9637F563FCC3F552BB4B140772343

7. 真实 Modbus RTU 和运动板测

执行入口:

py -B HostComputer\plsr_modbus_product_test.py `
  --port COM5 --run --phase all --allow-motion

最终 phase=all 的 9 组测试全部 PASS:

# 用例 实际验证内容 结果
1 fixed_map_and_exceptions 真实 FC03/06/10 访问固定配置、段、状态和控制区;检查保留字读零、控制字读零;验证不支持 FC01 返回 0x01,非法/跨区/只读地址返回 0x02,保留字非零、半个 DWORD 和组合控制命令返回 0x03。 PASS
2 positive_negative_absolute_zero 验证正向相对、负向相对、绝对定位及零位移,检查方向、终态和逻辑位置。 PASS
3 all_outputs_100khz 同一个 PLSR 依次选择 Y0、Y1、Y2、Y3,每路请求 100 kHz、执行 1000 个逻辑脉冲并检查完成位置。不是四轴并发。 PASS
4 short_final_profiles 对直线、平滑、正弦三种曲线执行最终 10 脉冲短段,检查终态和准确位置。 PASS
5 wait_time 执行 10 脉冲后进入 WAITING,配置等待 120 ms;检查不会异常提前完成,之后正常完成。 PASS
6 act_time 2000 脉冲目标配合 80 ms ACT,检查时间到后在 0~2000 之间切断并正常完成。 PASS
7 dynamic_frequency_repeated_stop 当前段从 500 Hz 动态改为 1200 Hz;真实状态读回 1199 Hz,在允许的 1 Hz 容差内;运行中静态输出选择写入返回 BUSY;重复 STOP 正常减速停止且未跑满 3000 脉冲。 PASS
8 future_segment_frequency_on_arrival 普通逐段模式运行第一段时修改未来第二段频率,确认当前段仍为 400 Hz,进入第二段后采用 900 Hz。 PASS
9 subsequent_future_frequency_handoff SUBSEQUENT 模式运行第一段时修改未来段频率,确认当前段不变,第二段以 900 Hz 衔接并最终累计 400 脉冲。 PASS

脚本在退出时停止仍在运行的任务,并恢复进入测试前保存的公共配置和前两段配置。

正式烧录后还在完整 phase=all 之前单独执行过一次 --phase smoke,固定映射和异常码检查 PASS。第 9 节恢复默认值并再次硬复位后又执行了一次 smoke,结果仍为 PASS。

8. X4/X5 实体回环板测

8.1 接线和方法

本轮保留的自动化回环接线:

Y4 -> X4
Y5 -> X5

脚本通过 ST-LINK 临时把 Y4/Y5 对应 GPIO 配置为输出,驱动 PLC 输入并直接读回 X4/X5 输入位;产品协议和正式固件没有为测试夹具新增私有寄存器。

开发期夹具最初尝试写 GPIO 的只写 BSRR 寄存器。旧版 ST-LINK_CLI 3.5.0 会在写后回读校验,因 BSRR 不可按普通寄存器回读而返回码 4。夹具随后改用 PI8/PE6 的 ODR 位带地址 0x424402A00x42420298 驱动输出。该失败是调试工具与只写寄存器的校验方式不兼容,不是接线、X4/X5 输入或 PLSR 功能故障。

执行入口:

py -B HostComputer\plsr_modbus_product_test.py `
  --port COM5 --run --phase x45 --allow-motion

8.2 九个用例

# 用例 实际验证内容 结果
1 x45_electrical_scan Y4/Y5 均关闭时 X4/X5 均为低;分别打开 Y4、Y5 时对应输入为高、另一路保持低;关闭后恢复低,验证双路电气扫描和隔离。 PASS
2 X4_wait_signal 选择 X4;50 脉冲后进入 WAITING,X4 低时保持,Y4 拉有效后完成,位置仍为 50。 PASS
3 X4_ext_signal 选择 X4;5000 脉冲运动中由 Y4 触发 EXT_SIGNAL,提前切段并正常完成。 PASS
4 X4_ext_or_complete_natural 选择 X4;不触发输入,50 脉冲自然完成。 PASS
5 X4_ext_or_complete_trigger 选择 X4;5000 脉冲运动中由 Y4 外部触发,提前完成。 PASS
6 X5_wait_signal 选择 X5;50 脉冲后进入 WAITING,X5 低时保持,Y5 拉有效后完成,位置仍为 50。 PASS
7 X5_ext_signal 选择 X5;5000 脉冲运动中由 Y5 触发 EXT_SIGNAL,提前切段并正常完成。 PASS
8 X5_ext_or_complete_natural 选择 X5;不触发输入,50 脉冲自然完成。 PASS
9 X5_ext_or_complete_trigger 选择 X5;5000 脉冲运动中由 Y5 外部触发,提前完成。 PASS

ODR 位带夹具修正后先完成独立电气扫描,再执行完整九项用例。异常清理顺序修正后又执行了第二次完整九项回归,结果仍全部 PASS。

8.3 最终夹具清理状态

测试结束或异常退出均按以下顺序清理:先关闭 Y4/Y5,再停止仍在运行的 PLSR,恢复测试前配置,最后把 PI8/PE6 恢复为输入高阻并清除上下拉。最终复核结果:

  • Y4/Y5 均关闭。
  • PI8/PE6 均为输入高阻、无内部上下拉。
  • X4/X5 读回均为低。

9. 持久化与硬复位板测

持久化测试使用真实目标板和 100 ms 硬复位,不以 Host 内存模拟代替。

9.1 保存准备

执行 persistence-prepare

  • 清零逻辑位置。
  • 写入 500 Hz、7 脉冲的特征配置。
  • 执行运动并确认 COMPLETED、位置为 7。
  • 等待后台保存完成。

9.2 第一次硬复位和恢复检查

执行 100 ms 硬复位后运行 persistence-verify --cleanup,结果:

  • 上电状态为 IDLE,没有自动续跑复位前任务。
  • 逻辑位置恢复为 7。
  • 第一段频率恢复为 500 Hz。
  • 第一段脉冲数恢复为 7。

随后执行 CLEAR,把位置恢复为 0;写回默认配置并等待保存。

9.3 第二次硬复位和默认状态检查

再次执行 100 ms 硬复位后运行 defaults-verify,结果:

  • 状态为 IDLE,逻辑位置为 0。
  • 默认方向建立延时为 10 ms。
  • 默认速度为 1000 Hz,起始速度和停止速度均为 100 Hz。
  • 第 1 段为 1000 Hz、1000 脉冲。
  • 第 2~10 段频率均为 1000 Hz、脉冲数均为 0。

最后又执行一次固定映射 smoke,确认默认配置恢复后 RTU 访问和异常码仍通过。

10. 测试过程中出现的问题和修复回归

本节记录中间失败;这些结果不是最终失败,而是用于说明本轮调试实际发现并关闭了哪些问题。

阶段 中间现象 原因与处理 修复后结果
旧架构 PDU 试验 length == 8UTestStatusAndControl() == 0 失败 试验基于待废弃的旧 PDU 架构。需求复核后没有继续补旧架构,而是按 2026 固定产品接口重写;该试验路线整体废弃。 新固定接口由 Host protocol_boundaries 和真实 fixed_map_and_exceptions 覆盖并通过。
初期 Host 12 tests / 262 assertions / 2 failures 失败项是 wait_zero_rejectedact_zero_rejected。复核明确需求后确认正确语义为 WAIT=0 按 1 ms,ACT=0 零脉冲跳段,代码和测试按正确语义修正。 wait_zero_one_msact_zero_no_pulse 通过;最终 44/1,694,007/0。
扩充 EXT 测试 Host 编译失败,PLSR_EXT_SIGNAL 未声明 测试扩充时枚举和测试引用未同步,补齐枚举/接口后重跑。 Host 编译和完整回归通过。
Modbus 裁剪中间态 IAR 10 errors / 2 warnings 头文件先精简,旧源文件与 main.c 尚未同步清理;不是运动算法失败。随后完成最小 RTU 源文件和入口同步。 IAR 全量构建 0 errors / 0 warnings
Host 脚本启动 Windows 默认策略阻止直接运行 .ps1 改用 powershell.exe -NoProfile -ExecutionPolicy Bypass -File ... Host 脚本正常执行并通过。
X4/X5 夹具初版 ST-LINK_CLI 3.5.0 写 BSRR 返回码 4 BSRR 是只写寄存器,旧 CLI 的写后回读校验不适用。改用 PI8/PE6 的 ODR 位带地址驱动 Y4/Y5。 独立电气扫描和完整 X4/X5 九项通过;判定为夹具工具限制,不计为产品失败。
X4/X5 夹具审查 异常退出清理顺序不够安全 调整为先关闭 Y4/Y5,再停止运动、恢复配置,最后释放 GPIO;保证清理期间不会继续保持输入触发。 完整 X4/X5 九项重新执行并通过,最终 GPIO/输入状态复核通过。

中间失败均保留在本报告中,但最终交付结论以当前基线重新执行的结果为准。

11. 明确未执行和结论边界

以下项目本轮未执行,不得从本报告的 PASS 推导为已验证:

  • 未使用逻辑分析仪,因此没有验证端子真实占空比、每路真实边沿数、毛刺、窄脉冲、方向建立时间或段间物理波形连续性。
  • 未对 MCU 中断最坏响应时间和 100 kHz 下的 ISR 最坏时延做仪器测量。
  • 未做四轴同时运动或四轴联动;本实现只有一个逻辑 PLSR,Y0~Y3 是逐路选择。
  • 未做 USB CDC 与 Modbus/运动并发长稳。
  • 未做本次最小重写的长时间压力、断线重连或坏 CRC 长稳矩阵。
  • 未做真实 VBAT 断主电源测试。本轮实际执行的是调试器控制的 100 ms 硬复位;它能证明复位恢复路径,不能等价证明 VBAT/完全掉电保持。
  • Host 的持久化用例使用内存模拟;真实 Flash/复位结论仅来自第 9 节板测。
  • Host 直接调用寄存器 API,不证明 RTU 物理链路;真实 RTU 覆盖仅限第 7~9 节列出的板测。
  • 未用 IAR 8.40 构建;本轮实际验证版本为 IAR EWARM 8.3.4。

12. 最终状态

测试结束后目标板处于以下状态:

  • 固件为 SHA256 97956D9EF30A9B274140B9B82F412EDD77F9637F563FCC3F552BB4B140772343 对应版本。
  • PLSR 状态为 IDLE,逻辑位置为 0。
  • 固定产品寄存器配置已恢复默认值。
  • Y4/Y5 夹具输出已关闭,PI8/PE6 已释放为输入高阻。
  • X4/X5 均读回低。
  • 最终 defaults-verify 和固定映射 smoke 均 PASS。

本报告没有引用旧实现的四轴、双 AB、长稳或逻辑分析仪结果作为本次重写证据。

13. 2026-08-13 第二批:单段硬件计数加减速

13.1 实现范围

  • PULSE/DIR、单段、完成模式、相对位置。
  • 直线、S 曲线、正弦曲线加减速。
  • PWM 由输出定时器持续产生,TIM9/TIM12 通过内部触发硬件计数。
  • 曲线频率按 1 ms 节拍计算;新 PSC/ARR/CCR 在下一个 PWM 更新边界整体生效。
  • 每次曲线更新最多产生一次边界提交中断,不按每个输出脉冲进入业务中断。
  • 仅当段长可容纳完整加减速预算时进入本批硬件曲线快路径;短曲线留待后续批次。

13.2 自动化验证

项目 结果 关键结果
C Host 完整回归 PASS 86 tests / 514,079 assertions / 0 failures
第二批专属 Host 矩阵 PASS 三种曲线均走有限硬件计数路径,运行中位置递增,先加速后减速,最终 20,000 脉冲
Python 产品测试离线自测 PASS 未打开串口
Python 控制面板离线自测 PASS 未打开 GUI 或串口
IAR clean build PASS 0 errors / 0 warnings
固件烧录与校验 PASS Download verified successfully

板测固件:

HEX: EWARM/Modbus/Exe/Modbus.hex
SHA256: C2686C1E432E2F55B0695ECF21A82E4E61373CB952CB065EBB256523D2689D35

13.3 实板波形与诊断

测试参数:Y0/Y12、10 kHz 起始、50 kHz 目标、10 kHz 停止、加减速各 100 ms、20,000 脉冲。

逻辑分析仪结果由操作者反馈:波形分析全部通过

板内最终状态:

项目 实测值 结果
累计位置 20,000 PASS
运行状态 7(COMPLETED) PASS
诊断标志 0x007E 计数、频率、曲线均已检查且 PASS
期望脉冲数 20,000 PASS
实测脉冲数 20,000 PASS
计数误差 0 PASS

13.4 性能门限

CPU 时钟 168 MHz,使用 Cortex-M4 DWT CYCCNT 实测。

路径 次数 最坏周期 最坏时间 结论
1 ms 曲线计算及硬件参数排队 160 1,302 cycles 7.75 us PASS;按 1 kHz 最坏调度约占 0.78% CPU
PWM 边界参数提交中断 159 151 cycles 0.90 us PASS;每次曲线更新一次,不按输出脉冲触发
65536 脉冲分块中断 0 0 0 符合预期,本用例仅 20,000 脉冲
最终停止中断 1 276 cycles 1.64 us PASS;低于 500 cycles 门限

第二批结论:单段长曲线的硬件计数、三种加减速曲线、精确停止、板内诊断和性能门限通过。

14. 2026-08-13 零加减速时间语义与 TC-PD-008 共性问题修复

14.1 修复语义

  • 加速时间为 0 ms 时,起始速度参数无效,当前段从该段设定频率直接启动。
  • 减速时间为 0 ms 时,停止速度参数无效,当前段保持该段设定频率直至完成。
  • 有加速或减速时间时,原有起始速度、停止速度和三种曲线规划保持不变。
  • 后续模式同方向连续段仍允许按下一段频率在合法边界衔接。

修复覆盖普通启动、方向建立延时后的启动、短段预计算、有限脉冲硬件计数快路径、自然段尾和 STOP 路径,避免只有部分路径遵守零时间语义。

14.2 Host 脉冲级回归

新增 zero_ramp_times_ignore_edge_speeds,覆盖直线、S 曲线、正弦曲线和 1、2、10 脉冲:

  • 加减速均为 0 ms,起始/停止速度均故意设为 100 Hz:每个实际周期均为 100,000 Hz。
  • 仅加速为 0 ms:起始速度分别设为 100 Hz 和 50,000 Hz,两次实际逐脉冲频率序列完全一致。
  • 仅减速为 0 ms:停止速度分别设为 100 Hz 和 50,000 Hz,两次实际逐脉冲频率序列完全一致。

完整 Host 回归结果:

94 tests / 515,670 assertions / 0 failures

14.3 IAR、烧录和持久化区保护

项目 结果
IAR EWARM 8.3.4 全量构建 0 errors / 1 warning;map 正文 Errors: noneWarnings: none
只读代码 67,586 bytes
只读数据 1,517 bytes
读写数据 27,335 bytes
HEX SHA256 F0B4EC12C71471B4C377E440C5442A006DA67E1095B0696BB16E20586E1B03F7
ST-LINK 烧录 Verification...OK,MCU 复位并运行
持久化区保护 0x080C00000x080FFFFF 分为四个 64 KiB 块,烧录前后 SHA256 逐块一致

旧版 ST-LINK_CLI 3.5.0 对单次 256 KiB Dump 卡住,因此保护校验改为四次 64 KiB 分块回读;连接探测、程序烧录和四块回读均正常。

14.4 COM5 实板内部验证

执行 28 个用例:

  • 加减速均为 0 ms,起始/停止速度均为 100 Hz:三种曲线 x 1/2/10 脉冲。
  • 仅加速为 0 ms,起始速度为 50,000 Hz:三种曲线 x 1/2/10 脉冲。
  • 仅减速为 0 ms,停止速度为 50,000 Hz:三种曲线 x 1/2/10 脉冲。
  • 加减速均为 0 ms、100,000 Hz、100,000 脉冲的有限硬件计数长段。

全部 28 项满足:状态 7、错误 0、位置等于设定、诊断期望计数等于实际计数、计数误差 0、诊断原因 0、曲线失配数 0、最大频率误差 0。

额外读取三种曲线的零加减速 10 脉冲诊断字段,均为:请求频率 100,000 Hz、定时器期望频率 100,000 Hz、定时器实际频率 100,000 Hz、请求误差 0、样本数大于 0、失配数 0。

14.5 TC-PD-008 结论边界

验收表中 TC-PD-008 已填写的“多 1 个脉冲、首脉冲偏长、尾部窄脉冲”是修复前固件数据。本批固件已包含 PULSE/DIR 启动相位和最终边界终止修复,Host、板内计数及诊断均通过,但仍需用逻辑分析仪对当前 SHA256 固件复测,才能关闭端子外部 N+1、首周期和尾窄脉冲问题。原验收数据保留,不以板内结果覆盖。

15. 2026-08-14 默认频率、10 段交接与段尾慢脉冲修复

15.1 功能修复

  • 段频率为 0 时运行使用默认频率,Modbus 寄存器仍读回原始值 0;启动前和运行中写 0 均覆盖。
  • 修复有限脉冲动态 ramp 的 queued→active 提交卡住后,段 2~8 长时间停留在约 1.05 kHz 的问题。
  • ramp 提交返回 STALE 时保持 ramp 活跃,终点频率必须成功提交后才结束。
  • 边界条件命中后立即提交首个减速频点,消除额外 1 ms 轮询延迟。
  • 删除重复的频差余量;仅当一个轮询周期的脉冲数不超过斜坡面积 5% 时保留轮询余量,避免短斜坡提前到达停止速度并发送慢尾脉冲。
  • timing 上位机在旧逐脉冲 IRQ 统计为空时读取有限硬件计数 block/final IRQ 统计,适配当前硬件计数架构。

15.2 Host 全量回归

新增和强化用例:

  • finite_ramp_retries_terminal_frequency_after_stale
  • complete_ten_segment_frequency_staircase
  • ten_ms_boundary_ramp_no_slow_tail
  • zero_segment_frequency_uses_default_speed
  • dynamic_zero_frequency_uses_default_speed

10 段用例逐脉冲检查 1~10 kHz 峰值,并要求段 1~9 最后连续 <=200 Hz 的脉冲不超过 2 个;10 ms 边界专项同时要求峰值达到 99% 且无慢尾。

100 tests / 525,879 assertions / 0 failures

15.3 IAR、固件与持久化区

项目 结果
IAR EWARM 8.3.4 0 errors / 1 warning
唯一警告 PlsrCounterTriggerSourceAxis set but never used
只读代码 67,770 bytes
只读数据 1,517 bytes
读写数据 39,623 bytes
HEX 大小 194,945 bytes
HEX SHA256 4E4ED664CE05F364B7443711DC85E719960B52BCBCD5FFC347D76F0CCFE5D863
ST-LINK 扇区 0~3 擦写,Verification...OK,复位运行
持久化区 最新烧录前后 SHA256 均为 44094568B88CC30AFB82D70D343AC7E67DC374A568854E6426EE21D431349783

15.4 COM5 Pulse/Direction 板测

产品矩阵 12 项全部通过:固定寄存器与异常码、正负/绝对/零位移、10 段顺序、从第 10 段启动、方向与极性矩阵、四路 100 kHz、短最终轮廓、WAIT、ACT、动态频率与重复 STOP、未来段改频、后续模式交接。

延长 10 段测试将每段脉冲数改为 1000,逐段捕获:

1000, 2000, 3000, 4000, 5000,
6000, 7000, 8000, 9000, 10000 Hz

最终位置 10,000、错误 0;末段诊断 expected 1000、actual 1000、count error 0、mismatch 0。测试后已恢复 10 段 x 100 脉冲、位置 0、IDLE。

15.5 DWT 性能

门限为 <1680 cycles(100 kHz 周期)。

路径 实测最大值 结果
四路有限计数最终 IRQ(Y0~Y3) 344 / 400 / 340 / 404 cycles PASS
10 脉冲短轮廓 IRQ 1657 cycles PASS
10 脉冲短轮廓生产者 1380 cycles PASS
65,535 脉冲长 ramp IRQ 159 cycles PASS
65,535 脉冲 ramp 更新 1320 cycles(197 次) PASS

完整 timing 阶段的 Pulse/Direction 部分通过;最后进入 AB Y2/Y3 负向用例时,诊断标志为 0x00FA,该 AB 路径按当前调试范围暂缓,不计入本批 Pulse/Direction 结论。

15.6 逻辑分析仪状态

14:34 的第二次 10段.bin 已证明段 1~10 分别达到目标频率,但段 3、7、8、9 仍有 3~4 个连续低速尾脉冲。根据实测又移除了固定 2 脉冲预装余量并重新烧录;最终还需覆盖采集一次同配置波形,确认段尾连续低速脉冲不超过 2 个。段间约 5 ms 还包含下一段 100 Hz 启动的低半周期,需与慢尾分开判断。详细数据见 PLSR波形验收报告_2026-08-14_完成模式10段阶梯频率.md

16. 2026-08-14 完成模式多段启动/停止速度语义修复

16.1 修复语义

当各段等待条件均为“外部或脉冲发送完成”,且由脉冲发送完成自然进入下一段时,多段按一条连续轨迹处理:

  • 启动速度只用于第一执行段;
  • 同方向中间段在前一段内向下一段频率过渡,完成时把当前速度带入下一段;
  • 停止速度只作为最后执行段的段尾目标;
  • 跳转段使用实际跳转目标段频率,不误用顺序下一段;
  • 外部截断、WAIT/ACT 结束、STOP 和方向反转不带速穿越,仍执行安全停机/换向流程;
  • 硬件多段常频序列只在加速和减速时间都为 0 ms 时启用,避免优化路径跳过首段加速或末段减速。

短段脉冲预算不足时,最后一段可能在到达停止速度前耗尽设定脉冲;此时要求按减速斜率平滑收尾,不额外补发脉冲以强行达到停止速度。

16.2 Host 全量回归

新增 complete_natural_boundaries_carry_speedcomplete_jump_carries_speed,并更新零时间有限序列、同向/反向方向写入的旧语义断言。覆盖三段同向顺序、跳转段、第一段启动速度、中间段速度携带、最后一段停止减速及反向安全路径。

102 tests / 526,542 assertions / 0 failures

16.3 IAR、固件与烧录

项目 结果
IAR EWARM 8.3.4 全量构建 0 errors / 1 warning
唯一警告 PlsrCounterTriggerSourceAxis set but never used
只读代码 67,806 bytes
只读数据 1,517 bytes
读写数据 39,623 bytes
HEX 大小 195,043 bytes
HEX SHA256 7C6534FA05FB61BBA8CAF7838F36BAF908612CBDE525A17F23354E8C702FB5A2
ST-LINK Sector 0~3 擦写,Verification...OK,复位运行
持久化区 Sector 10~13 分块读取,四块烧录前后 SHA256 分别一致

16.4 COM5 实板内部验证

三段配置为 1000/2000/3000 Hz、每段 1000 脉冲,启动 100 Hz、停止 200 Hz、加减速 10 ms。结果:

  • 终态 COMPLETED,错误 0,位置 3000;
  • 三段首次可读运行频率为 1000/2000/3000 Hz,中间段未回到 100 Hz;
  • 末段诊断 expected 1000、actual 1000、count error 0、mismatch 0;
  • 末段最后诊断请求频率为 1041 Hz,证明停止减速只发生在最后一段,且短段在达到 200 Hz 前按设定脉冲数正常结束;
  • 固定映射与异常码 smoke 复测通过。

测试后恢复 10 段、每段 100 脉冲、1~10 kHz、默认 10 kHz、启动/停止 100 Hz、加减速 10 ms、位置 0、IDLE。

16.5 待逻辑分析仪确认

当前代码、Host、构建、烧录和板内计数均通过。新语义固件仍需覆盖采集 10段.bin,确认启动速度只出现在第一段、停止减速只出现在第 10 段,并重新测量段间低电平;旧波形不作为本固件的物理波形结论。

17. 2026-08-14 15:24 连续轨迹波形与末段慢尾修复

17.1 15:24 波形结果

波形 SHA256:49BB40FE59A70DF41A82122AC6EAE253C48661F64E2B74C27F3EE01B3E03860B,共 10,011,664 点,6.25 MS/s,1000 个上升沿和 1000 个下降沿。

  • 第 2~10 段起始运行频率分别为 2000、3000、4000、5000、约 6000、7000、8000、9000、10000 Hz;中间段不再回到 100 Hz,连续轨迹语义通过。
  • 段 1~9恒速频率和向下一段的段尾过渡正确。
  • 9 个段间低电平为 0.250080~0.949760 ms,均小于 1 ms;旧固件约 5~6 ms 的低电平消失。
  • 第 10 段按 10000→100 Hz 减速,但脉冲 96~100 出现 183/100/100/100 Hz 周期和最终 5 ms 高电平;连续 <=200 Hz 周期为 4 个,超过最多 2 个的门限。

因此 15:24 波形证明多段启动/停止速度作用范围修复成功,但末段慢尾仍不通过。

17.2 末段慢尾根因与修复

边界估算原来使用连续梯形面积;实际 PlsrRampAdvance 每 1 ms 使用 1/durationduration/duration 的右端点频率。10 kHz→100 Hz、10 ms 的连续面积约为 51 脉冲,右端点离散面积约为 46 脉冲,导致减速提前约 5 脉冲到达停止速度。

修复后:

  • 短斜坡按实际右端点离散面积估算,避免提前进入停止速度慢尾;
  • 允许完整轮询余量的长斜坡补偿半个端点差,保持 65,535 脉冲长轮廓能够到达停止速度;
  • 10 段 Host 用例现在也检查第 10 段连续 <=200 Hz 尾脉冲不超过 2 个。

17.3 修复后验证

项目 结果
Host 全量 102 tests / 526,543 assertions / 0 failures
65,535 脉冲三曲线长轮廓 末频回归通过
IAR EWARM 8.3.4 0 errors / 1 warning
只读代码/数据、读写数据 67,886 / 1,517 / 39,623 bytes
HEX 大小 195,268 bytes
HEX SHA256 5851B7714454770DD8EF8A0ED8B01379791F4EF71BDF1B795B36639B18F258AB
ST-LINK Verification...OK;Sector 10~13 烧录前后分块哈希一致
COM5 10×100 位置 1000、错误 0、末段 expected/actual 100/100、count error 0、mismatch 0
末段最终板内诊断频率 3071 Hz,未提前进入 100 Hz 慢尾

板上已恢复 10 段 x 100 脉冲、位置 0、IDLE。需再覆盖采集一次 10段.bin,确认物理端子的末段连续低速尾脉冲不超过 2 个。

18. 2026-08-14 非零加减速段间连续输出修复

18.1 根因

实测发现加减速时间为 0 ms 时段间没有间隔,而加减速时间非 0 ms 时仍有约 250~900 us 低电平。根因是两种配置走了不同硬件路径:

  • 0 ms:整条同向轨迹使用硬件多段有限序列,计数器在段边界直接装载下一段,定时器不停机;
  • 非 0 ms:此前限制了硬件多段序列,每段分别启动有限计数,段完成后等待主循环处理边界再启动下一段,产生一个主循环周期以内的停波。

该间隔不是启动/停止速度数值本身造成,而是非零斜坡配置触发了逐段 stop/start 路径。

18.2 修复

  • 非零加减速也使用同一条硬件多段有限序列;
  • 序列第一步从启动速度开始,并在硬件序列持续运行期间执行 1 ms 斜坡更新;
  • 中间硬件边界只切换软件段状态和诊断,不停止脉冲定时器;
  • 最后一个段仍在同一序列内执行停止减速并由硬件总计数终止;
  • 同向可连续段以外的方向反转和不满足序列条件的路径仍保留安全停机。

18.3 验证

项目 结果
Host 全量 102 tests / 526,561 assertions / 0 failures
非末段边界 active 断言 9 个边界均保持有限序列和脉冲输出 active
IAR EWARM 8.3.4 0 errors / 1 warning
只读代码/数据、读写数据 67,954 / 1,517 / 39,623 bytes
HEX 大小 195,456 bytes
HEX SHA256 8778C24D3FDA364DC4B1D6FAD92E69D9090C5B8EC57D1C65DFCAC89EA0B5AC45
ST-LINK Verification...OK;Sector 10~13 烧录前后分块哈希一致
COM5 10×100 位置 1000、错误 0、末段 expected/actual 100/100、count error 0、mismatch 0

板上已恢复 10 段 x 100 脉冲、位置 0、IDLE。尚需新逻辑分析仪波形确认 9 个物理段边界不再出现额外低电平;未覆盖的旧 10段.bin 不重复分析。

19. 2026-08-14 单段 1 kHz 短斜坡与波形解析修复

19.1 bbb.bin 原始边沿复核

配置为 1 段、默认速度 10000 Hz、启动/停止速度 100 Hz、加减速时间 10 ms、段频率 1000 Hz、脉冲数 100。原始文件 bbb.bin 为 9,708,896 点、6.25 MS/s,共检测到 100 个上升沿和 100 个下降沿。

项目 原固件实测
首个上升沿至最后一个下降沿 104.001120 ms
首脉冲高/低电平 5.000160 / 0.500000 ms
首个上升沿周期 5.500160 ms,即 181.8129 Hz
中间可测周期 基本为 1.000000 ms,即 1000 Hz
末脉冲高电平 0.500000 ms

原理论/实测图片中的约 526 ms 红色减速尾线不是硬件输出。旧查看器把第 100 个脉冲后的采集空闲低电平当成最后一个周期,从而生成一个接近 0 Hz 的伪频率点并与前一点连线。查看器已改为只使用相邻两个上升沿计算周期;同一文件现在报告 100 个脉冲、99 个可测完整周期,不再绘制伪尾线。

19.2 固件问题与修复

原固件仍有真实的首末脉冲轮廓问题。100→1000 Hz 和 1000→100 Hz 按默认速度 10000 Hz、加减速 10 ms 计算,斜坡持续时间均约 0.9 ms,离散为 1 ms。有限计数路径依赖 1 ms 主循环提交频率,无法在已经开始的 100 Hz 首个高半周期内及时改频,也无法保证末脉冲前提交停止斜坡。

修复后,单段脉冲数不超过 1000 且存在 1 ms 短斜坡时,优先使用整段逐脉冲预计算队列;正常的较长有限斜坡、多段连续硬件序列和零斜坡恒速路径保持不变。该配置的预计算结果为:首脉冲约 550 Hz、中间 98 个脉冲为 1000 Hz、末脉冲约 550 Hz,完整周期累计约 101.64 ms。

19.3 自动验证与烧录

项目 结果
新增精确回归 首/末 549~551 Hz;中间 98 个 1000 Hz;总周期 101.6~101.7 ms
Host 全量 103 tests / 526,778 assertions / 0 failures
IAR EWARM 8.3.4 0 errors / 1 warning
只读代码/数据、读写数据 68,006 / 1,517 / 39,623 bytes
HEX 大小 195,612 bytes
HEX SHA256 068BDC9D417E3C1DEE377BA3053CBB850B32ED3B7EBBB1E9F7653623F29F713A
烧录 STM32CubeProgrammer 下载、校验、复位成功
持久化区 0x080C0000~0x080FFFFF 烧录前后 SHA256 均为 FC494806B0465476E51678F961A3EC63873C32915A214B31DFB4307048D3949A

COM5 板测已通过:位置 100、状态 COMPLETED、错误 0;诊断 expected/actual 为 100/100、count error 0、curve mismatch 0,末个诊断请求/定时器频率均为 550 Hz。测试后已清位置并恢复为 IDLE,保留同一单段配置。新逻辑分析仪波形仍待覆盖采集。

20. 2026-08-14 短斜坡单段/多段通用根治

20.1 架构修复

第 19 节的单段短轮廓分流仅能覆盖单段样本,不作为最终修复。根因是有限序列曾把一个逻辑段直接等同于一个硬件 step,首段加速和末段减速只能依赖 1 ms 主循环更新;只要斜坡在一个或少数脉冲内完成,单段和多段都会遇到同一问题。

最终实现将“硬件频率 step”和“逻辑段完成边界”拆开:

  • 首段入口短斜坡和最终段出口短斜坡在启动前按脉冲域生成硬件 step;
  • 计数器 IRQ 只在脉冲边界预装下一组定时器参数,不在 IRQ 内计算曲线;
  • 每个硬件 step 保存逻辑段内脉冲偏移,只有逻辑段最后一个 step 发布段完成事件;
  • 段内位置、剩余脉冲、诊断计数仍按逻辑段累计,不把斜坡子 step 当成新段;
  • step 索引扩展为 16 bit,统一上限为 2010;step 缓冲由 Core 静态持有,平台只保存运行期指针,避免四路重复占用 RAM;
  • 已删除“单段、脉冲数不超过 1000、斜坡不超过 1 ms”的临时特判。

20.2 Host 回归

用例 覆盖内容 结果
单段 100 脉冲 100→1000→100 Hz,首末约 550 Hz,中间 98 个 1000 Hz PASS
3 段无 Poll 入口斜坡、1000→2000→3000 Hz 硬件边界、最终出口斜坡;300 个脉冲期间不调用 PlsrPoll1ms() PASS
10 段无 Poll 启停 100 Hz、段频率 1000 Hz、默认速度 10000 Hz、加减速 10 ms;9 个边界持续输出 PASS
既有完整回归 有限计数、动态频率、方向反转、短轮廓、AB 相、诊断、持久化和异常路径 PASS

最终结果:

104 tests / 527,097 assertions / 0 failures

20.3 IAR、资源与固件

项目 结果
IAR EWARM 8.3.4 0 errors / 1 个既有未使用变量 warning
只读代码 / 只读数据 / 读写数据 69,258 / 1,517 / 87,096 bytes
通用有限 step 缓冲 48,240 bytes
HEX 大小 199,130 bytes
HEX SHA256 9B296CF02101F78A70F4CCF2BB89DC75AA27E8261F8AED451764854EE2106C4C
ST-LINK 下载、校验、复位和运行成功

20.4 最坏速率门限

板上使用 90 kHz→100 kHz、默认速度 10 kHz、加速时间 10 ms、2000 脉冲测试。该轮廓在定时器量化合并后触发 188 次硬件 step IRQ:

指标 实测 100 kHz 门限
block IRQ 最大周期 396 cycles,约 2.36 us 1680 cycles,10 us
final IRQ 周期 410 cycles,约 2.44 us 1680 cycles,10 us
最小余量 约 7.56 us 必须大于 0

性能门限 PASS。IRQ 内无除法、开方或轮廓计算。

20.5 COM5 与持久化

同一最坏速率配置板测结果:状态 COMPLETED、位置 2000、错误 0、expected/actual 2000/2000、count error 0、curve mismatch 0、reason 0。

性能测试会按设计写入配置和位置。测试前已备份 0x080C0000~0x080FFFFF,测试后仅恢复 sector 10/11;恢复镜像 SHA256 与测试前均为 7BE5A392BCCB26A510516B80F44FE8FEA287CE58E653325AA7964DDAEC38E4F1。板上最终运行关闭 timing 的 release 固件。