1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          event(事件Event的含義和作用)

          來源:互聯網轉載 時間:2024-05-13 20:29:24

          事件(Event)是一種任務間通信的機制,可用于任務間的同步。多任務環境下,任務之間往往需要同步操作,一個等待即是一個同步。事件可以提供一對多、多對多的同步操作。本文通過分析鴻蒙輕內核事件模塊的源碼,深入掌握事件的使用。本文中所涉及的源碼,以OpenHarmony LiteOS-M內核為例,均可以在開源站點https://gitee.com/openharmony/kernel_liteos_m 獲取。

          接下來,我們看下事件的結構體,事件初始化,事件常用操作的源代碼。

          1、事件結構體定義和常用宏定義

          1.1 事件結構體定義

          在文件kernel\include\los_event.h定義的事件控制塊結構體為EVENT_CB_S,結構體源代碼如下,結構體成員的解釋見注釋部分。

          typedefstructtagEvent{UINT32uwEventID;/**<事件ID,每一位標識一種事件類型*/LOS_DL_LISTstEventList;/**<讀取事件的任務鏈表*/}EVENT_CB_S,*PEVENT_CB_S;

          1.2 事件常用宏定義

          在讀事件時,可以選擇讀取模式。讀取模式由如下幾個宏定義:

          所有事件(LOS_WAITMODE_AND):

          邏輯與,基于接口傳入的事件類型掩碼eventMask,只有這些事件都已經發生才能讀取成功,否則該任務將阻塞等待或者返回錯誤碼。

          任一事件(LOS_WAITMODE_OR):

          邏輯或,基于接口傳入的事件類型掩碼eventMask,只要這些事件中有任一種事件發生就可以讀取成功,否則該任務將阻塞等待或者返回錯誤碼。

          清除事件(LOS_WAITMODE_CLR):

          這是一種附加讀取模式,需要與所有事件模式或任一事件模式結合使用(LOS_WAITMODE_AND | LOS_WAITMODE_CLR或 LOS_WAITMODE_OR | LOS_WAITMODE_CLR)。在這種模式下,當設置的所有事件模式或任一事件模式讀取成功后,會自動清除事件控制塊中對應的事件類型位。

          #defineLOS_WAITMODE_AND(4)#defineLOS_WAITMODE_OR(2)#defineLOS_WAITMODE_CLR(1)

          2、事件常用操作

          2.1 初始化事件

          在使用事件前,必須使用函數UINT32 LOS_EventInit(PEVENT_CB_S eventCB)來初始化事件,需要的參數是結構體指針變量PEVENT_CB_S eventCB。分析下代碼,⑴處表示傳入的參數不能為空,否則返回錯誤碼。⑵處把事件編碼.uwEventID初始化為0,然后初始化雙向循環鏈表.stEventList,用于掛載讀取事件的任務。

          LITE_OS_SEC_TEXT_INITUINT32LOS_EventInit(PEVENT_CB_SeventCB){⑴if(eventCB==NULL){returnLOS_ERRNO_EVENT_PTR_NULL;}⑵eventCB->uwEventID=0;LOS_ListInit(&eventCB->stEventList);OsHookCall(LOS_HOOK_TYPE_EVENT_INIT);returnLOS_OK;}

          2.2 校驗事件掩碼

          我們可以使用函數UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode)來校驗事件掩碼,需要的參數為事件結構體的事件編碼eventId、用戶傳入的待校驗的事件掩碼eventMask及讀取模式mode,返回用戶傳入的事件是否發生: 返回值為0時,表示用戶預期的事件沒有發生,否則表示用戶期望的事件發生。

          我們看下源碼,⑴處先檢查傳入參數的合法性,事件編碼不能為空。然后執行⑵處的代碼進行校驗。如果是任一事件讀取模式,接下來的判斷不等于表示至少有一個事件發生了,返回值ret就表示哪些事件發生了。⑶如果是所有事情讀取模式,當邏輯與運算*eventId & eventMask還等于eventMask時,表示期望的事件全部發生了,返回值ret就表示哪些事件發生了。⑷處當ret不為0,期望的事件發生,并且是清除事件讀取模式時,需要把已經發生的事情進行清除??磥?這個函數不僅僅是查詢事件有沒有發生,還會有更新事件編碼的動作。

          LITE_OS_SEC_TEXTUINT32LOS_EventPoll(UINT32*eventID,UINT32eventMask,UINT32mode){UINT32ret=0;UINT32intSave;⑴if(eventID==NULL){returnLOS_ERRNO_EVENT_PTR_NULL;}intSave=LOS_IntLock();⑵if(mode&LOS_WAITMODE_OR){if((*eventID&eventMask)!=0){ret=*eventID&eventMask;}}else{⑶if((eventMask!=0)&&(eventMask==(*eventID&eventMask))){ret=*eventID&eventMask;}}⑷if(ret&&(mode&LOS_WAITMODE_CLR)){*eventID=*eventID&~(ret);}LOS_IntRestore(intSave);returnret;}

          2.3 讀/寫事件

          2.3.1 讀取指定事件類型

          我們可以使用函數LOS_EventRead()來讀取事件,需要4個參數。eventCB是初始化好的事件結構體,eventMask表示需要讀取的事件掩碼,mode是上文說明過的讀取模式,timeout是讀取超時,單位是Tick。函數返回0時,表示期望的事件沒有發生,讀取事件失敗,進入阻塞。返回非0時表示期望的事件發生了,成功讀取事件。下面我們分析下函數的源碼來看看如何讀取事件的。

          ⑴處調用函數OsEventReadParamCheck()進行基礎的校驗,比如第25位保留不能使用,事件掩碼eventMask不能為零,讀取模式組合是否合法。⑵處表示不能中斷中讀取事件。⑶處調用校驗函數OsEventPoll()檢查事件eventMask是否發生。如果事件發生ret不為0,成功讀取直接返回。ret為0,事件沒有發生時,執行⑷,如果超時時間timeout為0,調用者不能等待時,直接返回。⑸如果鎖任務調度時,不能讀取事件,返回錯誤碼。

          ⑹更新當前任務的阻塞的事件掩碼.eventMask和事件讀取模式.eventMode。執行⑺調用函數OsSchedTaskWait更改當前任務的狀態為阻塞狀態,掛載到事件的任務阻塞鏈表上。如果timeout不是永久等待,還會把任務設置為OS_TASK_STATUS_PEND_TIME狀態并設置等待時間。⑻處觸發任務調度,后續程序需要等到讀取到事件才會繼續執行。

          ⑼如果等待時間超時,事件還不可讀,本任務讀取不到指定的事件時,返回錯誤碼。如果可以讀取到指定的事件時,執行⑽,檢查事件eventMask是否發生,然后返回結果值。

          LITE_OS_SEC_TEXTUINT32LOS_EventRead(PEVENT_CB_SeventCB,UINT32eventMask,UINT32mode,UINT32timeOut){UINT32ret;UINT32intSave;LosTaskCB*runTsk=NULL;⑴ret=OsEventReadParamCheck(eventCB,eventMask,mode);if(ret!=LOS_OK){returnret;}⑵if(OS_INT_ACTIVE){returnLOS_ERRNO_EVENT_READ_IN_INTERRUPT;}intSave=LOS_IntLock();⑶ret=LOS_EventPoll(&(eventCB->uwEventID),eventMask,mode);OsHookCall(LOS_HOOK_TYPE_EVENT_READ,eventCB,eventMask,mode);if(ret==0){⑷if(timeOut==0){LOS_IntRestore(intSave);returnret;}⑸if(g_losTaskLock){LOS_IntRestore(intSave);returnLOS_ERRNO_EVENT_READ_IN_LOCK;}runTsk=g_losTask.runTask;⑹runTsk->eventMask=eventMask;runTsk->eventMode=mode;⑺OsSchedTaskWait(&eventCB->stEventList,timeOut);LOS_IntRestore(intSave);⑻LOS_Schedule();⑼intSave=LOS_IntLock();if(runTsk->taskStatus&OS_TASK_STATUS_TIMEOUT){runTsk->taskStatus&=~OS_TASK_STATUS_TIMEOUT;LOS_IntRestore(intSave);returnLOS_ERRNO_EVENT_READ_TIMEOUT;}⑽ret=LOS_EventPoll(&eventCB->uwEventID,eventMask,mode);}LOS_IntRestore(intSave);returnret;}

          2.3.2 寫入指定的事件類型

          我們可以使用函數UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)來寫入指定的事件類型。代碼如下所示:

          下面通過分析源碼來看看如何寫入事件類型的。⑴處代碼把事件結構體的事件掩碼和要寫入的事件類型events進行邏輯或計算,來完成事件的寫入。⑵如果等待事件的任務鏈表不為空,需要處理寫入事件后是否有任務能讀取到相應的事件。⑶處for循環依次遍歷事件阻塞鏈表上的任務,⑷獲取下一個任務nextTask。⑸處

          分不同的讀取模式判斷事件是否符合任務resumedTask讀取事件的要求,如果滿足讀取事件,執行⑹設置退出標記exitFlag,然后調用函數OsSchedTaskWake()把讀取事件的任務更改狀態并放入就緒隊列,繼續執行⑺,遍歷事件的阻塞任務鏈表中的每一個任務。⑻如果有任務讀取到事件,需要觸發任務調度。

          LITE_OS_SEC_TEXTUINT32LOS_EventWrite(PEVENT_CB_SeventCB,UINT32events){LosTaskCB*resumedTask=NULL;LosTaskCB*nextTask=(LosTaskCB*)NULL;UINT32intSave;UINT8exitFlag=0;if(eventCB==NULL){returnLOS_ERRNO_EVENT_PTR_NULL;}if((eventCB->stEventList.pstNext==NULL)||(eventCB->stEventList.pstPrev==NULL)){returnLOS_ERRNO_EVENT_NOT_INITIALIZED;}if(events&LOS_ERRTYPE_ERROR){returnLOS_ERRNO_EVENT_SETBIT_INVALID;}intSave=LOS_IntLock();⑴eventCB->uwEventID|=events;OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE,eventCB);⑵if(!LOS_ListEmpty(&eventCB->stEventList)){⑶for(resumedTask=LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext,LosTaskCB,pendList);&resumedTask->pendList!=(&eventCB->stEventList);){⑷nextTask=LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext,LosTaskCB,pendList);⑸if(((resumedTask->eventMode&LOS_WAITMODE_OR)&&(resumedTask->eventMask&events)!=0)||((resumedTask->eventMode&LOS_WAITMODE_AND)&&((resumedTask->eventMask&eventCB->uwEventID)==resumedTask->eventMask))){⑹exitFlag=1;OsSchedTaskWake(resumedTask);}⑺resumedTask=nextTask;}if(exitFlag==1){LOS_IntRestore(intSave);⑻LOS_Schedule();returnLOS_OK;}}LOS_IntRestore(intSave);returnLOS_OK;}

          2.4 清除事件

          我們可以使用函數UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask)來清除指定的事件類型,下面通過分析源碼看看如何清除事件類型的。

          函數參數為事件結構體eventCB和要清除的事件類型eventMask。清除事件時首先會進行結構體參數是否為空的校驗,這些比較簡單。⑴處把事件結構體的事件掩碼和要清除的事件類型eventMask進行邏輯與計算,來完成事件的清理。

          LITE_OS_SEC_TEXT_MINORUINT32LOS_EventClear(PEVENT_CB_SeventCB,UINT32eventMask){UINT32intSave;if(eventCB==NULL){returnLOS_ERRNO_EVENT_PTR_NULL;}intSave=LOS_IntLock();⑴eventCB->uwEventID&=eventMask;LOS_IntRestore(intSave);OsHookCall(LOS_HOOK_TYPE_EVENT_CLEAR,eventCB);returnLOS_OK;}

          2.5 銷毀事件

          我們可以使用函數UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)來銷毀指定的事件控制塊,下面通過分析源碼看看如何銷毀事件的。

          函數參數為事件結構體,銷毀事件時首先會進行結構體參數是否為空的校驗,這些比較簡單。⑴處如果事件的任務阻塞鏈表不為空,則不能銷毀事件。⑵把事件結構體的讀取事件的任務鏈表stEventList設置為空,完成事件的銷毀。

          LITE_OS_SEC_TEXT_INITUINT32LOS_EventDestroy(PEVENT_CB_SeventCB){UINT32intSave;if(eventCB==NULL){returnLOS_ERRNO_EVENT_PTR_NULL;}intSave=LOS_IntLock();⑴if(!LOS_ListEmpty(&eventCB->stEventList)){LOS_IntRestore(intSave);returnLOS_ERRNO_EVENT_SHOULD_NOT_DESTORY;}⑵eventCB->stEventList.pstNext=(LOS_DL_LIST*)NULL;eventCB->stEventList.pstPrev=(LOS_DL_LIST*)NULL;LOS_IntRestore(intSave);OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY);returnLOS_OK;}

          “事件Event的含義和作用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注本站網站,小編將為大家輸出更多高質量的實用文章!

          標簽:event-

          c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...

          2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...

          :喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...

          (資料圖)1、現價GDP是指名義GDP,可比價GDP是指真實GDP。2、GDP是通過計算商品價格得到的,所以不可避免會受到價格波動的影響。3、比如一棵青菜,去年賣1塊5,今年賣5塊,明年可能是1塊2。4、為了避免價格波動造成的GDP統計失真,所以采用可比價格GDP,對相同或相似商品以某一年價格為基準,去除價格變動因素,以統計GDP的漲跌。本文到此分享完畢,希望對大家有所幫助。...

          華西村是怎么富起來的?華西村就是靠走公有制的集體道路,才讓村里的大部分村民都富起來。華西村隸屬于江蘇省江陰市華士鎮,是一個享譽全國、世界知名的村莊。這個村子創造了一個個驚人奇跡,成為共同富裕的典范和中國農村改革的樣本,被譽為“天下第一村”。然而,半個多世紀以前,華西村也是貧困落后的村莊,不僅糧食生產沒有保障,一遇自然災害農民們不是背井離鄉就是家破人亡。如今,華西村是中國最富...

          (相關資料圖)關于丶怎么打出來的知識大家了解嗎?以下就是小編整理的關于丶怎么打出來的介紹,希望可以給到大家一些參考,一起來了解下吧!1、這里我們用到的是搜狗輸入法。2、搜狗輸入法打這個很簡單,我們調用中文輸入,然后輸入“dian”即可。3、另外,我們輸入“zhu”的話,效果也是一樣的,可以試試。假如沒找到的話,可以多翻幾頁。4、同樣的,我們還可以輸入“un”來,打出該字符。5、假如使用的是百度輸入...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>