//BY 简单的元清 //部分内容引用了其他博主的文章,对这些博主表示感谢,时间关系就不一一指出了。 //如有转载,请说明,谢谢 /* ********************************************************************************************************* * uC/OS-II * The Real-Time Kernel * MESSAGE MAILBOX MANAGEMENT * * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL * All Rights Reserved * * V2.00 * * File : OS_MBOX.C * By : Jean J. Labrosse ********************************************************************************************************* */ #ifndef OS_MASTER_FILE #include "software\includes.h" #endif #if OS_MBOX_EN /* ********************************************************************************************************* * 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 you didn't pass the proper event pointer. ********************************************************************************************************* */ //无等待地从邮箱中得到一个消息 void *OSMboxAccept (OS_EVENT *pevent) reentrant { void *msg; OS_ENTER_CRITICAL(); //进入临界区 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ //检查事件类型是不是邮箱类型 OS_EXIT_CRITICAL(); //如果不是的话直接退出临界区 return ((void *)0); } msg = pevent->OSEventPtr; //把事件的指针指向msg if (msg != (void *)0) { /* See if there is already a message */ pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ //检查收到的消息是不是有效 } OS_EXIT_CRITICAL(); //退出临界区 return (msg); /* Return the message received (or NULL) */ } /*$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 : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the * created mailbox * == (void *)0 if no event control blocks were available ********************************************************************************************************* */ //建立一个邮箱 OS_EVENT *OSMboxCreate (void *msg) reentrant { OS_EVENT *pevent; OS_ENTER_CRITICAL(); //进入临界区 pevent = OSEventFreeList; /* Get next free event control block */ //从事件的空指针上取一个块下来给pevent 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->OSEventPtr = msg; /* Deposit message in event control block */ //事件的信息内容指针指向msg OSEventWaitListInit(pevent); //事件等待列表添加新创建的这个事件 } return (pevent); /* Return pointer to event control block */ //返回创建的邮箱的指针 } /*$PAGE*/ /* ********************************************************************************************************* * PEND ON MAILBOX FOR A MESSAGE * * Description: This function waits for a message to be sent to a mailbox * * Arguments : pevent is a pointer to the event control block associated with the desired mailbox * * timeout is an optional timeout period (in clock ticks). If non-zero, your task will * wait for a message to arrive at the mailbox up to the amount of time * specified by this argument. If you specify 0, however, your task will wait * forever at the specified mailbox or, until a message arrives. * * err is a pointer to where an error message will be deposited. Possible error * messages are: * * OS_NO_ERR The call was successful and your task received a message. * OS_TIMEOUT A message was not received within the specified timeout * OS_ERR_EVENT_TYPE Invalid event type * OS_ERR_PEND_ISR If you called this function from an ISR and the result * would lead to a suspension. * * Returns : != (void *)0 is a pointer to the message received * == (void *)0 if no message was received or you didn't pass the proper pointer to the * event control block. ********************************************************************************************************* */ //等待一个邮箱中的消息 void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant { void *msg; OS_ENTER_CRITICAL(); //进入临界区 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ //检查事件的类型是不是邮箱 OS_EXIT_CRITICAL(); //如果不是直接退出临界区 *err = OS_ERR_EVENT_TYPE; //返回错误码 return ((void *)0); } msg = pevent->OSEventPtr; //把信息指针指向msg if (msg != (void *)0) { /* See if there is already a message */ pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ //如果msg无效 OS_EXIT_CRITICAL(); //退出临界区 *err = OS_NO_ERR; //返回错误码 } else if (OSIntNesting > 0) { /* See if called from ISR ... */ //如果存在中断 OS_EXIT_CRITICAL(); /* ... can't PEND from an ISR */ //退出临界区 *err = OS_ERR_PEND_ISR; //返回错误码 } else { OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ //把事件的类型设置为邮箱 OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ //等待时间设置为超时 OSEventTaskWait(pevent); /* Suspend task until event or timeout occurs */ //一直等待事件直到超时 OS_EXIT_CRITICAL(); //退出临界区 OSSched(); /* Find next highest priority task ready to run */ //进行一次调度 OS_ENTER_CRITICAL(); //在此进入临界区 if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) { /* See if we were given the message */ //判断信息是否有效 OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */ OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; //清除TCB块里面事件的信息、状态设置伟状态状态,事件指针为零 } else if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) { /* If status is not OS_STAT_RDY, timed out */ //如果状态不为OS_STAT_RDY OSEventTO(pevent); /* Make task ready */ //时间到了,直接进入就绪状态 OS_EXIT_CRITICAL(); //退出临界区 msg = (void *)0; /* Set message contents to NULL */ //清空msg *err = OS_TIMEOUT; /* Indicate that a timeout occured */ //返回错误码 } else { msg = pevent->OSEventPtr; /* Message received */ //收到的信息放入msg pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; //事件指针指向空 OS_EXIT_CRITICAL(); //退出临界区 *err = OS_NO_ERR; //返回错误码 } } return (msg); /* Return the message received (or NULL) */ //返回msg的值 } /*$PAGE*/ /* ********************************************************************************************************* * POST MESSAGE TO A MAILBOX * * Description: This function sends a message to a mailbox * * Arguments : pevent is a pointer to the event control block associated with the desired mailbox * * msg is a pointer to the message to send. You MUST NOT send a NULL pointer. * * Returns : OS_NO_ERR The call was successful and the message was sent * OS_MBOX_FULL If the mailbox already contains a message. You can can only send one * message at a time and thus, the message MUST be consumed before you are * allowed to send another one. * OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. ********************************************************************************************************* */ //发送一个消息到邮箱中 INT8U OSMboxPost (OS_EVENT *pevent, void *msg) reentrant { OS_ENTER_CRITICAL(); //退出临界区 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ //如果事件的类型不是邮箱 OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); //退出临界区并返回错误码 } if (pevent->OSEventGrp) { /* See if any task pending on mailbox */ //事件组中是否有事件发生 OSEventTaskRdy(pevent, msg, OS_STAT_MBOX); /* Ready highest priority task waiting on event */ //把任务注册到状态列表 OS_EXIT_CRITICAL(); //退出临界区 OSSched(); /* Find highest priority task ready to run */ //进行一次调度 return (OS_NO_ERR); //返回错误码 } else { if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ //如果邮箱没有信息 OS_EXIT_CRITICAL(); return (OS_MBOX_FULL); //退出临界区并返回错误码 } else { pevent->OSEventPtr = msg; /* Place message in mailbox */ //读取msg信息并放入OSEventPtr指针 OS_EXIT_CRITICAL(); return (OS_NO_ERR); //退出临界区并返回错误码 } } } /*$PAGE*/ /* ********************************************************************************************************* * QUERY A MESSAGE MAILBOX * * Description: This function obtains information about a message mailbox. * * Arguments : pevent is a pointer to the event control block associated with the desired mailbox * * pdata is a pointer to a structure that will contain information about the message * mailbox. * * Returns : OS_NO_ERR The call was successful and the message was sent * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox. ********************************************************************************************************* */ // 查询一个邮箱的状态 INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *ppdata) reentrant { INT8U i; INT8U *psrc; INT8U *pdest; OS_ENTER_CRITICAL(); //进入临界区 if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ OS_EXIT_CRITICAL(); return (OS_ERR_EVENT_TYPE); //如果事件的类型不是邮箱 //直接退出临界区并返回错误码 } ppdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ psrc = &pevent->OSEventTbl[0]; pdest = &ppdata->OSEventTbl[0]; for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { *pdest++ = *psrc++; } ppdata->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */ //把事件的细节复制给一个变量然后返回 OS_EXIT_CRITICAL(); return (OS_NO_ERR); //退出临界区并返回错误码 } #endif
逐字逐句解析ucos ii 源代码-》OS_MBOX.c
猜你喜欢
转载自blog.csdn.net/m19930517/article/details/79240596
今日推荐
周排行