STM32H743能够承受多高的中断频率,取决于每次服务实际消耗多少时间,以及系统是否允许其他工作被推迟。CPU主频只能提供计算预算,不能单独给出“推荐中断频率”。判断是否可用,还要检查响应延迟、事件是否丢失和其他任务是否满足时限。
本页保留480 MHz条件下的预算算例,并给出实际测量方法。以下频率表不是某块开发板的实测结果,也不代表1~5 MHz中断在任意应用中都合理。
先确定硬件和运行条件
跳转到“先确定硬件和运行条件”H743采用Cortex-M7,配有16 KiB指令缓存和16 KiB数据缓存。允许的最高CPU频率还取决于硅片修订、电压档、Flash等待状态和时钟配置;不能只看料号就假设当前是480 MHz。普通TIM的时钟也与CPU不同,需核对APB分频、TIMPRE及其规格上限。STM32H743规格、AN5312修订迁移
记录测试条件时至少包括:实际CPU与定时器时钟、代码和栈所在存储区、缓存状态、编译器/优化选项、HAL版本、FPU使用情况、其他中断和RTOS任务。H743的Chrom-ART图形加速器不是对任意ISR从Flash执行时间的保证,不能把不同系列的ART描述混用。
区分三个时间量
跳转到“区分三个时间量”| 时间量 | 起点与终点 | 用来回答什么 |
|---|---|---|
| 响应延迟 | 外部事件或硬件请求出现,到ISR开始执行 | 事件是否能及时处理 |
| ISR内测量区间 | 代码中两个计时点之间 | 某段软件处理消耗多少周期 |
| 一次完整服务成本 | 因该中断发生而增加的全部CPU工作 | 平均负载预算和其他工作的可用时间 |
异常进入/返回、编译器保存寄存器、FPU现场、内存访问、缓存失效、总线竞争、优先级屏蔽和嵌套都会影响结果。Cortex-M7支持尾链和迟到中断等机制,但不能把“入口12周期+出口12周期”当作全部工程的固定ISR总成本。Arm Cortex-M7异常进入与返回
在C函数开头读取DWT时,部分入口和函数序言已经执行;最后读取之后还存在统计写入、函数尾声和异常返回。因此代码测得100周期,不等于整次服务只占100周期。
用周期数做预算
跳转到“用周期数做预算”设CPU频率为 ,实际完成的每次服务平均消耗 个CPU周期,中断服务频率为 。在统计口径一致、没有重复计算嵌套成本时,平均占用近似为:
若要求这类中断占用不超过预算 ,算术上有:
下面假设CPU为480 MHz,并假设完整服务成本已经是表中的数值:
| 假设完整服务成本 | 算术上占满CPU时的服务频率 | 分配50%平均CPU预算时 |
|---|---|---|
| 30周期 | 16 MHz | 8 MHz |
| 50周期 | 9.6 MHz | 4.8 MHz |
| 100周期 | 4.8 MHz | 2.4 MHz |
| 200周期 | 2.4 MHz | 1.2 MHz |
| 500周期 | 960 kHz | 480 kHz |
| 1000周期 | 480 kHz | 240 kHz |
这些是除法结果,不能把“30周期”自动指定给空ISR,也不能把“100~200周期”自动指定给任意HAL回调。占满CPU的列更不是可用于产品的目标,它没有给主循环、通信、操作系统或突发事件留下时间。
例如100 kHz、每次500周期,在480 MHz下约占10.42%的平均周期预算;1 MHz则约104.17%,已经超出这个假设下的总预算。可见仅说“100 kHz一定有问题”或“1 MHz一定很轻松”都缺少服务成本条件。即使平均预算未超,最坏响应延迟仍可能不满足某个控制周期。
DWT区间测量
跳转到“DWT区间测量”使用CYCCNT前,需要启用相应调试/跟踪功能,确认实现了周期计数、软件锁状态允许配置,再使能CYCCNT并验证它确实在递增。不要因为调试器连接时它恰好可用,就假设脱离调试器启动也已经配置完成。运行中不要由不同模块重复清零同一个计数器。
以下函数只测量一次函数调用区间,要求DWT已经正确启用,测量期间CPU频率不变、计数器不被复位,区间短于一次32位回绕:
#include <stdbool.h>#include <stdint.h>#include "stm32h743xx.h"
bool measure_cycle_interval(void (*work)(void), uint32_t *cycles){ if (work == 0 || cycles == 0 || (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk) != 0u || (DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk) == 0u) { return false; } __DSB(); __ISB(); uint32_t start = DWT->CYCCNT; work(); __DSB(); __ISB(); *cycles = DWT->CYCCNT - start; return true;}这里的屏障、间接调用和结束读取也有开销;结束DSB还会等待先前显式访问完成。可以用空工作函数测一个参考基线,但不能认为所有流水线、缓存和总线状态下都能精确减去同一个常数。若允许中断抢占,区间可能包含其他ISR时间;若为测量而屏蔽中断,又改变了实际运行条件,应分别标注。
480 MHz下,32位CYCCNT约8.948秒回绕。无符号减法能处理数值跨零,但不能区分已经经过多圈。时间换算使用实测/已核实的CPU时钟:
低功耗、调试暂停或动态变频可能改变该解释。不要把这些条件下的CYCCNT差值直接当作连续墙上时间。
在ISR里记录区间
跳转到“在ISR里记录区间”下面展示TIM2更新事件的一个精简测量入口。应用必须先完成TIM2/NVIC配置、开启DWT,并提供 service_tick()。它只处理独占TIM2的更新来源,不是任意共享TIM中断的通用处理器。
#include <stdint.h>#include "stm32h743xx.h"
extern void service_tick(void);volatile uint32_t irq_samples;volatile uint32_t irq_last_cycles;volatile uint32_t irq_max_cycles;
void TIM2_IRQHandler(void){ if ((TIM2->SR & TIM_SR_UIF) != 0u && (TIM2->DIER & TIM_DIER_UIE) != 0u) { uint32_t start = DWT->CYCCNT; TIM2->SR = ~TIM_SR_UIF; service_tick(); uint32_t elapsed = DWT->CYCCNT - start; irq_last_cycles = elapsed; if (elapsed > irq_max_cycles) { irq_max_cycles = elapsed; } irq_samples++; } __DSB();}所测区间包含清标志和 service_tick(),不包含前面的标志判断、部分入口开销、后面的统计和异常返回。它适合比较工作函数改动,不应直接拿这个数值填入“完整服务成本”表。前台读取多个统计字段时使用一致快照;打印和格式化放到前台,不要放进被测高频ISR。
TIM2->SR=0会同时清掉其他已置位标志。对写0清除的状态位,读改写也可能误清读取后才到达的另一事件;应按手册语义只清本次处理的目标。上例采用对应目标位写0、其余位写1的形式,与HAL定时器清标志宏的思路一致。
软件次数不等于硬件事件数
跳转到“软件次数不等于硬件事件数”外设状态位和NVIC挂起位通常不能无限保存同一来源的多个事件。若UIF已经是1,随后又发生更新,软件可能仍只看到一个1。ISR每次递增的 irq_samples 统计的是被处理的服务次数,不能自行证明每个硬件周期都已服务。
检验高频中断需要一个独立参照,例如:
- 让硬件定时器输出一个可观察的比较/PWM信号,同时用逻辑分析仪对照ISR GPIO脉冲。
- 使用另一个硬件计数/捕获通道记录源事件,比较源事件数和软件服务数。
- 使用DMA收集捕获或采样数据,检查缓冲区序列、溢出和处理进度;DMA同样有带宽和缓冲容量限制。
输入捕获还要记录CCxOF过捕获。只看平均ISR间隔、只看LED仍在闪烁,或只看串口还有输出,都不能排除已经丢事件。
GPIO与主循环观察的作用
跳转到“GPIO与主循环观察的作用”在ISR入口置GPIO、出口清GPIO,可以观察被包围代码的脉宽及抢占造成的延长。要测完整响应延迟,还需要在另一通道同时观察真正的源事件;仅有ISR自己的GPIO无法给出事件发生到入口之间的时间。GPIO写入也经过总线,并不与C语句零延迟等同。
原稿用中断开启前后主循环 main_count 的下降比例估算负载,这可以作为粗略比较,但会受编译优化、访存、缓存、计数溢出、测试窗口和打印影响。循环减少50%不应直接标成精确50%CPU占用。固定构建与测试条件后,它能帮助发现明显退化,精确预算仍需合适的计时和事件完整性证据。
怎样降低开销
跳转到“怎样降低开销”优先减少需要CPU逐次处理的事件:用硬件PWM/比较产生边沿,用定时器触发ADC,用DMA按块搬运,再让任务批量处理。需要高频事件并不意味着必须同频进入CPU中断。
之后再测量是否值得精简HAL分派、减少回调层级、避免浮点/复杂计算,或将时序关键代码及数据放入合适的ITCM/DTCM。放入TCM前要核对链接布局;DMA可达性和D-Cache一致性也要另行检查,见 H7 USB DMA与缓存。
优化应同时报告平均/最大区间、完整响应延迟、源事件与服务次数、其他任务的最坏延迟,以及冷/热缓存等测试条件。只有这些条件一起满足,才能判断某个频率适合当前系统。