菜鸟学uC/OS_II(3)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
By <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Norman
2008-7-10
事件标志组
事件标志组包括几个数据结构,用来保存当前事件组中各事件状态的一些标志位和等待这些事件标志的任务列表——这里的任务列表不同于其他任务等待列表不同,是一个双向列表。
疑惑一:事件标志组是如何被事件所影响的,也就是如何置位、清零的?
疑惑二:OS_EVENT_TYPE_FLAG仅仅用于指明这个数据结构是一个事件标志组吗?
疑惑三:事件标志组和事件标志结点的关系?
疑惑四:任务和结点、事件标志组的关系?
疑惑五:取出的状态和预期的状态的关系?
疑惑六:OSFlagPend()中flags指定对应事件标志位,所谓的指定是什么意思?难道是只取指定位?
疑惑七:创建事件标志组如何指定哪些事件?或者说是事件标志组内容(事件)是如何在创建时确定的?我怎么知道事件标志组里面确定有哪些事件要发生?
看起来,等待任务是通过事件标志结点跟事件标志组发生的联系,那么,有多少个等待任务,就需要有多少个事件标志结点。那么事件标志组是一个根据事件的发生而改变其值的数据结构,而事件标志结点则是一个根据任务需要而建立的判断标准。!?
创建事件标志组:OSFlagCreate()创建事件标志组很简单,就是从空闲事件标志组列表中得到所使用的数据结构空间,然后初始化结构成员;其中,传入的flags参数用来初始化OSFlagFlags,(这里,邵老师的书上说的是OSFlagNodeFlags,应该是不对的)这个成员保存事件标志组的值。通常初始化“全0”或“全1”。
事件标志数据结构OS_FLAG_NODE是由OSFlagPend()函数建立的,也就是说,当任务开始等待某些事件标志位的时候,就建立了这个数据结构。换句话说,当调用OSFlagPend()的时候,建立OS_FLAG_NODE。而当这些等待的事件标志发生的时候,这个数据结构就被删除了(这里要注意,如果想要在调用之后重新置起或是清除相应的标志位,可以在wait_type参数上加上OS_FLAG_CONSUME这个值就可以了)。
在事件标志函数OSFlagPost()中是这样处理的:函数OSFlagPost()根据参数flags来改变(置位或清零)事件标志组的值,然后会判断等待任务列表是否为空,如果非空,那么函数会遍历所有OS_FLAG_NODE以检查新设定的事件标志是否满足某个任务所期待的条件。如果在遍历之后发现有任务满足事件标志条件,那么会进行一次总的调度,让高优先级任务运行。
任务同结点其实有点包含关系,结点OS_FLAG_NODE数据结构由OSFlagPend()在任务堆栈中创建,并经由OS_FLAG_NODE与事件标志组发生关系。当删除时,它是自动消失的,堆栈空间自动释放,成为可用堆栈空间。
自己读了一遍邵老师的书之后,感觉各个部分的概念还是比较清晰的,不过,它们之间的联系好像就不太明白了,就像我在前面提出的疑惑一样,有些地方不知道互相有什么影响,互相是怎样调用、传递信息等等。例如,我就不太明白创建事件标志组的时候,怎么去设定有多少个事件,各个事件对应的是事件标志组中的哪个位?如果这个没有设定好,那么OSFlagPost()函数如何知道将事件标志组哪一位置位或者清零?
读了“浅析μCOS/II v2.85内核OSFlagPend()和OSFlagPost()函数工作原理”这篇网文之后,基本证实了我自己的一些理解,我认为作者用“登记”一词来说明OSFlagPost()的行为很形象,也比较容易懂。但是作者没有提到我所提出的那个问题:事件是如何对应的?
难道是我没有理解清楚这个概念?我好像把事件和事件标志搞在一起了(??),其实他们之间是没有关系的?事件标志组根本就是认为设置的一种类似“握手”的一种方式,而非像事件一样?可以将其看作类似事件一样的服务,而并不是包含在事件中的?
按照这种思路,我做以下思考:创建的时候,我们初始化一个8位或者16位等等的一个事件标志组,而在任务中调用OSFlagPend()函数给出我们等待的条件——也就是需要哪些位置位——至于哪些位,是开发人员自己设计的,与内核无关(??),而其他任务可以通过调用OSFlagPost()函数来对事件标志组进行置位/清零,每次置位/清零一位,直到所满足的事件标志位置位/清零(当然这要视等待方式而定)。这套设定是自由的,但是也仿佛遵循了一些规律:我们可以设定事件标志组与多少个任务关联,所发生的时间其实就是任务在事件标志组上进行“登记”,每个任务规定只能登记某一位或者某些位,这样,就可以实现等待多个事件,或者可以说,多个任务完成后,再运行某个任务的目的了(这个思路只是我的一个理解,没有经过专家证实,希望有人帮忙解惑,不胜感激)。
(待续)
文章评论(0条评论)
登录后参与讨论