一、功能简介

在实时操作系统中,任务阻塞并不只有 Delay 一种形式。

除了时间延时之外,任务还可能因为等待事件而进入阻塞状态。对于系统调试而言,仅仅知道“任务没有运行”是不够的,还需要进一步知道:

  • 当前任务是否正在等待 Event;

  • 任务正在等待哪个 Event;

  • 当前有多少任务等待同一个 Event;

  • 哪些任务正在等待指定 Event。

HRTOS Debug 提供了 Event Wait 功能,用于分析普通任务的事件等待状态。

该模块直接读取 HRTOS 内核任务控制块中的状态信息,通过任务的 wait_typewait_obj 判断任务是否处于 Event 等待状态,并进一步统计各 Event 对应的等待任务。

整个模块采用只读方式访问内核任务控制块,不修改内核数据,因此不会参与任务调度和事件处理本身。


二、Event Wait 的判断机制

HRTOS Debug 通过任务控制块中的:

OS_TASK[id].wait_type

判断任务当前的等待类型。

当:

OS_TASK[id].wait_type == WAIT_EVENT

时,说明该任务当前处于 Event 等待状态。

任务等待的 Event 编号则保存在:

OS_TASK[id].wait_obj

HRTOS Debug 中 Event 编号范围为:

Event 0 ~ Event 7

因此,一个任务的 Event 等待关系可以表示为:

Task ID
   │
   ├── wait_type
   │      └── WAIT_EVENT
   │
   └── wait_obj
          └── Event ID

这种设计使 Debug 模块不需要改变内核机制,只需要读取已有的任务运行状态即可完成分析。


三、判断任务是否等待 Event

首先提供单任务查询接口:

unsigned char HRTOS_DEBUG_EventWait_IsWaiting(
    unsigned char task_id);

使用方式:

if (HRTOS_DEBUG_EventWait_IsWaiting(3))
{
    /* Task 3 正在等待 Event */
}

函数首先检查任务 ID 是否有效,然后读取任务控制块中的 wait_type

if (OS_TASK[task_id].wait_type == WAIT_EVENT)
{
    return 1;
}

因此可以快速判断指定任务当前是否因为 Event 而阻塞。


四、获取任务等待的 Event

仅仅知道任务处于 Event 等待状态还不够,还需要知道它等待的是哪个 Event。

HRTOS Debug 提供:

unsigned char HRTOS_DEBUG_EventWait_GetEvent(
    unsigned char task_id);

例如:

event_id = HRTOS_DEBUG_EventWait_GetEvent(3);

如果 Task 3 当前等待 Event 5,则返回:

5

如果任务当前没有等待 Event,则返回:

HRTOS_DEBUG_INVALID_ID

函数同时检查 wait_obj 是否处于合法的 Event 范围内,从而避免直接使用无效的 Event 编号。


五、统计指定 Event 的等待任务数量

对于系统调试而言,一个非常有价值的信息是:

当前有多少任务正在等待同一个 Event?

HRTOS Debug 提供:

unsigned char HRTOS_DEBUG_EventWait_GetCount(
    unsigned char event_id);

例如:

count = HRTOS_DEBUG_EventWait_GetCount(2);

如果 Task 1、Task 4 和 Task 7 都在等待 Event 2,那么结果为:

Event 2 Wait Count = 3

实现方式是扫描全部普通任务:

for (i = 0; i < HRTOS_DEBUG_TASK_MAX; i++)
{
    if (OS_TASK[i].wait_type == WAIT_EVENT)
    {
        if (OS_TASK[i].wait_obj == event_id)
        {
            count++;
        }
    }
}

由于 HRTOS 的普通任务数量是固定的,这种遍历方式简单、确定,并且适合 8051 这种资源受限的平台。


六、获取 Event 等待任务位图

除了数量之外,HRTOS Debug 还提供了更加直接的任务分布信息:

unsigned int HRTOS_DEBUG_EventWait_GetMask(
    unsigned char event_id);

返回值为 16 位任务位图:

bit0  = Task 0
bit1  = Task 1
...
bit15 = Task 15

例如:

Event 3

Wait Mask = 0x0092

对应:

Task 1
Task 4
Task 7

正在等待 Event 3。

位图相比单纯的任务数量更加直观,因为它同时保留了等待任务的具体身份信息

核心实现:

mask |= ((unsigned int)1 << i);

最终可以通过一个 16 位变量表示整个任务等待关系。


七、统计当前所有 Event 等待任务

HRTOS Debug 还提供:

unsigned char HRTOS_DEBUG_EventWait_GetTotal(void);

用于统计当前所有处于 Event 等待状态的普通任务。

例如:

Task 2 → Event 0
Task 5 → Event 3
Task 8 → Event 3
Task 10 → Event 6

那么:

Event Wait Total = 4

这个接口适合用于系统级状态监控,例如 Debug Shell、状态页面或者运行时诊断信息。


八、一次获取全部 Event 状态

如果需要完整分析整个 Event 系统,可以使用:

unsigned char HRTOS_DEBUG_EventWait_GetAll(
    HRTOS_DEBUG_EVENT_WAIT_INFO xdata *info);

该接口一次扫描:

Event 0
Event 1
Event 2
...
Event 7

并分别获得:

info[i].event_id
info[i].wait_cnt
info[i].wait_mask

最终可以形成类似这样的调试信息:

Event 0 : Count=2  Mask=0x0009
Event 1 : Count=0  Mask=0x0000
Event 2 : Count=1  Mask=0x0020
Event 3 : Count=3  Mask=0x0092
...
Event 7 : Count=0  Mask=0x0000

这样就可以快速观察整个系统中的 Event 等待分布。


九、与任务调试功能结合

Event Wait 并不是孤立的调试功能。

它可以与 HRTOS Debug 中其他运行状态监控模块结合起来。

例如:

Task Monitor
    │
    ├── 当前任务状态
    │
    ├── Delay Wait
    │
    └── Event Wait
            │
            ├── 等待 Event ID
            ├── 等待任务数量
            └── 等待任务位图

Resource Monitor
    │
    ├── Semaphore
    ├── Mutex
    ├── Event
    └── Message Queue

这样可以从不同角度分析任务为什么没有运行。

例如一个任务处于阻塞状态时,可以进一步判断:

任务阻塞
   │
   ├── Delay
   │
   ├── Event
   │
   ├── Semaphore
   │
   ├── Mutex
   │
   └── Message Queue

这比单纯显示任务 ID 和任务状态更加有利于定位实时系统中的运行问题。


十、只读设计

Event Wait 模块的一个重要特点是:

Debug 模块只读取内核状态,不修改内核数据。

模块访问:

OS_TASK[]

获取任务当前的:

wait_type
wait_obj

然后进行统计和分析。

它不会:

  • 修改任务状态;

  • 修改 Event 状态;

  • 修改任务等待链;

  • 触发任务调度;

  • 改变内核资源。

因此 Debug 功能与 RTOS 核心机制保持了解耦。

这种设计尤其适合实时系统调试:调试工具本身不应该成为被调试系统运行状态的干扰源。


十一、总结

HRTOS Debug 的 Event Wait 模块通过读取任务控制块,实现了对 8051 实时系统 Event 阻塞状态的运行时分析。

目前主要提供:

功能作用
IsWaiting()判断任务是否等待 Event
GetEvent()获取任务等待的 Event 编号
GetCount()统计指定 Event 的等待任务数量
GetMask()获取指定 Event 的等待任务位图
GetTotal()统计全部 Event 等待任务
GetAll()一次获取全部 Event 等待信息

对于资源受限的 8051 平台,这种基于内核真实运行状态的轻量级监控方式,可以在不改变 RTOS 核心机制的情况下,为任务阻塞分析提供更加完整的信息。

Event Wait 与 Delay Wait、Resource Monitor、Task Monitor 等功能组合后,可以进一步形成一套完整的 HRTOS 运行状态分析体系,帮助开发者快速了解任务当前为什么等待、等待什么,以及系统中任务之间的等待关系。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐