uC/OS-II源码解析(os_mbox.c)

来源:互联网 发布:逆袭网络剧7第一集哇趣 编辑:程序博客网 时间:2024/06/02 13:51
/*** ver   : 2.52** file  : os_mbox.c** brief : 消息邮箱相关函数 C 文件*/#ifndef  OS_MASTER_FILE#include "includes.h"         /* 包含头文件 */#endif#if OS_MBOX_EN > 0/****************************************************************************************                                     无等待的请求消息邮箱** brief     : 该函数用于无等待的请求消息邮箱** pevent    : 指向事件控制块的指针** returns   : != (void *)0  邮箱内消息有效,返回后清空邮箱*             == (void *)0  未得到消息** note      : 该函数的另一个作用是清空消息邮箱******************************************************************************************/#if OS_MBOX_ACCEPT_EN > 0void  *OSMboxAccept (OS_EVENT *pevent){#if OS_CRITICAL_METHOD == 3                        OS_CPU_SR  cpu_sr;#endif        void      *msg;#if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                        /* 无效的事件控制块指 */        return ((void *)0);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {      /* 错误的事件类型      */        return ((void *)0);    }#endif    OS_ENTER_CRITICAL();    msg                = pevent->OSEventPtr;              /* 获取消息     */    pevent->OSEventPtr = (void *)0;                       /* 清空消息     */    OS_EXIT_CRITICAL();    return (msg);                                    }#endif/*$PAGE*//*********************************************************************************************                                        创建消息邮箱** brief   : 该函数用于创建消息邮箱** msg     : 指向消息的指针** Returns : != (OS_EVENT *)0  成功*           == (OS_EVENT *)0  失败*******************************************************************************************/OS_EVENT  *OSMboxCreate (void *msg){#if OS_CRITICAL_METHOD == 3                         OS_CPU_SR  cpu_sr;#endif        OS_EVENT  *pevent;    if (OSIntNesting > 0) {                      /* 不允许中断内创建邮箱 */        return ((OS_EVENT *)0);                    }    OS_ENTER_CRITICAL();    pevent = OSEventFreeList;                    /* 获取事件控制块       */    if (OSEventFreeList != (OS_EVENT *)0) {      /* 调整事件控制块链表  */        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;               /* 消息 */        OS_EventWaitListInit(pevent);    }    return (pevent);                           }/*$PAGE*//*******************************************************************************************                                         删除消息邮箱** brief     : 该函数用于删除消息邮箱** pevent    : 指向事件控制块的指针** opt       : 删除选项:*               opt == OS_DEL_NO_PEND   无任务等待时删除*               opt == OS_DEL_ALWAYS    无条件删除                                           ** err       : 指向错误代码的指针:*               OS_NO_ERR               成功*               OS_ERR_DEL_ISR          不允许中断内删除消息邮箱*               OS_ERR_INVALID_OPT      无效的删除选项*               OS_ERR_TASK_WAITING     有任务正在等待消息邮箱*               OS_ERR_EVENT_TYPE       错误的事件类型*               OS_ERR_PEVENT_NULL      无效的事件控制块指针** Returns    : pevent        删除失败 *              (OS_EVENT *)0 删除成功******************************************************************************************/#if OS_MBOX_DEL_EN > 0OS_EVENT  *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *err){#if OS_CRITICAL_METHOD == 3                                   OS_CPU_SR  cpu_sr;#endif        BOOLEAN    tasks_waiting;    if (OSIntNesting > 0) {                                /* 不能在中断中删除         */        *err = OS_ERR_DEL_ISR;                                     return (pevent);    }#if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                         /* 无效的事件控制块指针     */        *err = OS_ERR_PEVENT_NULL;        return (pevent);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {       /* 错误的事件类型           */        *err = OS_ERR_EVENT_TYPE;        return (pevent);    }#endif    OS_ENTER_CRITICAL();    if (pevent->OSEventGrp != 0x00) {                         tasks_waiting = TRUE;                              /* 有任务等待               */    } else {        tasks_waiting = FALSE;                             /* 无任务等待               */    }    switch (opt) {        case OS_DEL_NO_PEND:                               /* 无任务等待时删除         */             if (tasks_waiting == FALSE) {                 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;                 pevent->OSEventPtr  = OSEventFreeList;    /* 返还事件控制块           */                 OSEventFreeList     = pevent;                              OS_EXIT_CRITICAL();                 *err = OS_NO_ERR;                 return ((OS_EVENT *)0);                                } else {                 OS_EXIT_CRITICAL();                 *err = OS_ERR_TASK_WAITING;                 return (pevent);             }        case OS_DEL_ALWAYS:                                /* 无条件删除               */             while (pevent->OSEventGrp != 0x00) {          /* 就绪所有等待任务         */                 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX);             }             pevent->OSEventType = OS_EVENT_TYPE_UNUSED;             pevent->OSEventPtr  = OSEventFreeList;        /* 返还事件控制块          */             OSEventFreeList     = pevent;                              OS_EXIT_CRITICAL();             if (tasks_waiting == TRUE) {                                   OS_Sched();                               /* 任务调度                */             }             *err = OS_NO_ERR;             return ((OS_EVENT *)0);                               default:             OS_EXIT_CRITICAL();             *err = OS_ERR_INVALID_OPT;             return (pevent);    }}#endif/*$PAGE*//**************************************************************************************                                      请求消息邮箱** brief   : 该函数用来请求消息邮箱** pevent  : 指向事件控制块的指针** timeout : 等待超时.** err     : 指向错误代码的指针,可能取值:**             OS_NO_ERR           成功*             OS_TIMEOUT          超时*             OS_ERR_EVENT_TYPE   错误的事件类型*             OS_ERR_PEND_ISR     不允许在中断中请求*             OS_ERR_PEVENT_NULL  无效的事件控制块指针****************************************************************************************/void  *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err){#if OS_CRITICAL_METHOD == 3                       OS_CPU_SR  cpu_sr;#endif        void      *msg;    if (OSIntNesting > 0) {                           /* 中断内不允许请求消息    */        *err = OS_ERR_PEND_ISR;                                         return ((void *)0);    }#if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                    /* 无效的事件控制块指针    */        *err = OS_ERR_PEVENT_NULL;        return ((void *)0);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {  /* 错误的事件类型          */        *err = OS_ERR_EVENT_TYPE;        return ((void *)0);    }#endif    OS_ENTER_CRITICAL();    msg = pevent->OSEventPtr;    if (msg != (void *)0) {                           /* 邮箱有消息             */        pevent->OSEventPtr = (void *)0;               /* 消息返回,清空邮箱     */        OS_EXIT_CRITICAL();        *err = OS_NO_ERR;        return (msg);                                    }    OSTCBCur->OSTCBStat |= OS_STAT_MBOX;              /* 等待消息       */    OSTCBCur->OSTCBDly   = timeout;                   /* 记录超时       */    OS_EventTaskWait(pevent);                         /* 是任务等待     */    OS_EXIT_CRITICAL();    OS_Sched();                                       /* 任务调度       */    OS_ENTER_CRITICAL();    msg = OSTCBCur->OSTCBMsg;    if (msg != (void *)0) {                           /* 获得消息       */        OSTCBCur->OSTCBMsg      = (void *)0;          /* 清空邮箱       */        OSTCBCur->OSTCBStat     = OS_STAT_RDY;        OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;      /* 取消TCB ECB关联 */        OS_EXIT_CRITICAL();        *err                    = OS_NO_ERR;        return (msg);                                               }    OS_EventTO(pevent);                               /* 超时使任务就绪  */    OS_EXIT_CRITICAL();    *err = OS_TIMEOUT;                                  return ((void *)0);                                 }/*$PAGE*//***************************************************************************************                                       向邮箱发送一则消息** brief    : 该函数用于向消息邮箱发送一则消息** pevent   : 指向事件控制块的指针** msg      : 消息** Returns    : OS_NO_ERR            成功*              OS_MBOX_FULL         邮箱中已经存在消息*              OS_ERR_EVENT_TYPE    错误的事件类型*              OS_ERR_PEVENT_NULL   无效的事件控制块指针*              OS_ERR_POST_NULL_PTR 消息为空***************************************************************************************/#if OS_MBOX_POST_EN > 0INT8U  OSMboxPost (OS_EVENT *pevent, void *msg){#if OS_CRITICAL_METHOD == 3                        OS_CPU_SR  cpu_sr;#endif    #if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                    /* 无效的事件控制块指针 */        return (OS_ERR_PEVENT_NULL);    }    if (msg == (void *)0) {                           /* 发送的消息不能为空  */        return (OS_ERR_POST_NULL_PTR);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {  /* 错误的事件类型       */        return (OS_ERR_EVENT_TYPE);    }#endif    OS_ENTER_CRITICAL();    if (pevent->OSEventGrp != 0x00) {                 /* 是否有任务等待消息        */        OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX);   /* 使最高优先级等待任务就绪  */        OS_EXIT_CRITICAL();        OS_Sched();                                   /* 任务调度  */        return (OS_NO_ERR);    }    if (pevent->OSEventPtr != (void *)0) {            /* 邮箱中不应该已经存在消息  */        OS_EXIT_CRITICAL();        return (OS_MBOX_FULL);    }    pevent->OSEventPtr = msg;                         /* 将消息置邮箱内             */    OS_EXIT_CRITICAL();    return (OS_NO_ERR);}#endif/*$PAGE*//****************************************************************************************                                       向邮箱发送一则消息** brief    : 该函数用于向邮箱发送一则消息** pevent   : 指向事件控制块的指针** msg      : 发送到邮箱的消息指针  ** opt      : 发送选项*              OS_POST_OPT_NONE         消息发送给最高优先级就绪任务*              OS_POST_OPT_BROADCAST    消息发送给所有等待任务** Returns    : OS_NO_ERR            成功*              OS_MBOX_FULL         邮箱满*              OS_ERR_EVENT_TYPE    错误的事件类型.*              OS_ERR_PEVENT_NULL   无效的事件控制块指针*              OS_ERR_POST_NULL_PTR 发送的消息不能为空*******************************************************************************************/#if OS_MBOX_POST_OPT_EN > 0INT8U  OSMboxPostOpt (OS_EVENT *pevent, void *msg, INT8U opt){#if OS_CRITICAL_METHOD == 3                          OS_CPU_SR  cpu_sr;#endif    #if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                    /* 无效的事件控制块指针 */        return (OS_ERR_PEVENT_NULL);    }    if (msg == (void *)0) {                           /* 发送的消息不能为空   */        return (OS_ERR_POST_NULL_PTR);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {  /* 错误的事件类型       */        return (OS_ERR_EVENT_TYPE);    }#endif    OS_ENTER_CRITICAL();    if (pevent->OSEventGrp != 0x00) {                 /* 是否有任务等待消息   */        if ((opt & OS_POST_OPT_BROADCAST) != 0x00) {  /* 是否广播消息         */            while (pevent->OSEventGrp != 0x00) {      /* 就绪所有等待任务     */                           OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX);                }        } else {            OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX);/* 就绪最高优先级等待任务 */        }        OS_EXIT_CRITICAL();        OS_Sched();                                    /* 任务调度     */        return (OS_NO_ERR);    }    if (pevent->OSEventPtr != (void *)0) {            /* 确保邮箱为空  */        OS_EXIT_CRITICAL();        return (OS_MBOX_FULL);    }    pevent->OSEventPtr = msg;                         /* 消息置于邮箱内 */    OS_EXIT_CRITICAL();    return (OS_NO_ERR);}#endif/*$PAGE*//*******************************************************************************************                                        查询邮箱** brief     : 该函数用于查询消息邮箱** pevent    : 指向事件控制块的指针** pdata     : 保存邮箱信息的数据结构指针** Returns   : OS_NO_ERR           成功*             OS_ERR_EVENT_TYPE   错误的事件类型*             OS_ERR_PEVENT_NULL  无效的事件控制块指针******************************************************************************************/#if OS_MBOX_QUERY_EN > 0INT8U  OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *pdata){#if OS_CRITICAL_METHOD == 3                         OS_CPU_SR  cpu_sr;#endif        INT8U     *psrc;    INT8U     *pdest;#if OS_ARG_CHK_EN > 0    if (pevent == (OS_EVENT *)0) {                         /* 无效的事件控制块指针   */        return (OS_ERR_PEVENT_NULL);    }    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {       /* 错误的时间类型         */        return (OS_ERR_EVENT_TYPE);    }#endif    OS_ENTER_CRITICAL();    pdata->OSEventGrp = pevent->OSEventGrp;                /* 复制等待任务链表       */    psrc              = &pevent->OSEventTbl[0];    pdest             = &pdata->OSEventTbl[0];#if OS_EVENT_TBL_SIZE > 0    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 1    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 2    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 3    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 4    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 5    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 6    *pdest++          = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 7    *pdest            = *psrc;#endif    pdata->OSMsg = pevent->OSEventPtr;                     /* 复制邮箱内消息 */    OS_EXIT_CRITICAL();    return (OS_NO_ERR);}#endif                                                                        #endif                                                                  
原创粉丝点击