嵌入式实时操作系统uC/os-II(十四)-消息邮箱及其操作

2023-05-16

  1. 消息邮箱的定义

       把数据缓冲区的指针赋给事件控制块成员OSEventPtr,同时使事件控制块的成员OSEventType为常数OS_EVENT_TYPE_MBOX,则该事件控制块就叫做消息邮箱。

         消息邮箱的数据结构如图6-1所示。

                      

                                                               图6-1 消息邮箱的数据结构 

消息邮箱的操作

  1. 创建消息邮箱

      创建邮箱调用函数OSMboxCreate()。该函数的原型如下:

         OS_EVENT *OSMboxCreate(

         Void *msg                  //消息指针

         )

 其中,参数msg为消息的指针;函数的返回值为消息邮箱的指针。

         调用函数OSMboxCreate()必须先定义msg的初始值。在一般情况下,这个初始值为NULL,但也可事先定义一个邮箱,然后把这个邮箱的指针作为参数传递给函数OSMboxCreate(),从而使其一开始就指向一个邮箱。

         OS_EVENT  *OSMboxCreate (void *msg)

{

    OS_EVENT  *pevent;

#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */

    OS_CPU_SR  cpu_sr = 0;

#endif

 

    if (OSIntNesting > 0) {                                                     /* See if called from ISR ...  */

        return ((OS_EVENT *)0);                /* ... can't CREATE from an ISR  */

    }

    OS_ENTER_CRITICAL();

    pevent = OSEventFreeList;            /* Get next free event control block */

    if (OSEventFreeList != (OS_EVENT *)0) {  /* See if pool of free ECB pool was empty */

        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;

    }

    OS_EXIT_CRITICAL();

    if (pevent != (OS_EVENT *)0) {

        pevent->OSEventType    = OS_EVENT_TYPE_MBOX;

        pevent->OSEventCnt     = 0;

        pevent->OSEventPtr     = msg;  /* Deposit message in event control block */

#if OS_EVENT_NAME_SIZE > 1

        pevent->OSEventName[0] = '?';

        pevent->OSEventName[1] = OS_ASCII_NUL;

#endif

        OS_EventWaitListInit(pevent);

    }

    return (pevent);                /* Return pointer to event control block */

}

  1. 向消息邮箱发送消息

任务可通过调用函数OSMboxPost()向消息邮箱发送消息。该函数的原型如下:

INT8U OSMboxPost(

         OS_EVENT *pevent,

         void           *msg                          //消息指针

)

其中,第二个参数msg为缓冲区的指针;函数返回值为错误号。

uC/OS-IIuC/OS的基础上又增加了一个向邮箱发送消息的函数OSMboxPostPot(),该函数可以广播的方式向事件等待任务表中的所有任务发送消息。该函数的原型如下:

INT8U       OSMboxPostOpt(

         OS_EVENT        *pevent,

         void                   *msg,

         INT8U                opt                      //广播选项

)

函数中的第三个参数opt用来说明是否把消息向所有等待任务广播。如果该值为OS_POST_OPT_BROADCAST,则意味着把消息向所有等待任务广播;如果为OS_POST_OPT_NONE,则把消息只向优先级别最高的等待任务发送。

  1. 请求消息邮箱

       当一个任务请求邮箱时,需要调用函数OSMboxPend()。该函数的原型如下:

                void  *OSMboxPend(

                                                        OS_EVENT       *pevent,

                                                        INT16U              timeout,            //等待时限

                                                        INT8U                *err          

)

它的作用就是查看邮箱指针OSEventPtr是否为NULL如果不是NULL,则把邮箱中的消息指针返回给调用函数的任务,当函数参数err为OS_NO_ERR时,表示任务获取消息成功;如果邮箱指针OSEventPtr是NULL,则使任务进入等待状态,并引发一次任务调度。

请求邮箱的另一个函数为OSMboxAccept()。该函数的原型如下:

         void          *OSMboxAccept(

         OS_EVENT       *pevent

)

函数OSMboxAccept()OSMboxPend()的区别在于,调用函数OSMboxAccept失败时,任务不进行等待而继续运行。函数OSMboxAccept的返回值为消息指针。

  1. 查询邮箱的状态

     任务可调用OSMboxQuery()查询邮箱当前状态,并把相关信息存储在结构OS_MBOX_DATA中。

         INT8U       OSMboxQuery(

                   OS_EVENT        *pevent,

                   OS_MBOX_DATA      *pdata               //存放邮箱的结构

    )

  OS_MBOX_DATA结构如下:

   typedef   struct {

         void          *msg;

         INT8U       OSEventTbl[OS_EVENT_TBL_SIZE];

         INT8U       OSEventGrp;

   }OS_MBOX_DATA;

  1. 删除邮箱

任务可调用函数OSMboxDel()来删除一个邮箱。该函数的原型如下:

         OS_EVENT        *OSMboxDel(

                   OS_EVENT        *pevent,

                   INT8U                opt,

                   INT8U                *err

)

 

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

嵌入式实时操作系统uC/os-II(十四)-消息邮箱及其操作 的相关文章

随机推荐