发送对象:Codex 开发
全部现象来自实板逻辑分析仪波形(6.25MS/s),运动计数均正确(1000/1000 脉冲),问题集中在短轮廓(脉冲数不足以完成完整加减速)路径和段间延迟。
配置:段数 1|基准 100000Hz|启动 100Hz|停止 100Hz|加速 100ms|减速 100ms|段频率 100000Hz|脉冲数 1000
现象:总时长 461ms(理论 ~64ms),尾部 ~38 个脉冲以 100Hz 输出(每个 10ms,共 400ms)。
波形结构:
100Hz →(450脉冲)→ 33kHz 峰值 →(485脉冲 减速到~8kHz)→ 跳变 100Hz×38个 → 停
实测 vs 理论:
| 项 | 理论 | 实测 |
|---|---|---|
| 峰值 | ~31,623Hz((f²−10⁴)/1e6=1000 → f=√1e9) | 33,069Hz(+4.5%) |
| 加速段 | ~500 脉冲 | ~450 脉冲 |
| 减速段 | 平滑减到 100Hz,正好用完 | 减到 ~8kHz 直接跳 100Hz |
| 总时长 | ~64ms | 461ms |
根因:剩余脉冲不足以完成完整减速 ramp 时,固件直接 ApplyFrequency(停止速度) 把剩余脉冲发完,而不是按剩余脉冲裁剪/重算减速斜坡(截断三角)。
修复方向:减速进入判定 剩余脉冲 ≤ 减速所需 时,按剩余脉冲重算减速斜率(保持三角形面积守恒),不要跳变到停止速度。
配置:段数 1|基准 100000Hz|启动 100Hz|停止 100Hz|加速 10ms|减速 10ms|段频率 100000Hz|脉冲数 1000
现象:总时长 524ms(理论 ~20ms)。加速段整个丢失(3 个脉冲就从 100Hz 冲到 100kHz),然后 100kHz 恒速 945 个,尾部 51 个 100Hz(510ms)。
波形结构:
100Hz →(1脉冲 10ms)→ 200Hz →(66kHz)→ 100kHz × 945个 → 100Hz × 51个 → 停
根因 A(加速消失)——时序错位:
启动速度 100Hz → 第 1 个脉冲要等 1/100Hz = 10ms 才发出
加速 ramp → (100000−100)×10ms/100000 = 9.99ms 就走完了
→ ramp 在第一个脉冲之前完成,加速段物理不可见
→ 首脉冲出来时频率已是 100kHz
根因 B(减速提前切换):同 Bug 1。
修复方向:ramp 计时起点改为第一个脉冲发出时刻(或段启动先应用启动速度、等首脉冲后再启动 ramp),而不是从段启动瞬间计时。
配置:段数 1|基准 100000Hz|启动 10Hz|停止 10Hz|加速 10ms|减速 100ms|段频率 100000Hz|脉冲数 1000
现象:输出 10Hz 脉冲 1000 个(约 100 秒)。
数学推演:
启动速度 10Hz → 第 1 个脉冲要等 1/10Hz = 100ms
完整梯形需要 → 加速500 + 减速5000 = 5500 脉冲(1000 不够 → 短轮廓)
短轮廓总时长 → 10Hz↗42,640Hz↘10Hz ≈ 47ms
47ms 曲线 < 100ms 首脉冲等待 → ramp 全程跑在第一个脉冲之前,消耗脉冲 = 0
固件曲线走完后的处理:频率回到停止速度 10Hz,剩余 1000 脉冲全部 10Hz 输出
根因:Bug 2 根因 A 的极端版(ramp 时长 < 首脉冲等待时间),叠加"曲线走完但 0 脉冲消耗"的判定缺陷。
修复方向:同 Bug 2 根因 A;并检查短轮廓"脉冲消耗=0"时的处理(应按首脉冲后的剩余脉冲重新规划)。
验证方法:把启动速度改成 1000Hz(首脉冲 1ms < ramp 47ms),同一配置应恢复短轮廓三角——可快速验证根因。
配置:段数 10|完成模式|相对位置|恒速 1000Hz(启动=停止=段频率)|段脉冲 100~109|跳转 0
现象:每个段之间固定 ~2.5ms 低电平(段 100ms 内占 2.5%)。
根因:恒速小段走有限脉冲路径,段完成与下一段启动被拆成两个主循环周期(每周期 ~1ms):
段 N 最后脉冲 → CC1 中断置 FiniteCompletionPending(IRQ 内,零延迟)
周期 N:PlsrPoll1ms → PlsrServiceFiniteCompletion() 消费完成事件
(诊断结算 + PlsrBoundaryPending=1)→ return ← plsr.c:4502 提前返回
周期 N+1:PlsrPoll1ms → PlsrHandleBoundary() → 启动段 N+1
延迟 = 段结束→周期N随机等待(0~1ms) + 2 周期 ≈ 2~3ms,平均 2.5ms
对比:非有限路径(有加减速)段完成在 IRQ 内直接置 PlsrBoundaryPending,段间仅 0~1ms——无此问题。
修复方向:PlsrServiceFiniteCompletion 消费完成后不 return,同周期继续处理 PlsrBoundaryPending(去掉 plsr.c:4502 的提前返回),段间延迟降到 ~1ms。
| # | 问题 | 严重度 | 涉及路径 | 实测文件 |
|---|---|---|---|---|
| 1 | 减速预算不足时跳停止速度发完剩余 | 高 | 短轮廓/减速切换(PlsrMaybePlanBoundaryRamp、短轮廓边界规划) |
bug1.bin、bug2.bin |
| 2 | ramp 计时从段启动起算,ramp 时长 < 首脉冲等待时加速丢失 | 高 | 段启动/ramp(PlsrBeginSegmentOutput→PlsrRampStart) |
bug2.bin、Bug 3 |
| 3 | 短轮廓"0 脉冲消耗"判定 + 峰值规划偏差(31623 vs 实测 33069,加速 500 vs 450) | 中 | 短轮廓峰值/预算计算(PlsrShortProfilePeak 等) |
bug1.bin |
| 4 | 有限路径段间 2 周期延迟(~2.5ms) | 低 | PlsrServiceFiniteCompletion → PlsrPoll1ms |
TC-PD-011 |
建议修复顺序:Bug 1/2 根因(同一短轮廓路径)→ Bug 3(同根因极端版,改完 1/2 后复测确认)→ Bug 4(一行 return 改动)→ 峰值规划偏差(精度优化)。
回归验证: