【原创】ucos信号量的操作及原理
生活随笔
收集整理的這篇文章主要介紹了
【原创】ucos信号量的操作及原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
信號量的操作及原理
? 1.OSSemCreate創建信號量semaphore ? ? 在使用信號量之前,要先用OSSemCreate創建一個信號量,并通過返回的合法事件結構體指針使用信號量。? ??OS_NO_ERR ? ? ? ? ??? ??? ??? ??函數調用成功,獲得了信號量。 ? ??OS_TIMEOUT ? ? ? ??? ??? ??? ??在規定的時間內沒有申請到信號量 ? ??OS_ERR_EVENT_TYPE ??? ??事件類型錯誤,不是信號量 ? ??OS_ERR_PEND_ISR ? ?? ??? ??不能在中斷內申請信號量 ? ??OS_ERR_PEVENT_NULL? ??pevent指針無效 ? 下面講解一下函數內部原理: ? ? 如果信號量的計數器值大于0,則將其減1,表示又有一個任務占用,并直接返回。 ? ? 如果信號量的計數器值為0,表示信號量已被其他任務占用,此時任務控制塊中的狀態標志是等待信號狀態以及就緒的,因為使用的是按位或操作,保留了原有的就緒狀態標志。
? ? 之后調用了OS_EventTaskWait(pevent); 此時作了3件事:
? ? (1)OSTCBCur->OSTCBEventPtr = pevent;將事件控制塊指針保存于任務控制塊中
? ? (2)去除任務在任務就緒表的就緒狀態,注意沒有包括任務控制塊中的狀態標志 ? ? (3)設置事件控制塊中的任務等待表
? ? 至此任務被掛起!通過OS_Sched運行其他任務去了。
? ? 接下來的結果取決于,信號量是否在規定的等待時間內被釋放。
? ? 在當前任務被掛起,而運行其他任務的同時,每個時鐘節拍都會運行OSTimeTick中斷函數,此函數會遍歷所有任務,如果任務控制塊中的狀態標志為就緒的,且Dly等待值不為0,則將Dly減1,如果減1后剛好為0,則在任務就緒表中恢復該任務的就緒狀態!
? ? 如果該就緒狀態的任務恢復運行,此時任務控制塊的狀態標志仍為OS_STAT_SEM,運行OS_EventTO,做的事剛好和OS_EventTaskWait相反。
? ??(1)OSTCBCur->OSTCBEventPtr = 0;
? ? (2)設置任務控制塊中的狀態標志為就緒狀態(去除OS_STAT_SEM狀態) ? ? (3)去除事件控制塊中的任務等待表 ? ? 此時返回OS_TIMEOUT。
? ? 但是如果在等待時間未過去,其他任務釋放了信號量,OSSemPost能夠在釋放信號量的同時,恢復等待信號量的任務。等待信號量的任務恢復運行,此時任務控制塊的狀態標志不包含OS_STAT_SEM了,所以函數直接跳過第二個if語句,返回OS_NO_ERR。
釋放信號量過程: ? ? 函數OSSemPost在對信號量的計數器操作之前,首先檢查任務等待表中是否還有其他等待該信號的任務,如果沒有,就把計數器加1,如果有,則調用OS_EventTaskRdy將任務等待表中最高優先級的任務設為就緒狀態,并調用OSSched調度任務。
? 3. 應用 3.1申請函數和釋放函數在同一任務中成對出現 main: pevent = OSSemCreate(1);
task1: OSSemPend(pevent, 0, err);
.... OSSemPost(pevent); task2: OSSemPend(pevent, 0, err);
.... OSSemPost(pevent); 當一個任務沒有釋放信號量,另一個任務在申請信號量時只能掛起直到信號量釋放。 3.2 應用程序中有一個函數Fun(),如果想使任務M必須經過Y任務允許才能調用函數一次,可以使用信號量 main: pevent = OSSemCreate(0);
task1: OSSemPend(pevent, 0, err);
Fun(); task2: OSSemPost(pevent); 本文鏈接:http://www.cnblogs.com/cposture/p/4299055.html
轉載于:https://www.cnblogs.com/cposture/p/4299055.html
總結
以上是生活随笔為你收集整理的【原创】ucos信号量的操作及原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 下shell编程
- 下一篇: RS485最大通讯距离和RS485接口定