日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

os_mbox.c(全)

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 os_mbox.c(全) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本篇介紹以下內容:
  • 簡單介紹郵箱機制
  • 從郵箱中接收消息void ?*OSMboxAccept (OS_EVENT *pevent
  • 建立并初始化一個郵箱OS_EVENT ?*OSMboxCreate (void *pmsg)
  • 刪除郵箱OS_EVENT ?*OSMboxDel (OS_EVENT ?*pevent,INT8U ?opt,INT8U ? *perr)
  • 取消等待消息的任務OSMboxPendAbort (OS_EVENT ?*pevent,INT8U ?opt,INT8U ?*perr)
  • 通過消息郵箱向任務發送消息OSMboxPost (OS_EVENT ?*pevent,void ?*pmsg)
  • 通過郵箱向(多)任務發送消息OSMboxPostOpt (OS_EVENT ?*pevent,void *pmsg,INT8U opt)
  • ?取得郵箱中的信息OSMboxQuery (OS_EVENT ?*pevent,?OS_MBOX_DATA ?*p_mbox_data)

郵箱機制簡單介紹一下:

  • 在uc/os-ii中,完成一次兩個任務間的消息傳遞,只需要一個郵箱,并且郵箱中只能存放一個消息。在消息沒有取走前,不能在郵箱中存放新的消息。
  • uc/os-ii中存放和傳遞的是消息內容緩沖區的指針。
  • 在uc/os-ii中,調度系統不能自動通知某個任務郵箱中已經有消息,需要任務主動去取郵件(調用函數OSMboxPend())。
  • 郵箱操作過程:uc/os-ii郵箱通信的過程首先建立一個數據緩沖區,即創建郵箱。一個系統中或者一個任務可以建立多個郵箱。不同郵箱通過郵箱指針來識別,該指針在建立郵箱時產生。郵箱由使用郵箱的任務函數建立,也可在系統初始化函數中建立。郵箱一旦建立,建立后將得到“OS_EVENT”類型的結構指針,任務函數通過該指針可對郵箱進行存取操作。
  • 一個系統中可以存在多個郵箱,對于接收消息的任務函數來說,應該知道從那個郵箱中取消息,郵箱的識別是創建郵箱時“OSMboxCreate()”函數的返回值來得到的?;ハ喟l送和接收消息的2個任務使用同一個全局變量(“OS_EVENT”類型)來標識一個郵箱。
  • 和郵箱相關的數據結構主要是“OS_EVENT”,另外一個結構“OS_MBOX_DATA”在函數中作為局部變量使用。在先收后發的情況下,使用“OS_TCB”的“OSTCBMsg”分量來存儲消息指針。消息郵箱的數據結構為:
  • typedef struct os_mbox_data {void *OSMsg; /* Pointer to message in mailbox指向郵箱中消息的指針 */OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur消息的等待任務列表 */OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur消息的等待任務所在的組 */ } OS_MBOX_DATA; typedef struct os_event {INT8U OSEventType;/* Type of event control block (see OS_EVENT_TYPE_xxxx)事件類型 */void *OSEventPtr;/* Pointer to message or queue structure 指向消息或者隊列結構的指針 */INT16U OSEventCnt;/* Semaphore Count (not used if other EVENT type)*/OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur任務等待列表*/#if OS_EVENT_NAME_EN > 0uINT8U *OSEventName; #endif } OS_EVENT;

    OS_EVENT結構中的OSEventType用來表示事件類型,包括:

    郵箱事件:OS_EVENT_TYPE_MBOX;

    消息列表事件:OS_EVENT_TYPE_Q;

    信號量事件:OS_EVENT_TYPE_SEM;

    對于郵箱通信,我們只需要OS_EVENT中的”OSEventTb1“和”OSEventGrp“還有”OSEventPtr“就可以了。

    7.郵箱的容量:在郵箱創建時,系統并不分配郵箱的大小,郵箱的存儲空間實際上是發信任務定義的。消息傳遞過程中,只傳遞所發消息的指針,函數OSMboxPost()將消息指針傳遞給“OS_EVENT”中的“OSEventPtr”。

    8.注意一點:對于使用消息的任務函數來說,由于是指針傳遞,使用局部變量來儲存發送消息,消息可能會在被收到前消失,所以,最好用全局變量來存儲發送消息。

    ===============================================================

    ===============================================================

    以上關于郵箱機制的介紹很清楚了,下面是uc/os-ii中os_mbox.c的部分代碼(代碼只做簡單的語句注釋,不贅述其他)。

    從郵箱中接收消息void ?*OSMboxAccept (OS_EVENT *pevent):(部分代碼)

    #if OS_MBOX_EN > 0u /* ********************************************************************************************************* * 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. *描述:該功能檢查郵箱看是否有可以獲得的消息。與OSMboxPend()不同的是,如果消息不可獲得,OSMboxAccept()下任務不會被掛起。 * Arguments : pevent is a pointer to the event control block *參數: --pevent:指向事件控制塊的指針 * 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.返回值:!= (void *)0:如果有消息可以獲得,返回該消息。郵箱被清除,當下一次調用OSMboxAccept()時,郵箱狀態為空 ********************************************************************************************************* */ #if OS_MBOX_ACCEPT_EN > 0u void *OSMboxAccept (OS_EVENT *pevent) {void *pmsg;/*指向消息的指針*/ OS_ENTER_CRITICAL();/*進入中斷*/pmsg = pevent->OSEventPtr;pevent->OSEventPtr = (void *)0;/*清空郵箱*/OS_EXIT_CRITICAL();/*退出中斷*/return (pmsg); /* 返回收到的消息或null*/

    建立并初始化一個郵箱OS_EVENT ?*OSMboxCreate (void *pmsg):(部分代碼)

    /*$PAGE*/ /* ********************************************************************************************************* * CREATE A MESSAGE MAILBOX * 建立并初始化一個郵箱 * Description: This function creates a message mailbox if free event control blocks are available. *描述:如果有空閑的事件控制塊,創建一個郵箱。 * Arguments : pmsg 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. *參數: --pmsg:指向你將要存儲在郵箱的消息的指針。如果該指針為空,默認郵箱為空。 * 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 返回值:!= (OS_EVENT *)0:指向與創建的郵箱關聯的事件控制塊的指針。== (OS_EVENT *)0:沒有可用的事件控制塊。 ********************************************************************************************************* */OS_EVENT *OSMboxCreate (void *pmsg) {OS_EVENT *pevent; 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;/*將OS_EVENT結構中的事件類型設置為郵箱事件*/pevent->OSEventCnt = 0u;pevent->OSEventPtr = pmsg; /*將消息存儲在事件控制塊中 */#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";#endifOS_EventWaitListInit(pevent);/*初始化事件等待列表*/}return (pevent);/* 返回指向事件控制塊的指針*/

    刪除郵箱OS_EVENT ?*OSMboxDel (OS_EVENT ?*pevent,INT8U opt,INT8U ?*perr):

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * 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. *參數: --pevent:指向郵箱消息對應的事件控制塊的指針 * 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. * --opt:刪除方式選擇:opt == OS_DEL_NO_PEND:當沒有任務掛起時才能刪除;opt == OS_DEL_ALWAYS:即使有任務等待也將郵箱刪除。這種情況下,所有等待的任務都轉為就緒態。 * perr is a pointer to an error code that can contain one of the following values: * OS_ERR_NONE 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. * --perr:指向錯誤碼的指針:OS_ERR_NONE:成功調用,郵箱被刪除;OS_ERR_DEL_ISR:從中斷服務子程序中刪除郵箱;OS_ERR_INVALID_OPT:無效的選擇方式;OS_ERR_TASK_WAITING:一個或多個任務正在等待;OS_ERR_EVENT_TYPE:沒有指向郵箱的指針;OS_ERR_PEVENT_NULL:pevent為空指針。 * Returns : pevent upon error * (OS_EVENT *)0 if the mailbox was successfully deleted. *返回值:如果成功刪除,返回值為空。如果沒有成功,返回pevent。 * 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.注釋:1)該功能需要小心使用。等待郵箱消息的任務必須先檢查OSMboxPend()函數的返回值。2)調用OSMboxAccept()的任務無法知道要郵箱是否已經被刪除。3)該函數調用會中斷很長時間,時間與等待郵箱的任務的數量相關。4)因為所有掛起的任務都會被轉為就緒態,所以如果郵箱中的消息是互斥型信號量就需要特別注意了,因為此時資源是開放的。 ********************************************************************************************************* */#if OS_MBOX_DEL_EN > 0u OS_EVENT *OSMboxDel (OS_EVENT *pevent,INT8U opt,INT8U *perr) {BOOLEAN tasks_waiting;/*檢測是否有正在等待的任務*/OS_EVENT *pevent_return;/*返回指針*/#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return (pevent);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { *perr = OS_ERR_EVENT_TYPE;return (pevent);}if (OSIntNesting > 0u) { *perr = OS_ERR_DEL_ISR; return (pevent);}OS_ENTER_CRITICAL();/*進入中斷*/if (pevent->OSEventGrp != 0u)/*檢測是否有任務正在等待*/{ tasks_waiting = OS_TRUE; /*有任務等待,將等待標志設置為true*/} else{tasks_waiting = OS_FALSE; /* 沒有任務等待,將等待標志設置為false*/}switch (opt) /*選擇刪除方式并進行相應操作*/{case OS_DEL_NO_PEND: /* 無掛起才刪除*/if (tasks_waiting == OS_FALSE) /*沒有任務等待*/{#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";/*名字設為未命名*/#endifpevent->OSEventType = OS_EVENT_TYPE_UNUSED;/*事件類型設置為未使用類型*/pevent->OSEventPtr = OSEventFreeList; /*將事件控制塊返還給空閑列表*/pevent->OSEventCnt = 0u;OSEventFreeList = pevent;/*更新空閑列表 */OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;pevent_return = (OS_EVENT *)0; /*返回值設為空,郵箱已經被刪除*/}else/*有任務正在等待*/{OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_TASK_WAITING;/*設置錯誤類型*/pevent_return = pevent;/*將事件控制塊指針返回*/}break;case OS_DEL_ALWAYS: /* 無論怎樣都刪除郵箱*/while (pevent->OSEventGrp != 0u) { (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK);/*將所有的任務都設置為就緒態*/}#if OS_EVENT_NAME_EN > 0upevent->OSEventName = (INT8U *)(void *)"?";#endifpevent->OSEventType = OS_EVENT_TYPE_UNUSED;/*事件類型設置為未使用類型*/pevent->OSEventPtr = OSEventFreeList;/* 將事件控制塊返回給空閑列表 */pevent->OSEventCnt = 0u;OSEventFreeList = pevent;/* 更新空閑列表 */OS_EXIT_CRITICAL();/*退出中斷*/if (tasks_waiting == OS_TRUE) /*有任務正在等待*/{ OS_Sched(); /* 找到就緒任務中優先級最高的任務進行調度*/}*perr = OS_ERR_NONE;pevent_return = (OS_EVENT *)0;/*郵箱被刪除,返回空指針*/break;default:/*兩種刪除情況都不是*/OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_INVALID_OPT;/*設置錯誤類型*/pevent_return = pevent;/*將事件控制塊指針返回*/break;}return (pevent_return); } #endif

    等待消息進入郵箱void ?*OSMboxPend (OS_EVENT ?*pevent,INT32U ?timeout,INT8U ?*perr)

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * 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 *參數: --pevent:指向事件控制塊的指針 * 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. * --timeout:時間片。如果不為0,任務將等待消息到來,直到時間到達設定的值。如果設置為0,任務將無限等待,直到有消息到來。 * perr is a pointer to where an error message will be deposited. Possible error * messages are: * OS_ERR_NONE The call was successful and your task received a * message. * OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. * OS_ERR_PEND_ABORT The wait on the mailbox was aborted. * 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 * OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked * --perr:指向錯誤碼的指針:OS_ERR_NONE:成功調用,任務收到消息;OS_ERR_TIMEOUT:在規定時間內沒有收到消息(超時錯);OS_ERR_PEND_ABORT:取消了正在等待的任務;OS_ERR_EVENT_TYPE:無效的事件類型;OS_ERR_PEND_ISR:從中斷服務子程序中調用該函數;OS_ERR_PEVENT_NULL:pevent為空指針;OS_ERR_PEND_LOCKED:調度器上鎖時進行調用。 * 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.返回值:!= (void *)0:指向收到的消息的指針;== (void *)0:沒有收到消息或者pevnet為空指針或者沒有指向事件控制塊的指針時返回空。 ********************************************************************************************************* */ /*$PAGE*/ void *OSMboxPend (OS_EVENT *pevent,INT32U timeout,INT8U *perr) {void *pmsg;/*指向消息的指針*/ #if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u; #endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();} #endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return ((void *)0);} #endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { *perr = OS_ERR_EVENT_TYPE;return ((void *)0);}if (OSIntNesting > 0u) { *perr = OS_ERR_PEND_ISR; return ((void *)0);}if (OSLockNesting > 0u) { *perr = OS_ERR_PEND_LOCKED; return ((void *)0);}OS_ENTER_CRITICAL();/*進入中斷*/pmsg = pevent->OSEventPtr;/*指向消息*/if (pmsg != (void *)0)/*如果有消息存在*/{ pevent->OSEventPtr = (void *)0; /* 清除郵箱 */OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;return (pmsg); /*返回消息*/}/*如果沒有消息*/OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /*將任務掛起*/OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;OSTCBCur->OSTCBDly = timeout;/*最長等待時間=timeout,遞減式*/OS_EventTaskWait(pevent); /* 將任務掛起,直到有消息到來或者時間到*/OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /*選擇優先級高的任務進行調度*/OS_ENTER_CRITICAL();/*進入中斷*/switch (OSTCBCur->OSTCBStatPend) /*檢查掛起狀態原因,是超時還是任務被取消*/{ case OS_STAT_PEND_OK:/*無超時,也沒被取消,正常的等待消息*/pmsg = OSTCBCur->OSTCBMsg;/*返回消息*/*perr = OS_ERR_NONE;break;case OS_STAT_PEND_ABORT:/*被取消*/pmsg = (void *)0;/*返回空*/*perr = OS_ERR_PEND_ABORT; break;case OS_STAT_PEND_TO:/*超時*/default:/*其他情況*/OS_EventTaskRemove(OSTCBCur, pevent);/*將任務移除*/pmsg = (void *)0;/*返回空*/*perr = OS_ERR_TIMEOUT;break;}OSTCBCur->OSTCBStat = OS_STAT_RDY; /* 將當前任務狀態設置為就緒態*/OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /*清除掛起狀態*/OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /*清除事件指針*/#if (OS_EVENT_MULTI_EN > 0u)OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;#endifOSTCBCur->OSTCBMsg = (void *)0;/*清除收到的消息*/OS_EXIT_CRITICAL();/*退出中斷*/return (pmsg);/*返回收到的消息*/ }

    取消等待消息的任務OSMboxPendAbort (OS_EVENT ?*pevent,INT8U ? opt,INT8U ?*perr):

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * ABORT WAITING ON A MESSAGE MAILBOX * 取消等待消息的任務 * Description: This function aborts & readies any tasks currently waiting on a mailbox. This function * should be used to fault-abort the wait on the mailbox, rather than to normally signal * the mailbox via OSMboxPost() or OSMboxPostOpt(). *描述:該函數將正在等待郵箱消息的任務取消。該函數不需要通過OSMboxPost()或者OSMboxPostOpt()函數來通知郵箱進行刪除, 是默認取消。 * Arguments : pevent is a pointer to the event control block associated with the desired mailbox. *參數:--pevent:指向事件控制塊的指針。 * opt determines the type of ABORT performed: * OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the * mailbox * OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the * mailbox * --opt:取消方式:OS_PEND_OPT_NONE:取消一個;OS_PEND_OPT_BROADCAST:全部取消; * perr is a pointer to where an error message will be deposited. Possible error * messages are: * OS_ERR_NONE No tasks were waiting on the mailbox. * OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied * and informed of the aborted wait; check return value * for the number of tasks whose wait on the mailbox * was aborted. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. * --perr:錯誤碼指針:OS_ERR_NONE:沒有任務在等待;OS_ERR_PEND_ABORT:至少一個被通知取消等待的任務是就緒態。OS_ERR_EVENT_TYPE:沒有指向郵箱的指針;OS_ERR_PEVENT_NULL:pevent為空指針。 * Returns : == 0 if no tasks were waiting on the mailbox, or upon error. * > 0 if one or more tasks waiting on the mailbox are now readied and informed.返回值: == 0:沒有任務在等待,返回空;> 0:一個或者多個正在等待郵箱并且已經被通知取消的任務是就緒態。 ********************************************************************************************************* */#if OS_MBOX_PEND_ABORT_EN > 0u INT8U OSMboxPendAbort (OS_EVENT *pevent,INT8U opt,INT8U *perr) {INT8U nbr_tasks;#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0) {OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { *perr = OS_ERR_PEVENT_NULL;return (0u);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { *perr = OS_ERR_EVENT_TYPE;return (0u);}OS_ENTER_CRITICAL();/*進入中斷*/if (pevent->OSEventGrp != 0u) /*有任務正在等待郵箱*/{ nbr_tasks = 0u;switch (opt)/*選擇取消的方式并進行相關操作*/{case OS_PEND_OPT_BROADCAST:/*所有任務都清除*/while (pevent->OSEventGrp != 0u){ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);/*所有任務設為就緒態*/nbr_tasks++;}break;case OS_PEND_OPT_NONE:/*只清除一個*/default: /*其他情況 */(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);/*將最高優先級的任務設為就緒態*/nbr_tasks++;break;}OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /*對最高優先級任務進行任務調度*/*perr = OS_ERR_PEND_ABORT;return (nbr_tasks);}OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_NONE;return (0u);/*沒有任務等待返回空 */ } #endif

    通過消息郵箱向任務發送消息OSMboxPost (OS_EVENT ?*pevent,void ?*pmsg):

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * 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 *參數: --pevent:指向事件控制塊的指針。 * pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. * --pmsg:指向要發送的消息的指針,不可以為空 * Returns : OS_ERR_NONE The call was successful and the message was sent * OS_ERR_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 *返回值:OS_ERR_NONE:成功調用,消息被發出。OS_ERR_MBOX_FULL:郵箱已經包含了消息,一次只能給郵箱放一個消息。在郵箱消息沒有發送出去前不能再往里面放消息了。OS_ERR_EVENT_TYPE:不是給郵箱發消息;OS_ERR_PEVENT_NULL:pevent為空指針OS_ERR_POST_NULL_PTR:發送的是個空消息(空指針) * Note(s) : 1) HPT means Highest Priority Task 注釋:1)HPT表示最高優先級任務。 ********************************************************************************************************* */#if OS_MBOX_POST_EN > 0u INT8U OSMboxPost (OS_EVENT *pevent,void *pmsg) {#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}if (pmsg == (void *)0) { return (OS_ERR_POST_NULL_PTR);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();/*進入中斷*/if (pevent->OSEventGrp != 0u) /*如果有任務正在等郵箱*/{ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);/*將所有任務設置為就緒態*/OS_EXIT_CRITICAL();/*退出中斷*/OS_Sched(); /*找到最高優先級任務進行調度*/return (OS_ERR_NONE);}if (pevent->OSEventPtr != (void *)0) /*郵箱不為空,里面已經有消息存在*/{ OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_MBOX_FULL);}pevent->OSEventPtr = pmsg;/* 將消息放在郵箱中 */OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif

    通過郵箱向(多)任務發送消息OSMboxPostOpt (OS_EVENT ?*pevent,void *pmsg,INT8U opt):

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * 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 *參數: --pevent:指向事件控制塊的指針。 * pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. * --pmsg:指向要發送的消息的指針,不可以為空。 * opt determines the type of POST performed: * OS_POST_OPT_NONE POST to a single waiting task * (Identical to OSMboxPost()) * OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox * * OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked * --opt:發送類型:OS_POST_OPT_NONE:只給一個任務發送;OS_POST_OPT_BROADCAST:給所有等待消息的任務都發送OS_POST_OPT_NO_SCHED:調度程序不會被調用 * Returns : OS_ERR_NONE The call was successful and the message was sent * OS_ERR_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 *返回值:OS_ERR_NONE:調用成功,消息被發出OS_ERR_MBOX_FULL:郵箱中已經有消息存在,OS_ERR_EVENT_TYPE:發送對象不是郵箱。OS_ERR_PEVENT_NULL:pevent為空指針OS_ERR_POST_NULL_PTR:消息為空。 * Note(s) : 1) HPT means Highest Priority Task *注釋:1)HPT是最高優先級任務的意思 * Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the * interrupt disable time is proportional to the number of tasks waiting on the mailbox. 警告:如果選擇了給全部等待任務發消息,會中斷很長時間。中斷事件與等待的任務數量有關系。 ********************************************************************************************************* */#if OS_MBOX_POST_OPT_EN > 0u INT8U OSMboxPostOpt (OS_EVENT *pevent,void *pmsg,INT8U opt) {#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}if (pmsg == (void *)0) { return (OS_ERR_POST_NULL_PTR);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();/*進入中斷*/if (pevent->OSEventGrp != 0u)/*看是否有任務正在等待*/{ if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) /*給所有等待任務發消息*/{ while (pevent->OSEventGrp != 0u) { (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);}} else/*給一個等待任務發消息*/{ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);}OS_EXIT_CRITICAL();/*退出中斷*/if ((opt & OS_POST_OPT_NO_SCHED) == 0u) /*看是否需要喚醒調度程序*/{ OS_Sched(); /*選擇優先級最高的任務進行調度*/}return (OS_ERR_NONE);}/*沒有任務正在等待*/if (pevent->OSEventPtr != (void *)0)/*郵箱中有消息存在*/{ OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_MBOX_FULL);}pevent->OSEventPtr = pmsg;/*將消息放在郵箱中*/OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif

    取得消息郵箱的信息?OSMboxQuery (OS_EVENT *pevent,OS_MBOX_DATA ?*p_mbox_data):

    /*$PAGE*/ /*2018/2/21 ********************************************************************************************************* * 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 *參數: --pevent:指向事件控制塊的指針 * p_mbox_data is a pointer to a structure that will contain information about the message * mailbox. * --p_mbox_data:指向p_mbox_data結構體的指針。 * Returns : OS_ERR_NONE The call was successful and the message was sent * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer * OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer 返回值:OS_ERR_NONE:調用成功,消息被發出;OS_ERR_EVENT_TYPE:不是從郵箱中獲得消息;OS_ERR_PEVENT_NULL:pevent為空指針;OS_ERR_PDATA_NULL:p_mbox_data為空指針。 ********************************************************************************************************* */#if OS_MBOX_QUERY_EN > 0u INT8U OSMboxQuery (OS_EVENT *pevent,OS_MBOX_DATA *p_mbox_data) {INT8U i;OS_PRIO *psrc;OS_PRIO *pdest;#if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u;#endif#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0) { return (OS_ERR_PEVENT_NULL);}if (p_mbox_data == (OS_MBOX_DATA *)0) { return (OS_ERR_PDATA_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();/*進入中斷*//*將事件(郵箱)結構中的等待任務列表復制到pdata數據結構中*/p_mbox_data->OSEventGrp = pevent->OSEventGrp;/*等待事件的任務組中的內容傳送到狀態數據結構中*/psrc = &pevent->OSEventTbl[0];/*保存pevent->OSEventTbl[0]對應的地址,源*/pdest = &p_mbox_data->OSEventTbl[0];/*保存pdata->OSEventTbl[0]對應的地址,目的*/for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {*pdest++ = *psrc++;/*地址指針下移一個類型地址,獲取消息郵箱的值*/}p_mbox_data->OSMsg = pevent->OSEventPtr;/*將郵箱中的當前消息從事件數據結構復制到OS_MBOX_DATA數據結構 */OS_EXIT_CRITICAL();/*退出中斷*/return (OS_ERR_NONE); } #endif /* OS_MBOX_QUERY_EN */ #endif /* OS_MBOX_EN */

    文章到這里就結束了。

    uc/os-ii中的os_mbox.c文件全部讀完。重點是了解郵箱機制,還要清楚相關的結構體。看郵箱有沒有消息什么的都是通過事件控制塊中的OSEventGrp等判斷的。具體看代碼即可。



    總結

    以上是生活随笔為你收集整理的os_mbox.c(全)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。