⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_mbox.c

📁 avr ucos 代码 测试环境:source insight WINAVR 4个进程
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                                       MESSAGE MAILBOX MANAGEMENT
*
*                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
*                                           All Rights Reserved
*
* File : OS_MBOX.C
* By   : Jean J. Labrosse
*********************************************************************************************************
*/

#ifndef  OS_MASTER_FILE
#include "includes.h"
#endif

#if OS_MBOX_EN > 0
/*
*********************************************************************************************************
*                                     ACCEPT MESSAGE FROM MAILBOX
*
* Description: This function checks the mailbox to see if a message is available.  Unlike OSMboxPend(),
*              OSMboxAccept() does not suspend the calling task if a message is not available.
*
* Arguments  : pevent        is a pointer to the event control block
*
* Returns    : != (void *)0  is the message in the mailbox if one is available.  The mailbox is cleared
*                            so the next time OSMboxAccept() is called, the mailbox will be empty.
*              == (void *)0  if the mailbox is empty or,
*                            if 'pevent' is a NULL pointer or,
*                            if you didn't pass the proper event pointer.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
                                                    无等待地从邮箱中得到一则消息
描述:此函数检查邮箱中是否有消息,不同于OSMboxPend(),如果没有可行消息,
                OSMboxAccept() 不会挂起调用此函数的任务
参数;:pevent:是指向事件控制块的指针
返回:!= (void *)0 如果邮箱有消息,它指向邮箱中的一则消息,邮箱被清空,
                     如果下一次调用,它将是空的。
                 == (void *)0 如果邮箱为空,或者pevent指向空指针,或者没有传递一个合理事件
                                指针
*********************************************************************************************************
*/


#if OS_MBOX_ACCEPT_EN > 0
void  *OSMboxAccept (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    
    void      *msg;


#if OS_ARG_CHK_EN > 0//允许参数检验
    if (pevent == (OS_EVENT *)0) {                        /* Validate 'pevent'                         */
        return ((void *)0);//如果事件无效,返回零
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {      /* Validate event block type                 */
		//检查pevent所指向的事件控制块是不是由OS_EVENT_TYPE_MBOX建立
        return ((void *)0);
    }
#endif
    OS_ENTER_CRITICAL();
    msg                = pevent->OSEventPtr;//函数得到邮箱的当前内容
    pevent->OSEventPtr = (void *)0;                       /* Clear the mailbox     *///清空邮箱
    OS_EXIT_CRITICAL();
    return (msg);   /* Return the message received (or NULL)     *///将邮箱中的内容返回,以供调用
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                        CREATE A MESSAGE MAILBOX
*
* Description: This function creates a message mailbox if free event control blocks are available.
*
* Arguments  : msg           is a pointer to a message that you wish to deposit in the mailbox.  If
*                            you set this value to the NULL pointer (i.e. (void *)0) then the mailbox
*                            will be considered empty.
*
* Returns    : != (OS_EVENT *)0  is a pointer to the event control clock (OS_EVENT) associated with the
*                                created mailbox
*              == (OS_EVENT *)0  if no event control blocks were available
*********************************************************************************************************
*/
/*
*********************************************************************************************************
                                            建立一个邮箱
描述:如果空余事件控制块允许,就建立一个消息邮箱
参数:msg:指向你想存入邮箱的消息指针,如果存入零,我们认为它为空
返回:!= (OS_EVENT *)0:指向所建立邮箱的事件控制块指针
                 == (OS_EVENT *)0:如果没有可行事件控制块
*********************************************************************************************************
*/



OS_EVENT  *OSMboxCreate (void *msg)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    
    OS_EVENT  *pevent;


    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;//如果ECB可用,则将其设置为邮箱型
        pevent->OSEventCnt  = 0;//信号量,邮箱中不使用它
        pevent->OSEventPtr  = msg;               /* Deposit message in event control block             */
		//保存消息在ECB中
        OS_EventWaitListInit(pevent);//对事件控制块的等待任务列表进行初始化
    }
    return (pevent);                             /* Return pointer to event control block              */
	//返回事件控制块的指针,对邮箱的操作都通过此指针完成。
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         DELETE A MAIBOX
*
* Description: This function deletes a mailbox and readies all tasks pending on the mailbox.
*
* Arguments  : pevent        is a pointer to the event control block associated with the desired
*                            mailbox.
*
*              opt           determines delete options as follows:
*                            opt == OS_DEL_NO_PEND   Delete the mailbox ONLY if no task pending
*                            opt == OS_DEL_ALWAYS    Deletes the mailbox even if tasks are waiting.
*                                                    In this case, all the tasks pending will be readied.
*
*              err           is a pointer to an error code that can contain one of the following values:
*                            OS_NO_ERR               The call was successful and the mailbox was deleted
*                            OS_ERR_DEL_ISR          If you attempted to delete the mailbox from an ISR
*                            OS_ERR_INVALID_OPT      An invalid option was specified
*                            OS_ERR_TASK_WAITING     One or more tasks were waiting on the mailbox
*                            OS_ERR_EVENT_TYPE       If you didn't pass a pointer to a mailbox
*                            OS_ERR_PEVENT_NULL      If 'pevent' is a NULL pointer.
*
* Returns    : pevent        upon error
*              (OS_EVENT *)0 if the mailbox was successfully deleted.
*
* Note(s)    : 1) This function must be used with care.  Tasks that would normally expect the presence of
*                 the mailbox MUST check the return code of OSMboxPend().
*              2) OSMboxAccept() callers will not know that the intended mailbox has been deleted!
*              3) This call can potentially disable interrupts for a long time.  The interrupt disable
*                 time is directly proportional to the number of tasks waiting on the mailbox.
*              4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in
*                 applications where the mailbox is used for mutual exclusion because the resource(s)
*                 will no longer be guarded by the mailbox.
                                             删除一个邮箱
描述:此任务删除一个邮箱,准备好邮箱中挂起的所有任务
参数:pevent:指向想要邮箱的ECB的指针
                 opt:确定删除选项如下:
                 opt == OS_DEL_NO_PEND:如果没有任务挂起就删除邮箱
                 opt == OS_DEL_ALWAYS:即使任务等待也删除邮箱,这种情况下,所有挂起的任务将就绪
                 err:包含以下值的错误代码指针:
                 OS_NO_ERR:调用成功,删除邮箱
                 OS_ERR_DEL_ISR   :如果从ISR中删除邮箱
*               OS_ERR_INVALID_OPT :指定了不合理选项
*               OS_ERR_TASK_WAITING :一个或者几个任务在邮箱中等待
*               OS_ERR_EVENT_TYPE :没有传递指针给邮箱
*               OS_ERR_PEVENT_NULL :pevent是空指针,即邮箱的ECB为空。
返回:pevent:操作错误
                 (OS_EVENT *)0:邮箱成功删除
备注:1、此函数必须小心使用,任务希望在场的邮箱检查OSMboxPend()的返回代码
                2、OSMboxAccept()调用将不知道想要的邮箱已经被删除
                3、这个函数将潜在地关中断一长段时间,关中断时间与在邮箱中等待的任务
                       数成正比
                4、因为所有在邮箱中挂起的任务将就绪,你必须在邮箱相互排斥情况下小心使用
                       因为资源不再被邮箱保护
*********************************************************************************************************
*/


#if OS_MBOX_DEL_EN > 0
OS_EVENT  *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif    
    BOOLEAN    tasks_waiting;//typedef unsigned char BOOLEAN


    if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
        *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
        return (pevent);//如果在中断中调用,不能删除
    }
#if OS_ARG_CHK_EN > 0
    if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
        *err = OS_ERR_PEVENT_NULL;
        return (pevent);//如果pevent不合理
    }
    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {       /* Validate event block type                */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -