怎么实测定出控制程序的最小稳定周期?
从 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)。 这正是可以用「执行时间上界 ÷ 目标周期」反推周期的原因——执行时间不随周期变化。

改前改后的对照:
| 决策方式 | 改前:凭「跑到 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 周期计数