RTOS 提供任务调度、通信和时间服务,实时性仍由任务执行时间、优先级、阻塞和中断共同决定。先写清哪些工作必须在何时完成,再决定需要几个任务;每个功能各建一个任务往往会增加栈、同步和状态切换成本。
任务状态与时间要求
任务可能处于运行、就绪、阻塞或挂起等状态。阻塞等待队列或通知可以让出 CPU;循环检查标志仍然占用 CPU。高优先级任务若始终就绪,低优先级任务就可能长期得不到执行。
对周期任务记录周期 T、相对期限 D、最坏执行时间 C 和优先级。C 应包含需要计入的执行开销,不能用一次空载平均值替代。硬期限要求每次都满足;可以容忍偶发丢帧的遥测任务应明确丢弃规则和可接受延迟。
| 工作 | C | T 与 D | 固定优先级安排 |
|---|---|---|---|
| 快速采集 | 1 ms | 4 ms | 最高 |
| 数据处理 | 2 ms | 8 ms | 中 |
| 状态上传 | 2 ms | 16 ms | 低 |
这组任务利用率为 1/4+2/8+2/16=0.625。利用率小于 1 只是必要条件之一;固定优先级、不同释放时刻和阻塞可能仍使某个任务超期。
逐项计算响应时间
对独立、单核、可抢占的周期任务,在固定优先级、期限不大于周期且忽略释放抖动的模型中,可迭代:
R(k+1) = C + B + Σ ceil(R(k) / Th) × Ch
B 是相关阻塞上界,求和项来自所有更高优先级任务。迭代稳定且 R≤D 才在该模型下通过;若超过期限就失败。上表得到响应时间 1、3、6 ms。实际工程还要计入中断干扰、切换开销、临界区和任务释放抖动,不能直接把该结果当作上板证明。
下载 固定优先级响应时间实验,执行 python schedule.py。它核对上述可调度任务,并检查一个利用率超载的反例被拒绝。脚本做数学分析,没有运行 FreeRTOS 内核。
tick 与周期漂移
tick 是调度计时单位,分辨率受配置影响;毫秒转换还可能发生截断,短于一个 tick 的等待要特别检查。提高 tick 频率会增加调度中断成本,精密采样通常由硬件定时器触发,再通知任务处理。
相对延时会把本轮执行时间叠加到周期。对于支持相应 API 的 FreeRTOS 内核,可使用绝对周期推进:
TickType_t last = xTaskGetTickCount();
for (;;) {
acquire_and_process(); /* 该函数需要由应用提供。 */
xTaskDelayUntil(&last, pdMS_TO_TICKS(20));
}
这段接口示意以 FreeRTOS Kernel V11.1.0 为阅读版本,依赖正确移植、配置和应用函数,未独立编译。超过周期时不能靠 DelayUntil 自动补救;要记录超期,决定丢过期任务、降采样或进入故障状态。
练习与面试自查
把数据处理的 C 改成 5 ms,重新分析并解释首先受影响的任务;再加入 3 ms 互斥阻塞,看 CPU 利用率没变时响应时间为什么仍会恶化。测量时记录最大执行时间、栈高水位和超期次数,同时保留测量负载条件。
自查:高优先级任务调用延时后谁运行?时间片轮转与抢占有什么关系?相同周期的两个任务能否直接用平均执行时间验收?软定时器回调为什么不适合长时间阻塞?
参考:FreeRTOS 任务调度文档、FreeRTOS Kernel V11.1.0 配置与接口、Joseph 与 Pandya:实时系统响应时间分析。