2. 实时系统基础

TinyML 实时系统的验收,本质上是对“系统是否在既定时间约束下稳定运行”的工程判断。如果缺乏对实时操作系统(RTOS)核心机制的清晰认知,验收工作就容易停留在“功能是否跑通”的浅层,而无法回答“系统是否真正可靠”这一关键问题。本章将系统梳理 RTOS 的概念体系、任务调度策略、中断优先级设计以及时间约束分析方法,为后续章节中具体的稳定性测试、超时处理和资源余量评估提供统一的理论语言与判断框架。

RTOS 核心机制与时间约束分析框架 RTOS 核心概念 任务/内核/调度器 任务调度策略 优先级/时间片/抢占 中断优先级 ISR/嵌套/屏蔽 时间约束 截止期/抖动/响应 时间约束分析 WCET / 截止期 / 空闲时间 可调度性验证 CPU 利用率 < 上限(如 69%) 资源余量评估 栈/堆/带宽/响应时间余量 验收判定依据

上图展示了 RTOS 核心机制与时间约束分析之间的逻辑关系。在 TinyML 场景中,传感器数据采集、推理任务、通信上报等通常被拆分为多个实时任务,由 RTOS 统一调度。验收人员需要理解这些机制如何影响系统的端到端行为,才能设计出有效的测试用例和判定标准。

2.1 RTOS 核心概念与 TinyML 的适配

实时操作系统(RTOS)与通用操作系统(如 Linux)的本质区别在于其确定性。通用系统追求平均吞吐量,而 RTOS 追求在最坏情况下依然满足时间约束。对于 TinyML 设备而言,这意味着推理任务的启动时间、执行时间和完成时间都必须是可预测的。

RTOS 的三个核心抽象是任务(Task)、内核(Kernel)和调度器(Scheduler)。任务是并发执行的基本单位,每个任务拥有独立的栈空间和优先级。内核提供任务间通信(队列、信号量、互斥锁)和内存管理。调度器则根据既定策略决定哪个任务获得 CPU 使用权。

关键认知:在 TinyML 系统中,推理任务通常被设计为最高优先级或次高优先级任务,而传感器采集任务和通信任务则根据实时性要求分配不同优先级。例如,一个基于 Cortex-M4 的语音唤醒设备,其音频采集任务需要严格的时间周期(如每 10ms 采集一帧),而推理任务则可以在缓冲区满时被触发执行。

RTOS 的引入为 TinyML 带来了三个核心价值:时间确定性(任务在可预测的时间内完成)、模块化(不同功能解耦为独立任务)和资源管理(通过内核机制避免资源竞争)。但同时也引入了额外的上下文切换开销和内核服务调用延迟,这些在验收时都需要纳入考量。

2.2 任务调度策略:优先级、抢占与时间片

任务调度策略直接决定了系统在并发场景下的行为。TinyML 系统中最常用的调度策略是基于优先级的抢占式调度(Priority-Based Preemptive Scheduling)。在这种策略下,CPU 始终执行就绪队列中优先级最高的任务。当一个更高优先级的任务就绪时,当前任务会被立即抢占。

调度策略的选择需要权衡实时性与公平性。下表对比了三种常见调度策略在 TinyML 场景中的适用性:

调度策略 核心机制 TinyML 适用场景 潜在风险
优先级抢占 高优先级任务随时抢占 CPU 推理任务、紧急报警任务 低优先级任务可能饥饿
时间片轮转 同优先级任务轮流执行固定时间片 多个非实时后台任务(如日志记录) 时间片切换增加上下文切换开销
混合调度 高优先级抢占 + 同优先级时间片 大多数 TinyML 应用(推荐) 配置复杂度较高

在验收过程中,需要特别关注优先级反转问题。当一个低优先级任务持有互斥锁,而高优先级任务等待该锁时,中优先级任务可能抢占低优先级任务,导致高优先级任务被间接延迟。解决方案包括优先级继承或优先级天花板协议。验收时应检查代码是否使用了这些机制。

// 示例:FreeRTOS 中创建两个不同优先级任务的伪代码
// 传感器采集任务:优先级 3
xTaskCreate(sensor_read_task, "Sensor", 256, NULL, 3, &handle_sensor);
// 推理任务:优先级 5(更高)
xTaskCreate(inference_task, "Infer", 1024, NULL, 5, &handle_infer);

2.3 中断优先级与 ISR 设计

中断是实时系统响应外部事件的最快途径。在 TinyML 设备中,传感器数据就绪、定时器溢出、通信接收等事件都通过中断通知 CPU。中断优先级的设计直接影响系统的实时响应能力。

中断优先级需要遵循两个原则:中断服务程序(ISR)应尽可能短,以及关键中断的优先级应高于所有任务。ISR 中通常只做标记事件、拷贝数据到缓冲区等轻量操作,而将耗时处理(如推理)推迟到任务中执行。

常见误区:在 ISR 中直接调用 RTOS 的阻塞 API(如等待信号量)会导致系统崩溃或死锁。ISR 只能使用“FromISR”结尾的非阻塞 API。验收时需检查代码中是否存在此类违规调用。

中断嵌套也需要谨慎处理。虽然大多数 RTOS 支持中断嵌套,但嵌套深度过大会增加栈空间需求和延迟不确定性。建议在验收时通过静态分析工具检查最大中断嵌套深度,并确保栈空间预留充足。

2.4 时间约束:截止期、WCET 与响应时间

时间约束是实时系统验收的核心指标。每个实时任务都有三个关键时间参数:截止期(Deadline)、最坏执行时间(WCET)和响应时间(Response Time)。截止期是任务必须完成的时间点;WCET 是任务在最坏输入和最大干扰下的执行时间;响应时间是从任务就绪到完成的时间间隔。

可调度性分析的基本条件是:任务的响应时间必须小于等于其截止期。对于周期性任务,可以使用利用率分析(Utilization Analysis)进行快速判断。例如,对于 n 个周期任务,如果总利用率 U = Σ(Ci/Ti) ≤ 1,则系统在速率单调调度(RMS)下可调度(其中 Ci 为 WCET,Ti 为周期)。

在实际验收中,WCET 的测量比平均执行时间更重要。建议通过以下步骤获取可靠的 WCET 数据:

  1. 在目标硬件上运行任务至少 1000 次,覆盖不同输入数据分布。
  2. 使用逻辑分析仪或 RTOS 内置的 trace 工具记录每次执行时间。
  3. 取最大值并加上 10%-20% 的安全裕量作为 WCET 估计值。
  4. 考虑缓存命中率、分支预测等硬件因素对执行时间的影响。

经验提醒:对于 TinyML 推理任务,输入数据的维度变化(如不同尺寸的图像)会导致执行时间显著波动。验收时应设计包含最坏输入尺寸的测试用例,并单独测量该场景下的执行时间。

2.5 案例拆解:智能门锁的实时性验收

以一个基于 RTOS 的智能门锁系统为例,该系统包含指纹识别(推理任务)、密码输入(UI 任务)、蓝牙通信(通信任务)和电机驱动(控制任务)。验收目标是确保从指纹识别完成到电机动作的端到端延迟不超过 200ms。

系统约束:指纹识别推理任务周期为 100ms,WCET 为 45ms;控制任务周期为 20ms,WCET 为 5ms;通信任务为事件触发,WCET 为 15ms。所有任务运行在 100MHz 的 Cortex-M4 上。

初始现象:在实验室测试中,端到端延迟平均为 150ms,但偶发达到 230ms,超出设计指标。

分析过程:通过 RTOS trace 工具发现,偶发延迟发生在蓝牙通信任务与推理任务同时就绪时。由于通信任务优先级(优先级 4)高于推理任务(优先级 3),通信任务抢占了推理任务,导致推理完成时间延迟。进一步分析发现,通信任务在等待蓝牙数据时使用了阻塞等待,但等待期间释放了 CPU,问题不大;真正的问题在于通信任务的数据处理循环中有一个 10ms 的忙等待。

优化措施:将通信任务的忙等待改为信号量阻塞等待,并将推理任务优先级提升至 5,通信任务降为 3。同时,在控制任务中增加看门狗,确保电机驱动在 50ms 内响应。

结果对比:优化后,端到端延迟稳定在 120ms-160ms 之间,最坏情况为 175ms,满足 200ms 的截止期要求。CPU 利用率从 72% 降至 58%,为后续功能扩展留出了余量。

复盘经验:优先级分配不能仅凭直觉,需要基于任务的截止期和 WCET 进行系统分析。同时,验收测试必须包含“最坏情况组合”场景,即多个高优先级任务同时就绪的情况。

2.6 常见误区与总结复盘

在实时系统验收中,以下误区需要特别警惕:

  • 误区一:只测平均响应时间。实时系统的核心指标是最坏情况,平均时间无法反映系统在极端负载下的行为。
  • 误区二:忽略中断对任务的影响。高频率中断会消耗大量 CPU 时间,导致任务实际可用时间减少。验收时应测量中断占用 CPU 的比例。
  • 误区三:栈空间分配不足。RTOS 任务栈大小通常按最大调用深度估算,但实际中递归调用或大局部变量可能导致栈溢出。建议使用栈高水位标记(High-Water Mark)功能进行检测。
  • 误区四:认为优先级越高越好。过高的优先级可能导致低优先级任务饥饿,影响系统整体功能。优先级设计应基于截止期和重要性综合权衡。