在前面介绍rt-thread内核对象时(http://blog.csdn.net/flydream0?viewmode=contents),有介绍到rt-thread内核对象成员flag,但是没有怎么具体介绍他的含意,只是把它当做普通标志来理解,这里特意将此flag提出来总结一下,这也是这篇博文的目的.
首先,内核对象的flag确实是一标志,且是8个位的数据,按位来定义的,那么它到底各个位是怎么定义的呢?答案是用在不同的内核对象时,它的各位定义会有所不同.
从前面的博文中我们可以知道,rt-thread的内核对象有定时器,线程,信号量,互斥锁,事件,邮箱,消息队列,内存堆,设备,模块,这些内核对象都继承了内核对象的成员,其中也就包含了内核对象的flag成员,因此,内核对象成员flag在这些不同的场合是具体不同的含义的,下面总结一下:
object.flag在定时器中的各位如下定义:
位 | 0 | 1 | 备注 |
bit0 | RT_TIMER_FLAG_DEACTIVATED:定时器未激活,即初始化值 | RT_TIMER_FLAG_ACTIVATED:定时器激活,当定时器start后将会置为此状态 | 激活/非激活状态 |
bit1 | RT_TIMER_FLAG_ONE_SHOT:单次定时器.即定时器时间一到自动失效 | RT_TIMER_FLAG_PERIODIC:周期定时器.即时间一到,自动时行下一次定时. | 单次定时器/周期定时器 |
bit2 | RT_TIMER_FLAG_HARD_TIMER:硬时钟.即采用硬件时钟. | RT_TIMER_FLAG_SOFT_TIMER:软件时钟.即采用软件时钟. | 硬件时钟/软件时钟标志 |
线程虽然也继承了内核对象,但是它的数据定义并未直接包含内核对象结构体变量成员,而是直接在线程控制块中包含其成员,如下:
struct rt_thread { /* rt object */ char name[RT_NAME_MAX]; /**< the name of thread */ rt_uint8_t type; /**< type of object */ rt_uint8_t flags; /**< thread's flags */ #ifdef RT_USING_MODULE void *module_id; /**< id of application module */ #endif rt_list_t list; /**< the object list */ rt_list_t tlist; /**< the thread list */ /* stack point and entry */ void *sp; /**< stack point */ void *entry; /**< entry */ void *parameter; /**< parameter */ void *stack_addr; /**< stack address */ rt_uint16_t stack_size; /**< stack size */ //...由以上线程控制块定义可知,从开始到list成员都是保持与内核对象一致,至于为什么会是这样,估计是RTT作者应该是很早之前就写好了线程相关的代码,所以一直沿续至今.注意,在线程控制块中是flags,多了一个s,但这并不妨碍它继承自内核对象控制块的特点,但是这个内核对象的flags对于线程,在内核中似乎并没有多大的作用,从线程的初始化接口函数中可以看出并没有使用这个flags参数,也没有从外部实参传进来,似乎RTT作者将它遗忘了,或是暂时还没有想好在线程中如何使用这个参数.
RTT在IPC对象在信号量,互斥锁,事件,邮件,消息队列这五类这里我们统称为IPC内核对象.object.flag在这些IPC内核对象中,只有bit0有定义,如下:
位 | 0 | 1 | 备注 |
bit0 | RT_IPC_FLAG_FIFO:按消息队列先进先出的方式处理. | RT_IPC_FLAG_PRIO:按线程优先级的方式处理,即哪个线程的优先级高,则哪个先操作. | IPC处理方式 |
object.flag在设备,内存堆和内存池中都没有被用到.
object.flag在模块中有用到,bit0被用作带entry point与否标志,之前还没有介绍到RTT模块的内容,这里也就不介绍了,后续我将在专门介绍RTT模块的博文中介绍,敬请关注!
完!