嵌入式实时操作系统uC/os-II(十六)-信号量集

2023-05-16

  • 信号量定义

uC/OS-II提供了可处理多个信号量的信号量集。其实意图如图7-1所示。

                             

                                                    图7-1 信号量集的示意图 

从图中可以看到,信号量实质上就是一个多输入、多输出的组合逻辑。其输入为其他任务发出的多个信号,而输出则是多个输入逻辑运算的结果。目前,uC/OS-II信号量集可以对信号量进行(ANDALL)”(ORANY)”两种逻辑运算。 

  • 信号量集的结构

uC/OS-II把信号量集的功能分成了两部分:标志组(输入信号标志组)和等待任务链表。标志组存放了信号量的所有信号,而等待任务链表中的每个节点都对应着一个叫做OS_FLAG_NODE 的结构。

       OS_FLAG_NODE结构实质上就是等待任务控制块。也就是说,uC/OS-II信号量集由   一个标志组和多个等待任务控制块组成。

  1. 信号量标志组

         标志组其主要组成部分就是一个叫做信号列表的二进制数OSFlagFlags。OSFlagFlags其实就是一个位图,其长度可在系统配置文件OS_CFG.H中来制定,系统默认定义为16位。该位图每一位都对应一个信号量,位图的作用就是用来接收并接收保存其他任务所发送来的信号量值,所以它也可看作是输入信号暂存器。

         OSFlagFlags的图形表示如图6-2所示。

                                      

                                                                    图7-2 OSFlagFalgs的位图表示 

信号量集也应该有一个控制块,该控制块以OSFlagFlags作为主要成员。由于OSFlagFlags存放了输入信号量的值。所以uC/OS-II将这个控制块叫做标志组。其定义如下:

                   typedef  struct {

                            INT8U                OSFlagType;                        //识别是否为信号集的标志

                            void                    *OSFlagWaitList;                 //指向等待任务链表的指针

                            OS_FLAG           OSFlagFlags;                     //输入信号量值列表

                   }OS_FLAG_GRP;

从该结构的定义中可见,其中OSFlagType为信号量集标识,其值固定为OS_EVENT_TYPE_FLAG; OSFlagWaitList则是一个void 类型的指针。其有两种用途,其主要作用是指向一个链表,该链表中存放了给信号量集的全部等待任务。综上所述,一个信号量集的标记组结构OS_FLAG_GRP如图6-3所示。

                                

                                                       图7-3 标志组OS_FLAG_GRP的图形表示

  1. 等待任务

信号量集在等待任务的中操作究竟如何?

  1. 在多个信号的输入中挑选等待任务感兴趣的输入
  2. 把挑选出来的输入按照等待任务所希望的逻辑来运算,以得出输出

     于是,为了处理第一个问题,uC/OS-II定义了长度与输入标志列表OSFlagFlags相等的OSFlagNodeFlags,目的就是要用后者作为过滤器从输入标志列表筛选出等待任务感兴趣的输入

     为了出来第二问题,uC/OS-II又定义了一个OSFlagNodeWaitType变量来指定对选出来的信号的逻辑运算。OSFlagNodeWaitType的可选值及其意义见表7-1

                                                            表7-1 OSFlagNodeWaitType的可选值及其含义

                                         

      OSFlagFlagsOSFlagNodeFlagsOSFlagNodeWaitType三者之间的关系如图7-4所示。

                                          

                                                  图7-4 标志组与等待任务共同完成信号量集的逻辑运算及控制 

综上所述,为了描述信号量集的等待任务,uC/OS-II在上面所介绍OSFlagNodeFlagsOSFlagNodeWaitType两个数据基础上,又增加了一些其他辅助数据,从而形成数据结构OS_FLAG_NODE。其结构定义如下:

 typedef  struct{

                            void          *OSFlagNodeNext;           //指向下一个节点的数据

                            void          *OSFlagNodePrev; //指向前一个节点的数据

                            void          *OSFlagNodeTCB;             //指向对应等待任务的控制块的指针

                            void          *OSFlagNodeFlagGrp;      //反向指向信号量集的指针

                   OS_FLAGS       OSFlagNodeFlags;             //信号过滤器

                   INT8U                OSFlagNodeWaitType;     //定义逻辑运算关系的数据

}OS_FLAG_NODE;

由于关联了任务控制块,所以该结构也可看作信号量集等待任务控制块。OS_FLAG_NODE结构的图形如图7-5所示。

                                 

                                                    图7-5 信号量集等待任务的图形表示

  1. 等待任务链表

信号量集用一个双向链表来组织等待任务,每一个等待任务都是该链表中的一个节点(Node)。标志组OS_FLAG_GRP的成员OSFlagWaitList就指向了信号量集的这个等待任务链表。等待任务链表与标志组组成的整个信号量集示意图如图7-6所示。

                               

                                                                           7-6信号量集结构图

  1. 对任务等待链表的操作

         uC/OS-II定义了两个对等待任务链表的基本操作—添加节点和删除节点,以供对信号量集操作的函数调用。

  1. 添加节点

      给等待任务链表添加节点的函数为OS_FlagBlock()。该函数的原型如下:

      static void OS_FlagBlock(

                            OS_FLAG_GRP          *pgrp,                         //信号量集指针

                            OS_FLAG_NODE       *pnode,                      //待添加的等待任务节点指针

                            OS_FLAGS                  flags,                           //指定等待信号的数据

                            INT8U                         wait_typde,                        //信号与等待任务之间的逻辑

                            INT16U                       timeout;,                             //等待时限

                   )

       这个函数将在请求信号量集函数OSFlagPend()中被调用。

  1. 删除节点

         从等待任务链表中删除一个节点的函数为OS_FlagUnLink()。该函数的原型如下:

         void OS_FlagUnLink(OS_FLAG_NODE     *pnode);

         这个函数将在发送信号量集函数OSFlagPost().

  1. 空标志组链表

         uC/OS-II初始化时,系统会根据在文件OS_CFG.H中定义的常数OS_MAX_FLAGS创建OS_MAX_FLAGS个标志组,并借用成员OSFlagWaitList作为指针把这些标志组链接成一个单向链表。由于这个链表中的各个标志组还未被真正创建,因此这个链表叫做空标志组链表。

         空标志组链表的头指针存放在系统全局变量OSFlagList中,每当应用程序创建一个信号量集时就从这个链表中取一个标志组,并移动头指针OSFlaList,使之指向下一个空标志组。

         空标志组链表的结构如图7-7所示。

                                            

 

                                                                        图7-7 空信号量集标志组链表

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式实时操作系统uC/os-II(十六)-信号量集 的相关文章

随机推荐