Time Management · HRTOS

任务延时 Task Delay

任务延时用于表达“当前任务暂时不需要继续执行”的时间要求。 通过系统时间基准与调度机制配合,任务可以在延时期间让出处理器, 并在满足恢复条件后重新参与调度。

Tick Timing Task Scheduling Time Conversion
01

延时机制概述

延时是任务级时间控制机制,不等同于 CPU 忙等待。

在 RTOS 中,任务延时通常用于周期性工作、等待指定时间后继续执行, 或为其他任务提供处理器执行机会。与循环查询时间的忙等待不同, 可调度的任务延时会结合内核调度机制处理任务的暂停与恢复。

Task-level

任务级延时

通过内核接口请求延时,任务在等待期间不继续执行其后续代码。

Tick-based

节拍时间基准

系统 Tick 为内核提供离散的时间计数,延时到期判定受节拍机制影响。

Scheduler

重新参与调度

延时条件满足后,任务可以重新具备运行资格;不代表它会立即获得 CPU。

Timing

时间精度

实际延时受到 Tick 配置、调用时刻与调度开销等因素影响。

关键区别: 延时到期、任务重新就绪与任务真正开始执行,是三个不同的时刻。 不能把请求的延时时长直接理解为任务一定会在该时刻精确恢复运行。
02

工作原理

从延时请求到重新调度,涉及时间推进与任务状态管理。

在典型的 Tick 驱动任务延时模型中,任务提交延时请求后, 内核记录相应的时间条件,并通过调度机制使当前任务暂停执行。 系统时间基准继续推进,满足到期条件后,任务被恢复为可参与调度的状态。

STEP 01 请求延时

任务调用延时接口,指定需要等待的时间。

STEP 02 暂停执行

内核根据延时语义处理任务的运行资格。

STEP 03 时间推进

系统时基推进,并判断延时条件是否满足。

STEP 04 重新调度

任务恢复参与调度,具体执行时刻取决于调度条件。

Conceptual Flow
Task requests delay
        |
        v
Kernel processes delay request
        |
        v
Task temporarily stops executing
        |
        v
System time advances
        |
        v
Delay condition is satisfied
        |
        v
Task becomes eligible for scheduling
        |
        v
Scheduler selects the next task
实现说明: 上述流程是概念模型,不规定 HRTOS 必须使用某一种延时队列结构, 也不意味着每次 Tick 都会扫描所有任务。实际的到期检查、任务记录方式和调度触发路径应以当前内核实现为准。
03

Tick 与延时精度

Tick 是离散时间基准,实际延时精度不能只看请求参数。

Tick 通常由周期性系统时钟中断推进。若系统 Tick 周期为 \(T_{\text{tick}}\),则一个 Tick 对应的名义时间间隔为该周期。 延时请求与 Tick 边界之间的相位差,以及到期后的调度过程, 都会影响任务实际恢复执行的时刻。

Time Base
Tick frequency = f_tick
Tick period    = 1 / f_tick

Nominal elapsed time for N ticks:
T = N × T_tick

例如,若某系统配置的 Tick 周期为 1 ms,那么 10 个 Tick 对应的名义时间跨度为 10 ms。 这并不意味着任务调用延时接口后,经过严格的 10.000 ms 就一定开始继续执行。 实际结果仍取决于计时起点、到期判定方式与调度时机。

配置原则: 不应在通用文档中固定宣称 HRTOS 的 Tick 频率为某个范围。 应以具体工程的时钟配置和实际时基参数为准。 提高 Tick 频率可以缩小时间量化间隔,但也会增加节拍中断及相关处理开销。
04

时间管理接口

按任务延时、单位换算与系统时间读取三个方向理解接口。

API Reference · Verify Against Current Headers
os_delay(u16 tick)
os_delay_ms(u8 ms)
os_ms_to_tick(u16 ms)
os_sec_to_tick(u8 sec)
os_tick_config(u8 slice_count, u16 tick_value)
os_tick_get(u16 *high, u16 *low)
os_uptime_ms()
接口 用途说明 核对重点
os_delay() 请求基于 Tick 的任务延时。 参数单位、零值语义、适用调用上下文与实际恢复规则。
os_delay_ms() 以毫秒为单位表达延时需求。 忙等待延时,等待期间持续占用 CPU。
os_ms_to_tick() 毫秒到 Tick 的时间单位换算。 舍入方式、最小非零值与数值溢出边界。
os_sec_to_tick() 秒到 Tick 的时间单位换算。 返回类型、支持范围与大数值处理方式。
os_tick_config() 配置与系统节拍有关的参数。 各参数的真实含义、单位、合法范围及配置生效时机。
os_tick_get() 读取系统 Tick 计数。 高低部分的组合方式、读取一致性与计数回绕处理。
os_uptime_ms() 读取以毫秒表示的系统运行时间。 时间来源、分辨率、返回类型及长时间运行后的回绕行为。
API 版本提示: 上述接口名称沿用原页面所列内容。正式发布前,请确认它们在当前 HRTOS 版本的公开头文件中均存在, 并以函数声明、注释与实现核实参数类型和行为。表中的说明不替代实际 API 契约。
05

典型使用场景

将时间等待交给合适的机制,避免不必要的 CPU 占用。

Periodic Work

周期性任务

定期采样、状态检查或低频后台处理,可考虑使用任务级延时控制执行节奏。

Deferred Work

延后执行

在一次处理结束后等待一段时间,再进入下一轮工作。

Time Conversion

统一时间单位

通过经过核实的换算接口,将业务层时间需求转换为内核时基单位。

Short Timing

短时硬件时序

极短的硬件时序要求需要单独评估,任务延时通常不适合承担精确微秒级波形控制。

如果任务等待的是消息、信号量或其他事件,而不是固定时间, 应优先评估相应的等待或同步机制,避免用固定延时代替事件驱动。

忙等待与任务延时: 忙等待会在等待期间持续执行循环或查询操作,可能占用 CPU; 任务级延时则由内核调度机制处理等待过程。 具体 API 属于哪一类,应根据实际实现确认。
06

调用约束与边界条件

延时接口的可用性取决于执行上下文与参数契约。

  • 不要假设所有延时接口都可以在中断服务程序中调用;应以对应接口的调用约束为准。
  • 不要假设请求延时到期后任务会立即执行,任务还需要满足调度条件。
  • 检查零 Tick、最小延时、数值范围和时间换算中的舍入规则。
  • 涉及长时间运行的系统计数时,应考虑计数回绕与多字节读取的一致性。
  • 周期任务若要求控制长期漂移,应明确区分相对延时与基于统一时间基准的周期调度方案。
中断上下文: 任务延时通常依赖任务调度与任务切换,不能直接把它当作中断内可阻塞操作。 除非 HRTOS 对某个特定接口明确规定了 ISR 调用语义,否则不要在中断服务程序中调用任务级阻塞接口。
07

理解要点

正确理解延时的时间语义,比记住接口名称更重要。

  • 任务级延时的核心是改变任务继续执行的时机,而不是让 CPU 停止工作。
  • Tick 提供离散时间基准,Tick 周期并不等于所有任务延时的绝对误差上限。
  • 延时到期、任务重新具备运行资格、任务实际获得 CPU,是不同阶段。
  • 延时队列、到期扫描方式和调度触发路径属于实现细节,应以源码为准。
  • 时间换算、计数回绕与调用上下文约束,是接口文档不可忽略的部分。

建议结合 Time 模块总览、 Scheduler 调度机制、 任务状态模型 阅读,从系统时基、任务运行资格和调度决策三个层次理解延时行为。