怎么实测定出控制程序的最小稳定周期?

从 100 μs 逐档压低周期,每档记录 ISR 执行时间与 CPU 占用:43 条路由实测执行 4.86–4.99 μs,于是 5.00 μs 是临界、4.50 μs 已过载(110.8%)。判据只有一条:执行时间必须小于周期。

把周期从 100 μs 一档一档往下压,每档同时记录中断服务程序的执行时间。43 条路由的实测执行时间是 4.86–4.99 μs,所以 5.00 μs 时 CPU 占用 99.9%(临界),4.50 μs 时 110.8%(过载)。最小稳定周期不是试出来的经验值,它是执行时间上界加上几十纳秒的结果。

现象

「能跑起来、串口还在打印」并不等于没有超时。超载时的典型表现很隐蔽:

表现 容易被误认为
输出周期偶尔跳一拍 负载波动、传感器噪声
看门狗复位,间隔几十秒到几分钟 偶发干扰、电源不稳
监控计数增长速度比预期慢 通信丢包、上报抖动
长时间运行后复位,短时间测试正常 温度漂移、元件问题

四种表现都不指向「中断没跑完」,因为它们看起来像外部问题。但根因可能是同一个:中断执行时间已经超过周期,下一次中断已经挂起,而你测的那一档本来就是过载的。

原因

判据可以写成一个比值:

CPU 占用 = ISR 执行时间 ÷ 中断周期
  • 比值 > 100%:这一拍没算完,下一拍又来了,必然丢周期。表现是时间复杂度崩塌,而不是算术出错。
  • 比值 ≈ 100%:理论上刚好,但任何一个额外开销(一次总线竞争、一次分支预测失败)都会让它变成 >100%,所以这只是临界点,不是可用工作点。
  • 比值 < 100%:能跑,但余量必须覆盖最坏情况,不是平均值。

第二点最容易被忽略:执行时间的平均值很小,不代表每次都很小。同一段代码在不同输入下可能走到不同分支,在 Cortex-M7 上一次分支预测失败约 12 个周期惩罚,一次缓存缺失可能是几十上百个周期。用平均值定档,等于把最坏情况留给现场。

怎么做

四步,一套可复现的扫描流程。

第一步:固定被测程序。 同一个控制程序、同一份固件、同一块板,不要在中途改编译选项——-O0 与 -O2 之间可能是数倍差距,混在一起测没有意义。

第二步:从宽到窄扫。 定时器重装载值(ARR)按倍数递减,每档稳定运行一段固定时间:

100 μs(ARR 13600)→ 50 → 20 → 10 → 8 → 7 → 6 → 5.5 → 5.0 → 4.5 μs

第三步:每档采两个数。 中断入口记时间戳算周期,中断入口与出口各记一次算执行时间;两组都用 DWT 周期数,换算时除以当时主频。

/* 中断入口 */
uint32_t t_in = DWT_CYCCNT;
/* ... 中断体 ... */
uint32_t t_out = DWT_CYCCNT;

uint32_t exec_cycles = t_out - t_in;        /* 执行时间 */
/* 周期:与上一次入口时间戳相减 */
uint32_t period_cycles = t_in - last_in;
last_in = t_in;

第四步:算占用率并找拐点。 占用率突然贴近 100% 的那一档就是临界;越过它之后出现丢周期或复位,就是过载。

验证

43 条路由的实测结果(同一个程序,逐档压周期):

周期 ARR ISR 执行时间 CPU 占用 状态
100.0 μs 13600 5.0 μs 5.0% 正常
20.0 μs 2720 4.9 μs 24.7% 正常
10.0 μs 1359 4.87–4.95 μs 49.5% 正常
7.00 μs 951 4.87–4.94 μs 70.6% 正常
6.00 μs 815 4.86–4.96 μs 82.6% 需留意
5.00 μs 679 4.86–4.99 μs 99.9% 临界
4.50 μs 611 4.87–4.99 μs 110.8% 过载

注意第三列几乎不动:周期改了 20 倍,执行时间稳定在 4.86–4.99 μs(抖动 60 ns)。 这正是可以用「执行时间上界 ÷ 目标周期」反推周期的原因——执行时间不随周期变化。

折线图:43 路由逐档压周期的 CPU 占用实测

改前改后的对照:

决策方式 改前:凭「跑到 4 μs 还没崩」定档 改后:按执行时间上界定档
周期选择 4.5 μs(实测已过载 110.8%) 5.00 μs(99.9%,或留余量取 7 μs)
依据 短期观察没报错 执行时间上界 ÷ 目标占用率
风险 偶发丢拍、长时间跑必复位 可论证

旁证:换一个更吃 CPU 的配置,结论会同步变化。20 条路由在 -O0 编译下执行时间为 27.4 μs,100 μs 周期只占 27.4%——同一硬件、不同编译选项与原语数量,最小周期差了好几倍。所以「这个芯片能跑多快」这种说法没有意义,必须绑定程序与编译配置。

边界

  • 结论只在同一固件、同一块板、同一编译选项下成立;换 -O 级别、改 Flash 等待周期、调整中断优先级,数字都会变。
  • 用平均值算占用率会低估风险,定档应按「观测到的最大执行时间」而不是均值。
  • 示波器看输出周期跳拍比看 CPU 占用更直接;两者应交叉验证。
  • 若系统里有其他中断或 DMA 大量占用总线,ISR 的实际执行时间会被拉长,此时测得的占用率是乐观值。
  • 5.00 μs 这一档即使能跑也不建议作为工作点:99.9% 占用意味着没有任何余量吸收突发开销。

最后验证于 2026-10-29 · STM32H723ZG(RM0468)· 43 路由测试程序 · DWT 周期计数

怎么实测定出控制程序的最小稳定周期?

作者 JimmyZ,嵌入式 / 确定性控制方向。GitHub · 掘金