?? os_mbox.c
字號(hào):
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
*err = OS_ERR_EVENT_TYPE;
return (pevent);//如果事件不是郵箱模式
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on mailbox */
//看郵箱中有沒有任務(wù)在等待
tasks_waiting = TRUE; /* Yes */
} else {
tasks_waiting = FALSE; /* No */
}
switch (opt) {
case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */
//沒有任務(wù)等待的情況下才刪除郵箱
if (tasks_waiting == FALSE) {//如果沒有任務(wù)等待
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;//將事件標(biāo)志為沒有用的
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
//將ECB返回給空閑列表
OSEventFreeList = pevent; /* Get next free event control block */
//它指向新的空閑列表
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;//成功刪除
return ((OS_EVENT *)0); /* Mailbox has been deleted */
} else {
OS_EXIT_CRITICAL();
*err = OS_ERR_TASK_WAITING;//如果有任務(wù)在等待
return (pevent);
}
case OS_DEL_ALWAYS: /* Always delete the mailbox */
while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for mailbox */
OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX);
}//所以等待該信號(hào)的任務(wù)都進(jìn)入就緒態(tài),每個(gè)任務(wù)都以為自己得到了
//NULL指針,每個(gè)任務(wù)必須檢查返回的指針,看是不是非NULL,另外,
//當(dāng)每個(gè)任務(wù)都進(jìn)入就緒態(tài),中斷是關(guān)的,也延長(zhǎng)了中斷響應(yīng)時(shí)間。
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
OSEventFreeList = pevent; /* Get next free event control block */
//同上面一樣,將ECB返回給空閑列表,并指向新的表頭
OS_EXIT_CRITICAL();
if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
//只有有任務(wù)等待的時(shí)候才需要任務(wù)調(diào)度
OS_Sched(); /* Find highest priority task ready to run */
}
*err = OS_NO_ERR;
return ((OS_EVENT *)0); /* Mailbox has been deleted */
default:
OS_EXIT_CRITICAL();
*err = OS_ERR_INVALID_OPT;//如果有其它不合理的選項(xiàng)。
return (pevent);
}
}
#endif
/*$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.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
*
* Returns : != (void *)0 is a pointer to the message received
* == (void *)0 if no message was received or,
* if 'pevent' is a NULL pointer or,
* if you didn't pass the proper pointer to the event control block.
等待郵箱中的消息
描述:等待將要送到郵箱中的消息
參數(shù):pevent:指向目標(biāo)郵箱ECB的指針
timeout:超時(shí)階段的選項(xiàng),如果非零,事件將在郵箱中等待消息的到來
直到這個(gè)值的時(shí)間到;如果是零,消息將永遠(yuǎn)等待,直到消息到來。
err:指向?qū)⒁獋鬟f的錯(cuò)誤消息指針。可能如下:
OS_NO_ERR 操作成功,任務(wù)得到消息
* OS_TIMEOUT 規(guī)定時(shí)間內(nèi)沒有收到消息
* OS_ERR_EVENT_TYPE 非法事件類型
* OS_ERR_PEND_ISR 如果在中斷中調(diào)用,結(jié)果將中止
* OS_ERR_PEVENT_NULL 如果pevent 是空指針
*********************************************************************************************************
*/
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
void *msg;
if (OSIntNesting > 0) { /* See if called from ISR ... */
*err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
return ((void *)0);
}//中斷服務(wù)子程序不能等待。
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return ((void *)0);//目標(biāo)郵箱ECB指針為零,不合理
}
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
//事件類型不是郵箱類型
*err = OS_ERR_EVENT_TYPE;
return ((void *)0);
}
#endif
OS_ENTER_CRITICAL();
msg = pevent->OSEventPtr;
if (msg != (void *)0) { /* See if there is already a message */
//如果郵箱中有消息,則從中取出消息,返回給調(diào)用函數(shù),并將NULL存入郵箱,
//同時(shí)返回?zé)o錯(cuò)代碼給它的調(diào)用函數(shù),這個(gè)返回結(jié)果表示,已由另一個(gè)任務(wù)或者中斷
//服務(wù)子程序?qū)⑿畔l(fā)送到郵箱中。如果為空的話,調(diào)用此函數(shù)的任務(wù)將進(jìn)入睡眠狀態(tài)
//等待另一個(gè)任務(wù)(可中斷服務(wù)程序)通過郵箱發(fā)送消息,OSMboxPend()允許定義一個(gè)
//最長(zhǎng)等待時(shí)間作為它的參數(shù),防止任務(wù)無期限等待
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (msg); /* Return the message received (or NULL) */
//返回得到的消息
}
OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */
//消息無效,掛起任務(wù),進(jìn)入睡眠,等待其它郵箱消息喚醒
OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */
//等待時(shí)間也放入任務(wù)控制塊中,該址在OSTimeTick()中被逐次減一
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
//真正將任務(wù)進(jìn)入睡眠,
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next highest priority task ready to run */
//任務(wù)調(diào)度,下一個(gè)優(yōu)先級(jí)的任務(wù)運(yùn)行。
OS_ENTER_CRITICAL();
msg = OSTCBCur->OSTCBMsg;//取出消息
if (msg != (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();
//是否真正接收到消息,如果是,進(jìn)入就緒態(tài),不再等待事件,
*err = OS_NO_ERR;
return (msg); /* Return the message received */
//將收到的消息返回
}
OS_EventTO(pevent); /* Timed out, Make task ready */
//如果超時(shí),讓任務(wù)就緒
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT; /* Indicate that a timeout occured */
return ((void *)0); /* Return a NULL message */
//返回空指針
}
/*$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.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
向郵箱發(fā)送一則消息
描述:向郵箱發(fā)送一則消息
參數(shù):pevent:指向目標(biāo)郵箱的ECB的指針
msg:將要發(fā)送的消息指針,不能發(fā)送空指針
返回:OS_NO_ERR:消息發(fā)送成功
OS_MBOX_FULL :如果郵箱中已經(jīng)有消息了,一次只能發(fā)送一條消息,
在你允許發(fā)送另一條前,消息必須用掉
OS_ERR_EVENT_TYPE:如果你要發(fā)送到的不是郵箱
OS_ERR_PEVENT_NULL:如果目標(biāo)ECB是空指針
OS_ERR_POST_NULL_PTR:如果你想發(fā)空指針
*********************************************************************************************************
*/
#if OS_MBOX_POST_EN > 0
INT8U OSMboxPost (OS_EVENT *pevent, void *msg)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}//合理的目標(biāo)ECB
if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -