首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

uC/OSIII的消息队列处理机制

uC/OSIII的消息队列处理机制

在uC/OSIII中没有邮箱这个概念,而是统一合并到了消息队列MSG_Q。因为消息队列可以看作是很多邮箱的集合,邮箱只是包含单个消息的消息队列。
在分析消息队列之前,必须要对消息的数据结构做一个彻底的分析。
消息队列对象和其他内核对象一样,它的结构定义很简单:
下面看一下消息队列的结构体,记住这个结构体名字叫OS_Q:
struct os_q { /* Message Queue */
    OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_Q */
    CPU_CHAR *NamePtr; /* Pointer to Message Queue Name (NUL terminated ASCII) */
    OS_PEND_LIST PendList; /* List of tasks waiting on message queue */
    OS_MSG_Q MsgQ; /* List of messages */
};
typedef struct os_q OS_Q;
在应用程序中创建消息队列的时候,就是要定义这样的一个结构体变量:
举例创建过程如下:
OS_Q taskq;
void main()
{
    OS_ERR err;
    OSQCreate ((OS_Q *)&p_q,
                          (CPU_CHAR *)"my task Q",
                          (OS_MSG_QTY) 10,
                          (OS_ERR *)&err );
}
这样一个消息队列就创建好了。这里要注意:
OS_Q taskq;这句话应该是全局变量,因为通常都要在其他函数中访问。
有时不注意,很容易依照OSQCreate 的参数创建成这样的队列变量:
OS_Q * taskq;注意这样创建的只是个指针,并没有实体,这样的定义在OSQCreate中参数传入时不会出错,但一运行就会进入hard fault,因为指针跑飞了。
结构体OS_Q的基本信息就是这么多。应当注意的是最后两个成员:
OS_PEND_LIST PendList;
OS_MSG_Q MsgQ;
能看出来,这两个成员又是结构体,一个是OS_PEND_LIST类型,一个是OS_MSG_Q类型。
这两个数据结构是消息队列的核心,只有掌握它们,才能真正了解消息队列的来龙去脉。
首先看一下OS_PEND_LIST,顾名思义,就是所创建的消息队列taskq下面的等待列表。等待者是谁?就是那些调用了OSQPend(&taskq...)的阻塞任务。那这两者之间又是怎么样联系在一起的呢?先告诉你,比较复杂,并不是直接连接在一起的,而是又调用了一个中间结构叫OS_PEND_DATA 。下面先看一下OS_PEND_LIST结构:
struct os_pend_list {
    OS_PEND_DATA *HeadPtr;
    OS_PEND_DATA *TailPtr;
    OS_OBJ_QTY NbrEntries;
};
可见,这个结构又是比较“简单”的:两个指向OS_PEND_DATA的指针,一个指向头,一个指向尾,还有就是计数NbrEntries,记录的是有多少个OS_PEND_DATA。这样的设计是很明显的,典型的一个链表。正是这个链表,将一连串的OS_PEND_DATA链接起来,挂在每个消息队列下边,而每个OS_PEND_DATA里记录的正是等待该消息队列的任务TCB。同时,在该任务TCB中也有指针反向记录着对应的OS_PEND_DATA。下面就仔细看一下OS_PEND_DATA结构,这个分支就到头了,再没有其他结构了:
struct os_pend_data {
    OS_PEND_DATA *PrevPtr;    /*指向链表中的上一个OS_PEND_DATA */
    OS_PEND_DATA *NextPtr;  /*指向链表中的下一个OS_PEND_DATA */
    OS_TCB *TCBPtr;     /*指向等待该队列的任务TCB*/
    OS_PEND_OBJ *PendObjPtr; /*反向指着调用它的内核对象(是队列或者信号量)*/
    /*以下仅供MultiPend时使用*/
OS_PEND_OBJ *RdyObjPtr;
    OS_MSG_SIZE RdyMsgSize;
    CPU_TS RdyTS;
};
继承事业,薪火相传
返回列表