嵌入式操作系统原理及应用
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.3 结构体

C语言的结构体是不同数据类型数据的集合。它占用连续内存空间,适合描述具有结构的事物(如数据库的记录)。它不需要分类存放,检索速度快且恒定。

在C语言中,结构地址和结构中第一个元素的地址是相同的,因此在µLinux内核中经常出现使用结构第一个元素的地址来表示结构地址的情况,在读代码时要注意这一点。

例如:

struct my_struct{
int a;
int b;
}c;
if(&c==&c.a){ // always true
...
}

上面的c 和c.a的地址是一样的,所以判断语句是永真的。

µCOS中的结构体如任务控制块(os_tcb):

typedef struct os_tcb{
    OS_STK *OSTCBStkPtr; /*指向当前栈顶*/
#if OS_TASK_CREATE_EXT_EN>0
    void *OSTCBExtPtr; /* 指向用户定义的TCB扩展数据*/
    OS_STK *OSTCBStkBottom;/* 指向栈底*/
    INT32U OSTCBstkSize; /* 堆栈大小*/
    INT32U OSTCBOpt; /* OSTaskCreateExt传递的堆栈参数*/
    INT32U OSTCBstkId; /* 堆栈标识(0-65535)*/
#endif
    struct os_tcb *OSTCBNext;  //下一个任务控制块
    struct os_tcb *OSTCBPrev;  //上一个任务控制块,这两个参数将任务控制
//块连成一个双向链表,在时钟节拍函数OSTimeTick()里会用到
#if (OS_Q_EN && (OS_MAX_QS >=2)) || OS_MBOX_EN || OS_SEM_EN
    OS_EVENT  *OSTCBEventPtr; //事件指针
#endif
#if (OS_Q_EN && (OS_MAX_QS >=2)) || OS_MBOX_EN
    void   *OSTCBMsg;   //事件消息
#endif
    INT16U OSTCBDly;    //任务延时节拍
    INT8U OSTCBStat; //任务状态,当它等于OS_STAT_READY时,任务进入就绪态
    INT8U OSTCBPrio;   //任务优先级
    INT8U OSTCBX;  //任务优先级的低三位,例如任务的优先级为25,换成2//进制后,则OSTCBX=1

INT8U OSTCBY; //任务优先级的高三位 INT8U OSTCBBitX; //优先级表快查用 INT8U OSTCBBitY; //优先级组对应的位数

#if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq; // #endif } OS_TCB;

struct 是结构定义的关键字,struct后面的os_tcb是结构体的名字。后面大括号内部的定义就是对成员变量的定义。一般来说结构体的成员个数是一定的,成员类型可以各不相同。

上述结构体代码中包含的第一个成员变量是OS_STK指针类型的 *OSTCBStkPtr,指向当前的任务堆栈。#if…#endif 是宏定义段,是为了增强系统的扩展性,也就是一种可以变成员个数的结构的方法。用结构体和上述的指针结合可以完成一些更加复杂的嵌入式操作系统数据结构,包括链表、树等。