色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從數據結構和算法解析OpenHarmony的事件機制

OpenAtom OpenHarmony ? 來源:OpenAtom OpenHarmony ? 作者:蔣衛峰、陳利明 ? 2022-06-16 09:46 ? 次閱讀

近年來,國內開源實現跨越式發展,并成為企業提升創新能力、生產力、協作和透明度的關鍵。作為 OpenAtom OpenHarmony(以下簡稱“OpenHarmony”)開源項目共建單位之一,深開鴻以成為智能物聯網操作系統領軍者為戰略目標,基于 OpenHarmony 聚焦智能物聯網操作系統(KaihongOS)的技術研發與持續創新。身為深開鴻 OS 內核開發師,我們常年深耕于 OpenHarmony 的內核開發,希望通過分享一些工作上的經驗,幫助大家掌握開源知識。OpenHarmony LiteOS-M 內核是面向 IoT 領域構建的輕量級物聯網操作系統內核,具有小體積、低功耗、高性能的特點,其代碼結構簡單,實現了進程、線程、內存等管理機制,提供了常見任務間 IPC、軟定時器等公共模塊,大幅度降低了嵌入式設備開發的難度。目前 OpenHarmony 的事件提供一種任務間的 IPC,即一個或多個任務可以通過寫一個或多個不同的事件來觸發內核調度,讓另一個等待讀取事件的任務進入運行狀態,從而實現任務間的同步。對于嵌入式開發工作人員和技術愛好者來說,深入了解常見任務間 IPC,有助于學習和研發內核。本文將從數據結構和算法解析 OpenHarmony 的事件機制,帶大家深入了解內核任務間 IPC 原理。

關鍵數據結構

在解讀事件的源碼之前,首先了解下事件的關鍵的數據結構 PEVENT_CB_S:
typedef struct tagEvent {    UINT32 uwEventID;           LOS_DL_LIST stEventList; /**< Event control block linked list */  }EVENT_CB_S,*PEVENT_CB_S;
uwEventID:即標記任務的事件類型,每個bit可以標識一個事件,最多支持 31 個事件(第 25bit 保留)。stEventList:即事件控制塊的雙向循環鏈表,理解這個字段是理解事件的關鍵。在雙向循環鏈表中唯一不變的節點就是頭節點,而這里的 stEventList 就是頭節點。當有任務等待事件但事件還沒發生時,任務會被掛載到等待鏈表中;當事件發生時,系統喚醒等待事件的任務,此時任務就會被剔出鏈表。

事件初始化

下面是事件初始化源碼:
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB){    if (eventCB == NULL) {        return LOS_ERRNO_EVENT_PTR_NULL;    }    eventCB->uwEventID = 0;    LOS_ListInit(&eventCB->stEventList);    OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB);    return LOS_OK;}

PEVENT_CB_S 相當于 EVENT_CB_S *, 因此 eventCB 是指針。

說明事件控制塊由任務自己創建,內核事件模塊只負責維護。任務定義自己的事件控制塊變量,通過 LOS_EventInit 初始化,此時沒有事件發生,事件鏈表為空。

用圖來表達就是:

d55e716e-ecac-11ec-ba43-dac502259ad0.png

事件寫操作

任務可以通過 LOS_EventWrite 來寫觸發一個或多個事件:
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events){    ...    eventCB->uwEventID |= events;                    ---1    if (!LOS_ListEmpty(&eventCB->stEventList)) {     ---2        for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList);             &resumedTask->pendList != (&eventCB->stEventList);) { -------3            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);       ---4            }            resumedTask = nextTask;        }
        if (exitFlag == 1) {            LOS_IntRestore(intSave);            LOS_Schedule();                        ---5            return LOS_OK;        }    }    ...}
1處,保存事件使用的或運算操作,因此一個或多個任務可以寫一個或多個事件,寫一次或多次,而且每次為不同的事件,多次寫同一個事件相當于只寫了一次;2處,有事件發生了就該檢查是否有任務在等待事件,事件鏈表不為空說明有任務在等待事件;3處,遍歷事件鏈表,喚醒符合條件的任務。LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext,LosTaskCB,pendList) 前面提到,頭節點是空節點,第一次遍歷從頭節點的下一個節點開始,后續再依次找出 nextTask,直到回到頭節點;4處,針對事件讀取模式,找到滿足條件的任務并喚醒該任務;5處,一旦匹配到等待事件的任務,則執行任務調度,被喚醒的任務得到執行。

寫事件實際操作如下圖:

d56d742a-ecac-11ec-ba43-dac502259ad0.png

事件讀操作

LiteOS 為用戶提供了兩個事件的函數:● LOS_EventPoll():根據任務傳入的事件值、掩碼及校驗模式,返回滿足條件的事件,任務可以主動檢查事件是否發生而不必被掛起;● LOS_EventRead():讀取事件,可以理解為阻塞式讀,如果事件沒有發生,可以指定等待時間,掛起當前任務。

下面是 LOS_EventPoll() 的實現:

LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode){    UINT32 ret = 0;    UINT32 intSave;
    if (eventID == NULL) {        return LOS_ERRNO_EVENT_PTR_NULL;    }    intSave = LOS_IntLock();    if (mode & LOS_WAITMODE_OR) {        if ((*eventID & eventMask) != 0) {      ---1            ret = *eventID & eventMask;        }    } else {        if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) {   ---2            ret = *eventID & eventMask;        }    }    if (ret && (mode & LOS_WAITMODE_CLR)) {   ---3        *eventID = *eventID & ~(ret);    }    LOS_IntRestore(intSave);    return ret;}
1處,如果讀取模式是LOS_WAITMODE_OR,只要有一個事件發生則讀取成功,返回發生的那個事件;2處,如果讀取模式LOS_WAITMODE_AND,全部檢查事件發生才算讀取成功,并返回全部發生事件;3處,事件讀取成功后事件控制塊中的事件標記怎么處理?這里通過LOS_WAITMODE_CLR來決定是否清除事件標記。

可以看出以上實現了兩種事件的讀取方式:一種是多個事件只要一個發生就算發生,另一種是全部事件發生才算發生。

下面是 LOS_EventRead():

LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut){    ...    ret = LOS_EventPoll(&(eventCB->uwEventID), eventMask, mode);           ---1    OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeOut);    if (ret == 0) {        if (timeOut == 0) {            LOS_IntRestore(intSave);            return ret;        }
        if (g_losTaskLock) {            LOS_IntRestore(intSave);            return LOS_ERRNO_EVENT_READ_IN_LOCK;        }        runTsk = g_losTask.runTask;        runTsk->eventMask = eventMask;        runTsk->eventMode = mode;        OsSchedTaskWait(&eventCB->stEventList, timeOut);                  ---2        LOS_IntRestore(intSave);        LOS_Schedule();                                                   ---3
        intSave = LOS_IntLock();        if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) {            runTsk->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;            LOS_IntRestore(intSave);            return LOS_ERRNO_EVENT_READ_TIMEOUT;        }
        ret = LOS_EventPoll(&eventCB->uwEventID, eventMask, mode);       ---4    }     ...}
1處,主動查詢想要的事件是否已經發生;2處,如果事件沒有發生,就把當前任務掛起到等待事件鏈表中;3處,如果事件沒有發生,當前讀事件的任務被掛起,讓出 CPU4處,事件發生時等待事件的任務被調度再次獲得 CPU 恢復執行,讀取事件。

事件讀寫整個過程串起來如下圖所示:

d5865e54-ecac-11ec-ba43-dac502259ad0.png

事件銷毀操作

做事有始有終,事件消費完成剩下的事情是清除事件和等待事件的任務鏈表。
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask){    ...    eventCB->uwEventID &= eventMask;    ...}

LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB){    ...    eventCB->stEventList.pstNext = (LOS_DL_LIST *)NULL;    eventCB->stEventList.pstPrev = (LOS_DL_LIST *)NULL;    ...}
在 LOS_EventClear 中通過使 eventMask=0 來清空事件,在 LOS_EventDestroy 中清空事件鏈表指針。

小結

看了上面的描述,相信大家對 OpenHarmony LiteOS-M 內核事件的運作機制有了更加深刻的理解,開發者可以更好地使用事件的 API 來進行任務間的同步操作,也可以進一步嘗試修改內核事件通知機制,做出一個更適合自己任務的IPC機制。

OpenHarmony 生態建設離不開每位開發者的參與,希望有更多的開發者分享自己開源項目的經驗和成果,共同為 OpenHarmony 生態建設貢獻一份力量。

原文標題:OpenHarmony——內核對象事件之源碼詳解

文章出處:【微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內核
    +關注

    關注

    3

    文章

    1381

    瀏覽量

    40364
  • 數據結構
    +關注

    關注

    3

    文章

    573

    瀏覽量

    40190
  • 事件機制
    +關注

    關注

    0

    文章

    2

    瀏覽量

    6227
  • OpenHarmony
    +關注

    關注

    25

    文章

    3744

    瀏覽量

    16473

原文標題:OpenHarmony——內核對象事件之源碼詳解

文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    數據結構算法分析(Java版)(pdf)

    數據結構算法分析(Java版)(pdf)http://www.ibeifeng.com/read.php?tid=4812&u=73481【中文】Java數據結構算法中文第
    發表于 12-20 21:22

    數據結構算法分析

    數據結構算法分析
    發表于 06-05 10:46

    OpenHarmony——內核IPC機制數據結構解析

    的頭部。六、總結本篇文章通過數據結構的隊列、事件、互斥鎖、信號量四大方面對內核IPC機制數據結構進行解析,希望以上的講解能給大家建立一個IPC機制
    發表于 09-05 11:02

    OpenHarmony——內核IPC機制數據結構解析

    涉及到哪些關鍵數據結構?這些數據結構又是如何工作的?接下來我將從隊列、事件、互斥鎖、信號量幾個內核對象出發,為大家講解內核IPC機制數據結構。二、
    發表于 09-08 11:44

    數據結構教程,下載

    1. 數據結構的基本概念 2. 算法數據結構3. C語言的數據類型及其算法描述要點4. 學習算法
    發表于 05-14 17:22 ?0次下載
    <b class='flag-5'>數據結構</b>教程,下載

    數據結構算法習題

    數據結構算法習題,ACM專用,刷題初期按照這個地方刷很好
    發表于 03-03 18:25 ?0次下載

    數據結構算法

    全國C語言考試公共基礎知識點——數據結構算法,該資料包含了有關數據結構算法的全部知識點。
    發表于 03-30 14:27 ?0次下載

    數據結構算法分析

    一部淺顯易懂的介紹數據結構算法的書籍。
    發表于 07-14 17:12 ?0次下載

    引入深度遍歷機制的分布式數據結構插值算法

    引入深度遍歷機制的分布式數據結構插值算法_龔健虎
    發表于 01-08 14:55 ?0次下載

    算法數據結構——接口

    第三章為算法數據結構,本文為3.2.3 接口。
    的頭像 發表于 09-19 17:41 ?8568次閱讀
    <b class='flag-5'>算法</b>與<b class='flag-5'>數據結構</b>——接口

    大牛分享平時如何學習數據結構算法

    數據結構算法的地位對于一個程序員來說不言而喻。今天這篇文章不是來勸你們學習數據結構算法的,也不是來和你們說數據結構
    的頭像 發表于 11-02 11:25 ?3001次閱讀

    JavaScrit數據結構算法(第2版)

    JavaScrit數據結構算法(第2版)教材下載。
    發表于 06-01 15:35 ?0次下載

    算法數據結構基礎知識分享(上)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法
    的頭像 發表于 04-06 16:48 ?820次閱讀
    <b class='flag-5'>算法</b>和<b class='flag-5'>數據結構</b>基礎知識分享(上)

    算法數據結構基礎知識分享(中)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法
    的頭像 發表于 04-06 16:48 ?632次閱讀
    <b class='flag-5'>算法</b>和<b class='flag-5'>數據結構</b>基礎知識分享(中)

    算法數據結構基礎知識分享(下)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法
    的頭像 發表于 04-06 16:48 ?775次閱讀
    <b class='flag-5'>算法</b>和<b class='flag-5'>數據結構</b>基礎知識分享(下)
    主站蜘蛛池模板: 欧美18精品久久久无码午夜福利| 中文字幕人成乱码熟女APP| 成人伊人青草久久综合网| 翁用力的抽插| 久久亚洲精品2017| 北条麻妃のレズナンパ| 亚洲精品AV无码永久无码| 伦理在线影院伦理电影| 第一次处破女18分钟免费| 亚洲最大在线视频| 日本888 xxxx| 九九九精品国产在线| 操老太太的逼| 亚洲中文字幕一二三四区苍井空 | 伊人国产精品| 日本久久久WWW成人免费毛片丨| 国产亚洲精品AV片在线观看播放 | 双性诱受灌满哭求饶BL| 久久视频这只精品99re6| 公和熄洗澡三级中文字幕| 伊久久| 丝瓜涩涩屋黄瓜香蕉丝瓜| 老熟女重囗味GRANNYBBW| 国产精品久久久久久亚洲毛片| 综合精品欧美日韩国产在线| 网红主播 国产精品 开放90后| 老鸭窝毛片| 国产欧美日韩亚洲第一页| 99热这里只有精品| 一个人免费播放高清在线观看| 色小说在线| 內射XXX韩国在线观看| 和尚轮流澡到高潮H| 东北老妇人70OLDMAN| 97国产人妻精品无码AV在线| 亚洲精品在看在线观看| 色婷婷粉嫩AV精品综合在线| 嫩草影院久久精品| 久久久久琪琪精品色| 国模精品一区二区三区视频| 国产 亚洲 中文字幕 久久网|