本节摘要:时间事件有三个供给来源:系统节拍驱动毫秒级世界,硬件定时器直供微秒级精度,软件定时器服务秒级杂务。本节讲清三者的精度边界与开销差异,给出节拍频率的配置准则与低功耗的 tickless 方案,并附定时器选型阶梯。
一九七一年的第一台单片定时器芯片问世时,工程师们把它称为「系统的心跳」——这个比喻沿用至今:节拍中断每毫秒敲一次,任务世界的日历、闹钟、延时全部由这一下一下的心跳推着走。但心跳只是时间体系的一层。本节把三层时间来源摆在一起:什么时候用心跳、什么时候绕过心跳、什么时候连心跳都可以停。
节拍是 RTOS 时钟组件的地基:硬件定时器周期性溢出,中断里节拍计数加一,延时列表与超时检查随之推进(2.1 节的时钟链路)。它的两个属性决定了整个任务世界的时间行为。一是精度:所有 vTaskDelay 与带超时的等待都以节拍为刻度,1 千赫兹节拍下毫秒就是最小单位,3 毫秒的延时实际落在 3 到 4 毫秒之间。二是开销:每拍一次中断、一次列表头检查,千赫兹节拍意味着每秒至少千次中断,这在主频紧张的芯片上不是小数。
配置准则因此有两条。节拍频率由最细的时间需求决定:最快的周期任务是 5 毫秒一次,节拍设 1 千赫兹(1 毫秒)已留出五倍分辨率,设 10 千赫兹纯属浪费八倍的中断预算。节拍值与硬件定时器能力匹配:节拍周期必须是定时器时钟的整数倍,否则每拍积累半拍误差——「测量发现周期任务整体慢了千分之一」这类报告,常源于此。
需要比节拍更细的时间时,直接用一路硬件定时器,不等节拍对齐。典型场景是电机电流环的几十微秒周期、超声波测距的回波计时、PWM 波形的精确边沿。硬件定时器的中断走 6.1 节的标准管线,只是它自带「时间到」的触发源:
/* 微秒级周期:一路硬件定时器独立于系统节拍 */ void TIM2_IRQHandler(void) /* 每 50 微秒触发 */ { TIM2->SR &= ~TIM_SR_UIF; /* 清溢出标志 */ ADC_SoftwareStartConv(ADC1); /* 触发采样,任务侧收数据 */ }
要分清「定时精度」与「触发抖动」:定时器本身的计数精度可达时钟一个周期,但触发后真正执行动作的时刻还叠着 6.1 节的延迟四段,最坏情况要看全系统最长关中断时间。需要输出级精确时序(如某些传感器协议)时,正确做法是用定时器的外设联动能力(触发 DMA、直接驱动输出比较引脚)把处理器彻底绕开,而不是靠中断里掐时间。
软件定时器不是硬件,而是内核在节拍之上提供的服务:到期回调由一个专职的定时器服务任务代为执行。它适合「秒级、低频、不讲究」的杂务——按键去抖、指示灯慢闪、周期性状态上报。两个使用要点:回调运行在服务任务的上下文,回调里禁止阻塞,否则所有软件定时器一起晚点;到期精度受节拍与服务任务调度双重影响,只适合宽松场合。
三层的选型阶梯可以一句话总结:毫秒级找节拍,微秒级找硬件定时器,秒级杂务找软件定时器。把微秒需求塞给节拍(把节拍配到几十千赫兹)是最常见的错误配置,等于让全系统为一路需求陪跑。
电池供电的设备大部分时间无事可做:水表每小时抄一次,传感器每分钟采一轮,剩下的时间任务都在阻塞等待。此时千赫兹的节拍成了纯粹的耗电项——每次心跳都把处理器从深睡中拉起来一次。tickless 模式的思路:进入空闲时算出「下一个到期事件还有多久」,据此设置定时器只在此刻唤醒一次,中间的节拍中断全部省去;醒来后把睡眠时长一次性补进节拍计数,任务世界的时间账不受影响。
代价与适用面同样清楚:唤醒后的补偿逻辑让节拍精度略降;睡眠期间失去周期性的处理器活动,某些依赖固定轮询的外设驱动需要适配;调试器跟踪的时间线会出现长空洞,需要工具理解 tickless。功耗敏感项目值回票价——深睡电流与活跃电流相差三四个数量级,省下一次无用心跳就是实实在在的电池寿命。

背景。电池供电的智能水表,要求每月上报一次用量,同时阀门动作要在一百毫秒内完成指令到执行。整机预算:一节锂电池撑十年。
操作。系统节拍仅用于按键扫描与阀门状态机,跑在千赫兹;上报周期与日历时钟由外置低功耗实时时钟芯片维护,平时根本不唤醒主芯片;阀门动作前由实时时钟中断唤醒处理器,开启节拍运行阀门状态机,完成即回到 tickless 深睡。软件定时器承担指示灯与重试逻辑。
结果。整机平均电流从改造前的百微安级降到个位数微安级,电池寿命测算越过十年红线;阀门动作全程节拍正常,一百毫秒要求以最坏四十七毫秒通过。
解读。案例的要点在「分工」:把日历级的时间职责交给为低功耗而生的外置时钟,把毫秒级的职责留给节拍,把十年功耗目标变成对「心跳次数」的约束——三层时间来源各守一段,谁也不越位。若把上报轮询交给主芯片的节拍硬扛,千赫兹心跳本身就足以吃掉十年预算。
变式。若水表升级为支持远程即时开阀(秒级响应的网络指令),网络芯片的唤醒链路要加入时钟设计:无线电接收必须周期性开机监听,监听周期与响应时限的乘积决定了另一层功耗预算,这是低功耗广域网协议设计的经典权衡,思路与 tickless 同源——「为下一次必须醒来的时刻而醒来」。
问:节拍设五百赫兹行不行? 由最细需求决定:若最细的周期任务是十毫秒,五百赫兹(两毫秒刻度)有五倍分辨率,完全够用还省了一半节拍中断。节拍值没有「标准答案」,只有与需求的匹配度。
问:系统时间与节拍是什么关系? 任务世界的时间全部由节拍推算,节拍停(tickless 睡眠中)系统时间就停,醒来后补偿。需要真正的墙钟时间,用外置实时时钟芯片——本节水表案例的做法。
问:软件定时器回调里能调用 API 吗? 能调用非阻塞的内核 API,不能阻塞、不能等锁。把它当成「跑在定时器服务任务里的一段普通代码」来要求就对了。
问:定时器精度实测总比设定值差一拍,正常吗? 正常,节拍刻度的量化效应:设定值落在两拍之间时按后一拍生效。需要更准就换硬件定时器,不是调参能解决的事。
问:多个定时器同时到期会怎样? 内核按到期顺序逐个处理,回调彼此串行——所以回调必须短,一个慢回调会把后面所有定时器拖晚。周期接近的多个定时器还应错开相位,避免周期性叠加成负载尖峰。