云计算百科
云计算领域专业知识百科平台

HRTOS Debug:8051实时操作系统资源状态监控与分析

在实时操作系统中,任务调度只是系统运行机制的一部分,任务之间如何使用和等待系统资源,同样直接影响系统的运行状态。

例如,当一个任务长时间处于等待状态时,仅仅查看任务本身的信息,往往很难判断它究竟在等待什么。

如果能够直接查看资源对象的当前状态,就可以进一步回答:

  • 当前资源的值是多少?

  • 当前是否存在资源拥有者?

  • 有多少任务正在等待?

  • 哪些任务正在等待该资源?

  • 是否存在来自ISR的待处理信号?

针对这些问题,HRTOS Debug提供了 Resource状态监控功能。

该模块统一分析HRTOS内部的8个Resource对象,并提供资源值、拥有者、等待任务数量、等待任务位图以及ISR Pending Signal等运行状态信息。

需要特别说明的是:

HRTOS Debug Resource模块只读取和分析内核资源状态,不修改内核数据。


一、HRTOS Resource的统一设计

HRTOS内部采用统一的Resource对象管理部分同步和通信相关机制。

Resource对象包含以下主要信息:

Resource

├── value
├── owner
├── wait_cnt
├── wait_mask
└── pending_signal

这些Resource可以用于:

Semaphore
Mutex
Event
Message Queue Wait

因此,Debug模块并不需要针对每一种同步机制分别设计一套监控接口,而是直接读取统一的Resource对象。

整体关系可以表示为:

HRTOS Resource

┌────────────┼────────────┐
│ │ │
Semaphore Mutex Event
│ │
└──── Message Queue Wait ┘


HRTOS Debug

┌────────────┼────────────┐
│ │ │
Value Owner Waiters

Pending Signal

这种设计可以让Debug层与内核资源机制保持一致。


二、Resource对象

Debug模块通过以下方式访问HRTOS内部的Resource数组:

extern volatile OS_RESOURCE xdata OS_RES[
HRTOS_DEBUG_RESOURCE_MAX];

同时定义:

#define HRTOS_DEBUG_RESOURCE_MAX 8
#define HRTOS_DEBUG_INVALID_ID 0xFF

因此当前Debug模块监控:

Resource 0
Resource 1
Resource 2
Resource 3
Resource 4
Resource 5
Resource 6
Resource 7

共8个Resource对象。

每个Resource都有自己的运行状态。


三、Resource的五项核心信息

HRTOS Debug主要提供五类信息。

1. Resource Value

value

表示当前Resource的资源值。

对于不同类型的Resource,其具体含义由内核使用方式决定。

Debug模块不改变这个值,只负责读取当前状态。


2. Resource Owner

owner

表示当前Resource的拥有者。

这个字段对于Mutex等具有所有者概念的资源尤其有价值。

例如:

Resource 2
Owner : Task 5

可以直接知道当前资源由Task 5持有。

如果返回:

HRTOS_DEBUG_INVALID_ID

则可以表示当前没有有效的Owner。


3. Wait Count

wait_cnt

表示当前正在等待该Resource的任务数量。

例如:

Resource 3
Wait Count : 4

说明当前有4个任务处于该Resource的等待状态。

这对于分析任务阻塞非常有帮助。


4. Wait Mask

除了等待任务数量之外,HRTOS Debug还提供:

wait_mask

用于记录具体哪些任务正在等待该Resource。

HRTOS当前拥有16个普通任务,因此可以使用一个16位整数表示任务等待关系:

bit0 → Task 0
bit1 → Task 1
bit2 → Task 2

bit15 → Task 15

例如:

wait_mask = 0x002A

对应的二进制位中,可以直接分析出具体处于等待状态的任务。

这相比单独提供:

Wait Count = 3

提供了更多信息。

因为:

Wait Count告诉我们“有多少任务在等待”,Wait Mask则告诉我们“哪些任务在等待”。


5. Pending Signal

Resource还提供:

pending_signal

用于记录来自ISR的待处理信号计数。

这对于中断与任务之间的资源交互分析非常有意义。

例如:

ISR

├── 产生信号


Resource

└── pending_signal

Debug模块可以直接读取当前Pending Signal状态。


四、读取单个Resource

最基础的接口是:

unsigned char HRTOS_DEBUG_Resource_Get(
unsigned char id,
HRTOS_DEBUG_RESOURCE_INFO xdata *info)

调用时传入Resource编号和输出结构体地址。

首先进行ID检查:

if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 1;
}

当前有效ID范围:

0 ~ 7

如果超过范围,则直接返回错误。

随后检查输出指针:

if (info == 0)
{
return 2;
}

避免向无效地址写入数据。


五、Resource信息复制

参数检查完成后,Debug模块直接从内核Resource对象读取状态:

info->id =
id;

info->value =
OS_RES[id].value;

info->owner =
OS_RES[id].owner;

info->wait_cnt =
OS_RES[id].wait_cnt;

info->wait_mask =
OS_RES[id].wait_mask;

info->pending_signal =
OS_RES[id].pending_signal;

整个过程实际上就是:

OS_RES[id]

├── value
├── owner
├── wait_cnt
├── wait_mask
└── pending_signal


HRTOS_DEBUG_RESOURCE_INFO

Debug模块只负责读取和复制。


六、获取Resource等待任务数量

如果应用程序只关心当前等待任务数量,可以直接使用:

unsigned char HRTOS_DEBUG_Resource_GetWaitCount(
unsigned char id)

例如:

unsigned char count;

count = HRTOS_DEBUG_Resource_GetWaitCount(2);

返回:

0 ~ 16

这样就不需要读取完整的Resource结构。


七、获取等待任务位图

如果需要知道具体哪些任务正在等待,可以使用:

unsigned int HRTOS_DEBUG_Resource_GetWaitMask(
unsigned char id)

例如:

unsigned int mask;

mask = HRTOS_DEBUG_Resource_GetWaitMask(2);

然后根据对应bit判断任务状态。

结构如下:

16 bit Wait Mask

15 8 7 0
┌────────────────────┬────────────────────┐
│ Task 15 … Task 8 │ Task 7 … Task 0 │
└────────────────────┴────────────────────┘

因此一个16位变量即可表达全部16个普通任务的等待关系。

对于8051这种资源受限的平台,这种设计非常直接。


八、获取Resource Owner

对于需要关注资源所有者的场景,可以使用:

unsigned char HRTOS_DEBUG_Resource_GetOwner(
unsigned char id)

例如:

unsigned char owner;

owner = HRTOS_DEBUG_Resource_GetOwner(2);

如果Resource存在有效拥有者,则返回对应Task ID。

如果ID无效:

return HRTOS_DEBUG_INVALID_ID;

其中:

#define HRTOS_DEBUG_INVALID_ID 0xFF

用于区分正常Task ID和错误状态。


九、获取Resource Value

如果只需要查询资源当前值,可以使用:

unsigned char HRTOS_DEBUG_Resource_GetValue(
unsigned char id)

例如:

unsigned char value;

value = HRTOS_DEBUG_Resource_GetValue(0);

这种接口适合Shell或者Debug界面进行单项查询。


十、获取ISR Pending Signal

对于需要分析中断与资源交互的场景,可以使用:

unsigned char HRTOS_DEBUG_Resource_GetPendingSignal(
unsigned char id)

例如:

unsigned char pending;

pending =
HRTOS_DEBUG_Resource_GetPendingSignal(1);

通过该值可以观察Resource当前是否存在来自ISR的待处理信号。

这样就能够进一步分析:

外部事件


ISR


Resource


Pending Signal


任务处理

对于实时系统中的中断—任务协作分析,这类信息具有实际意义。


十一、一次获取全部8个Resource

如果Debug界面需要显示完整的Resource状态,可以使用:

unsigned char HRTOS_DEBUG_Resource_GetAll(
HRTOS_DEBUG_RESOURCE_INFO xdata *info)

该函数一次性读取全部8个Resource。

核心代码:

for (i = 0; i < HRTOS_DEBUG_RESOURCE_MAX; i++)
{
info[i].id =
i;

info[i].value =
OS_RES[i].value;

info[i].owner =
OS_RES[i].owner;

info[i].wait_cnt =
OS_RES[i].wait_cnt;

info[i].wait_mask =
OS_RES[i].wait_mask;

info[i].pending_signal =
OS_RES[i].pending_signal;
}

调用后,输出数组就保存了完整的Resource状态。

可以进一步用于:

Shell
Debug Monitor
串口输出
系统状态分析
故障定位


十二、为什么采用“只读”设计

Resource Debug模块有一个非常重要的原则:

Debug模块只观察系统,不干预系统。

也就是说,Debug层不会修改:

OS_RES[]

中的任何内核状态。

它只执行:

读取

复制

分析

显示

而不是:

读取

修改

影响调度

对于实时操作系统来说,这一点非常重要。

Debug功能本身的存在,不应该改变被调试系统的资源状态。

因此,HRTOS Debug与HRTOS内核之间可以保持比较清晰的边界:

┌─────────────────────────┐
│ HRTOS Kernel │
│ │
│ Scheduler / Resource │
│ Task / ISR / IPC │
└────────────┬────────────┘

Read Only


┌─────────────────────────┐
│ HRTOS Debug │
│ │
│ Resource Monitor │
│ Task Monitor │
│ CPU Usage │
│ Stack Monitor │
└─────────────────────────┘


十三、Resource Debug可以解决什么问题

假设某个任务长期处于等待状态。

仅仅查看任务状态:

Task 5 : WAIT

信息是不完整的。

进一步查看Resource:

Resource 2

Value : …
Owner : Task 3
Wait Count : 4
Wait Mask : …
Pending Signal : …

就能够进一步判断:

Task 5


正在等待 Resource 2

├── 当前Owner = Task 3
├── 还有其他任务等待
└── 是否存在Pending Signal

这样,Debug就从“查看任务状态”进一步进入了:

分析任务为什么处于当前状态。

这也是系统级Debug工具的重要价值。


十四、Resource与任务监控结合

如果进一步把Resource Monitor与Task Monitor结合起来,可以形成更加完整的分析链。

例如:

Task Monitor


发现 Task 5 WAIT


Resource Monitor


找到 Resource 2

├── Owner
├── Wait Count
├── Wait Mask
└── Pending Signal


进一步分析阻塞原因

再结合CPU Usage:

CPU Usage


系统负载异常


Task Monitor


Resource Monitor


定位任务与资源关系

这样Debug功能就形成了从:

系统

任务

资源

逐层深入的分析能力。


十五、完整核心代码

Resource Debug模块完整实现如下:

#include "HRTOS_Debug.h"

#define HRTOS_DEBUG_RESOURCE_MAX 8
#define HRTOS_DEBUG_INVALID_ID 0xFF

extern volatile OS_RESOURCE xdata OS_RES[
HRTOS_DEBUG_RESOURCE_MAX];

unsigned char HRTOS_DEBUG_Resource_Get(
unsigned char id,
HRTOS_DEBUG_RESOURCE_INFO xdata *info)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 1;
}

if (info == 0)
{
return 2;
}

info->id =
id;

info->value =
OS_RES[id].value;

info->owner =
OS_RES[id].owner;

info->wait_cnt =
OS_RES[id].wait_cnt;

info->wait_mask =
OS_RES[id].wait_mask;

info->pending_signal =
OS_RES[id].pending_signal;

return 0;
}

unsigned char HRTOS_DEBUG_Resource_GetWaitCount(
unsigned char id)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 0;
}

return OS_RES[id].wait_cnt;
}

unsigned int HRTOS_DEBUG_Resource_GetWaitMask(
unsigned char id)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 0;
}

return OS_RES[id].wait_mask;
}

unsigned char HRTOS_DEBUG_Resource_GetOwner(
unsigned char id)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return HRTOS_DEBUG_INVALID_ID;
}

return OS_RES[id].owner;
}

unsigned char HRTOS_DEBUG_Resource_GetValue(
unsigned char id)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 0;
}

return OS_RES[id].value;
}

unsigned char HRTOS_DEBUG_Resource_GetPendingSignal(
unsigned char id)
{
if (id >= HRTOS_DEBUG_RESOURCE_MAX)
{
return 0;
}

return OS_RES[id].pending_signal;
}

unsigned char HRTOS_DEBUG_Resource_GetAll(
HRTOS_DEBUG_RESOURCE_INFO xdata *info)
{
unsigned char i;

if (info == 0)
{
return 1;
}

for (i = 0; i < HRTOS_DEBUG_RESOURCE_MAX; i++)
{
info[i].id =
i;

info[i].value =
OS_RES[i].value;

info[i].owner =
OS_RES[i].owner;

info[i].wait_cnt =
OS_RES[i].wait_cnt;

info[i].wait_mask =
OS_RES[i].wait_mask;

info[i].pending_signal =
OS_RES[i].pending_signal;
}

return 0;
}


十六、总结

HRTOS Debug Resource模块通过统一的Resource对象,对HRTOS内部资源运行状态进行集中监控。

目前可以获取:

Resource Value
Resource Owner
Wait Count
Wait Mask
Pending Signal

其中:

Wait Count

用于了解当前有多少任务等待资源;

Wait Mask

用于进一步确定具体哪些任务正在等待;

Owner

用于分析资源当前拥有者;

Pending Signal

用于观察ISR与Resource之间的信号状态。

整个模块遵循:

只读内核状态,不修改内核数据。

因此它可以作为HRTOS Debug体系中的一个独立观察层,为任务状态分析、资源等待分析以及中断—任务协作分析提供基础数据。

对于资源有限的8051实时系统而言,Debug并不一定需要复杂的调试器接口。

能够直接看到:

任务在做什么
资源在做什么
谁在等待
谁拥有资源
系统有多忙

就已经能够解决相当一部分实际开发中的定位问题。

这也是HRTOS Debug希望提供的核心能力:

让实时系统内部的运行状态变得可观察、可分析。

赞(0)
未经允许不得转载:网硕互联帮助中心 » HRTOS Debug:8051实时操作系统资源状态监控与分析
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!