H HRTOS 示例
Time Control Core

延时 vs 等待

在 HRTOS 中,os_delay 和 os_event_wait 代表两种不同的阻塞机制。 os_delay 是时间驱动阻塞,由系统 Tick 递减计数唤醒; os_event_wait 是事件驱动阻塞,由事件触发立即唤醒。 本示例对比两种机制的调度差异,展示正确时间控制方式对系统实时性的影响。

示例目标

系统运行三个任务:task_delay(时间驱动)、task_wait(事件等待)、task_event_trigger(事件触发)。 通过 LED 行为直观验证两种阻塞机制的差异,理解任务让出 CPU 与任务暂停执行的关系。

核心API os_delay / os_event_wait
调度触发 Tick / 事件触发
阻塞方式 时间队列 / 事件队列
实时响应 周期性 / 即时响应

核心机制

  • 时间驱动阻塞机制
  • 事件驱动阻塞机制
  • Tick 递减唤醒
  • 事件触发唤醒
Mechanism Definition

机制定义

两种阻塞机制的基本概念

在 HRTOS 中,delay 和 wait 代表两种不同的阻塞路径,分别对应时间驱动调度和事件驱动调度。 理解这两种机制的区别对于设计实时系统至关重要。

os_delay(时间驱动阻塞)

任务进入延时队列,由系统 Tick 递减计数,到期后恢复调度。 属于"Tick countdown based blocking",适用于周期性背景任务。

os_event_wait(事件驱动阻塞)

任务阻塞在事件队列,直到 os_event_write 触发立即唤醒。 属于"Event wake-up based blocking",适用于高实时响应逻辑。

HRTOS 模型: Tick Scheduler + Time Blocking + Event Blocking + ISR/Task Wake-up Dispatch
Core Differences

核心行为差异

两种机制的关键区别

os_delay(时间任务)

阻塞方式:任务进入延时队列

唤醒机制:由系统 Tick 递减计数,到期后恢复调度

调度触发:Tick 驱动调度

适用场景:周期性背景任务

os_event_wait(事件任务)

阻塞方式:任务阻塞在事件队列

唤醒机制:直到 os_event_write 触发立即唤醒

调度触发:ISR/任务主动唤醒调度

适用场景:高实时响应逻辑

调度触发机制

delay:Tick 驱动调度,按时间片轮转

event:ISR/任务主动唤醒调度,即时响应

优先级:事件模型优先级更高

响应延迟:事件模型显著低于纯时间模型

实时性对比

时间模型:响应延迟受 Tick 周期限制

事件模型:响应延迟极低,接近即时

CPU 利用:事件模型更高效,避免空转

系统设计:根据实时性要求选择合适机制

Execution Flow

执行流程

三种任务的执行路径

1Delay Task:运行 → LED 翻转 → os_delay → Tick 阻塞 → 恢复
2Event Task:等待 → os_event_wait → 阻塞 → os_event_write 触发 → 立即唤醒
3Trigger Task:周期延时 → 写事件 → 唤醒等待任务
hrtos_main → os_task_create → task_delay(时间驱动) → task_wait(事件等待) → task_event_trigger(事件触发) → os_delay / os_event_wait → Tick/事件唤醒 → LED 行为验证
Core Code

核心代码

延时 vs 等待的完整实现

任务函数实现

task_delay、task_wait 和 task_event_trigger 任务函数

#include "hrtos.h"

#define EVENT_ID 1

sbit LED_DELAY  = P1^0;
sbit LED_WAIT   = P1^1;
sbit LED_EVENT  = P1^2;

/* 时间驱动任务 */
void task_delay(void)
{
    while(1)
    {
        LED_DELAY = ~LED_DELAY;
        os_delay(10);   // Tick阻塞
    }
}

/* 事件等待任务 */
void task_wait(void)
{
    while(1)
    {
        if(os_event_wait(EVENT_ID, 0))
        {
            LED_WAIT = ~LED_WAIT;

            os_event_delete(EVENT_ID);

            {
                u16 i = 10000;
                while(i--);
            }
        }
    }
}

/* 事件触发任务 */
void task_event_trigger(void)
{
    while(1)
    {
        os_delay(20);

        os_event_write(EVENT_ID);

        LED_EVENT = ~LED_EVENT;
    }
}

系统初始化与任务创建

hrtos_main 函数,初始化事件并创建三个任务

/* 系统入口 */
void hrtos_main(void)
{
    LED_DELAY = 0;
    LED_WAIT  = 0;
    LED_EVENT = 0;

    os_event_init(EVENT_ID);

    os_task_create((unsigned int)task_delay,        1, 2, 5);
    os_task_create((unsigned int)task_wait,         2, 3, 5);
    os_task_create((unsigned int)task_event_trigger,3, 2, 5);
}
API Reference

API 对照(v2)

相关的核心 API

Time API

os_delay - 时间驱动阻塞函数

System Significance

系统意义

机制对系统设计的影响

调度路径差异

在 HRTOS 中,delay 属于"时间驱动调度路径",event 属于"事件驱动调度路径"。 两种路径对应不同的调度策略和实时性保证。

实时性选择

实际系统中,event 模型通常用于高实时响应逻辑(如中断处理、关键事件), delay 用于周期性背景任务(如数据采集、状态监控)。

CPU 利用效率

事件驱动机制避免了 CPU 空转,提高了系统资源利用率。 时间驱动机制适用于需要精确时间控制的场景。

系统设计原则

正确选择阻塞机制对系统实时性和稳定性至关重要。 应根据任务特性和实时性要求,合理使用 delay 和 event 机制。

核心判断: delay 和 wait 的本质区别在于调度触发方式:delay 基于 Tick 时间片,wait 基于事件触发。 事件模型具有更高的实时性和响应速度,适合关键任务;时间模型适合周期性任务。