0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenHarmony内核任务间IPC原理

2KHh_gh_15d2f06 来源:深开鸿 作者:深开鸿 2022-07-12 16:45 次阅读

近年来,国内开源实现跨越式发展,并成为企业提升创新能力、生产力、协作和透明度的关键。作为 OpenAtom OpenHarmony(以下简称“OpenHarmony”)开源项目共建单位之一,深开鸿以成为智能物联网操作系统领军者为战略目标,基于 OpenHarmony 聚焦智能物联网操作系统(KaihongOS)的技术研发与持续创新。

身为深开鸿 OS 内核开发师,我们常年深耕于 OpenHarmony 的内核开发,希望通过分享一些工作上的经验,帮助大家掌握开源知识。

OpenHarmony LiteOS-M 内核是面向 IoT 领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点,其代码结构简单,实现了进程、线程、内存等管理机制,提供了常见任务间 IPC、软定时器等公共模块,大幅度降低了嵌入式设备开发的难度。目前 OpenHarmony 的事件提供一种任务间的 IPC,即一个或多个任务可以通过写一个或多个不同的事件来触发内核调度,让另一个等待读取事件的任务进入运行状态,从而实现任务间的同步。

对于嵌入式开发工作人员和技术爱好者来说,深入了解常见任务间 IPC,有助于学习和研发内核。本文将从数据结构和算法解析 OpenHarmony 的事件机制,带大家深入了解内核任务间 IPC 原理。

关键数据结构

在解读事件的源码之前,首先了解下事件的关键的数据结构 PEVENT_CB_S:

typedefstructtagEvent{    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_INITUINT32LOS_EventInit(PEVENT_CB_SeventCB){    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 初始化,此时没有事件发生,事件链表为空。

用图来表达就是:

fde8ee4c-ed2a-11ec-ba43-dac502259ad0.png

事件写操作

任务可以通过 LOS_EventWrite 来写触发一个或多个事件:

LITE_OS_SEC_TEXTUINT32LOS_EventWrite(PEVENT_CB_SeventCB,UINT32events){    ...    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处,一旦匹配到等待事件的任务,则执行任务调度,被唤醒的任务得到执行。

写事件实际操作如下图:

fe029ed2-ed2a-11ec-ba43-dac502259ad0.png

事件读操作

LiteOS 为用户提供了两个事件的函数:

● LOS_EventPoll():根据任务传入的事件值、掩码及校验模式,返回满足条件的事件,任务可以主动检查事件是否发生而不必被挂起;

● LOS_EventRead():读取事件,可以理解为阻塞式读,如果事件没有发生,可以指定等待时间,挂起当前任务。

下面是 LOS_EventPoll() 的实现:

LITE_OS_SEC_TEXTUINT32LOS_EventPoll(UINT32*eventID,UINT32eventMask,UINT32mode){    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_TEXTUINT32LOS_EventRead(PEVENT_CB_SeventCB,UINT32eventMask,UINT32mode,UINT32timeOut){    ...    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处,如果事件没有发生,当前读事件的任务被挂起,让出 CPU

4处,事件发生时等待事件的任务被调度再次获得 CPU 恢复执行,读取事件。

事件读写整个过程串起来如下图所示:

fe0b2066-ed2a-11ec-ba43-dac502259ad0.png

事件销毁操作

做事有始有终,事件消费完成剩下的事情是清除事件和等待事件的任务链表。

LITE_OS_SEC_TEXT_MINORUINT32LOS_EventClear(PEVENT_CB_SeventCB,UINT32eventMask){    ...    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——内核对象事件之源码详解

文章出处:【微信公众号:深开鸿】欢迎添加关注!文章转载请注明出处。

审核编辑:彭静

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10854

    浏览量

    211578
  • 操作系统
    +关注

    关注

    37

    文章

    6801

    浏览量

    123283
  • IPC
    IPC
    +关注

    关注

    3

    文章

    346

    浏览量

    51902
  • 数据结构
    +关注

    关注

    3

    文章

    573

    浏览量

    40123
  • OpenHarmony
    +关注

    关注

    25

    文章

    3713

    浏览量

    16254

原文标题:OpenHarmony——内核对象事件之源码详解

文章出处:【微信号:gh_15d2f062a168,微信公众号:深开鸿】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ipc系统的网络带宽需求分析

    IPC(Internet Protocol Camera)系统的网络带宽需求分析涉及多个因素,包括IPC的码流大小、网络架构、监控需求等。以下是对IPC系统网络带宽需求的分析: 一、IPC
    的头像 发表于 11-15 14:28 285次阅读

    ipc协议在物联网中的应用

    随着物联网(IoT)技术的快速发展,各种通信协议在其中扮演着至关重要的角色。IPC(进程通信)协议,虽然最初设计用于操作系统内部的进程通信,但在物联网领域也展现出了其独特的应用价值。 1. 物
    的头像 发表于 11-15 14:19 296次阅读

    【龙芯2K0300蜂鸟板试用】OpenHarmony代码

    收到龙芯2K0300蜂鸟开发板后,对开发板做了一些了解和研究,现将OpenHarmony代码提供给大家测试,也希望大家能更多的认识龙芯2K0300蜂鸟开发板,下面先简单介绍一下这块开发板。 广东
    发表于 09-18 11:42

    基于ArkTS语言的OpenHarmony APP应用开发:HelloOpenharmony

    1、程序简介该程序是基于OpenHarmony标准系统编写的UI应用类:HelloOpenHarmony。本案例是基于API9接口开发。本案例已在OpenHarmony凌蒙派-RK3568开发
    的头像 发表于 09-15 08:09 371次阅读
    基于ArkTS语言的<b class='flag-5'>OpenHarmony</b> APP应用开发:Hello<b class='flag-5'>Openharmony</b>

    IPC工控机有哪些技术特点?

          IPC工控机是一种加固增强型的个人计算机,由于IPC工控机的性能稳定,软件丰富,价格比较低,在工控机行业中脱颖而出,应用日渐广泛,目前IPC工控机已经被运用到通讯、工业控制现场、路桥收费
    的头像 发表于 07-30 09:59 427次阅读

    安防摄像头IPC芯片的应用

    安防摄像头IPC芯片的应用
    的头像 发表于 07-22 09:42 722次阅读
    安防摄像头<b class='flag-5'>IPC</b>芯片的应用

    欢创播报 华为宣布鸿蒙内核已超越Linux内核

    1 华为宣布鸿蒙内核已超越Linux内核   6月21日,在华为开发者大会上, HarmonyOS NEXT(鸿蒙NEXT)——真正独立于安卓和iOS的鸿蒙操作系统,正式登场。这是HarmonyOS
    的头像 发表于 06-27 11:30 826次阅读

    OpenHarmony语言基础类库【@ohos.taskpool(启动任务池)】

    任务池(taskpool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且您无需关心线程实例的生命周期。您可以使用任务池API创建后台任务(Task),并对所创
    的头像 发表于 04-24 17:45 346次阅读
    <b class='flag-5'>OpenHarmony</b>语言基础类库【@ohos.taskpool(启动<b class='flag-5'>任务</b>池)】

    OpenHarmony南向能力征集令

    1、适配过程中缺少哪些接口能力或者南向能力,需要OpenHarmony去补齐的?例如内核、编译、器件适配、单板适配等; 2、对标linux,需要OpenHarmony提供哪些能力?比如V4L2
    发表于 04-09 15:32

    OpenHarmony内核编程实战

    编程入门[Hello,OpenHarmony]在正式开始之前,对于刚接触OpenHarmony的伙伴们,面对大篇幅的源码可能无从下手,不知道怎么去编码写程序,下面用一个简单的例子带伙伴们入门。▍任务
    的头像 发表于 03-27 08:31 807次阅读
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>内核</b>编程实战

    鸿蒙OpenHarmony技术:【设备互信认证】

    OpenHarmony中,设备互信认证模块作为安全子系统的子模块,负责设备可信关系的建立、维护、使用、撤销等全生命周期的管理,实现可信设备的互信认证和安全会话密钥协商,是搭载OpenHa
    的头像 发表于 03-25 17:04 734次阅读
    鸿蒙<b class='flag-5'>OpenHarmony</b>技术:【设备互信认证】

    【鸿蒙】OpenHarmony运行docker详细步骤

    1.环境和设备 系统版本: 3.2release(64 位) OpenHarmony 内核版本:5.10 标准系统设备: DAYU200 Docker:18.03.1 (64 位) sd 卡一张
    的头像 发表于 03-02 15:10 2606次阅读
    【鸿蒙】<b class='flag-5'>OpenHarmony</b>运行docker详细步骤

    IPC平台商的市场格局

    AIoT星图研究院《2023视觉IoT消费市场分析报告》市场调研临近尾声,在我们走访企业时发现个有趣的现象:“头部方案商自己在做IPC平台,而不少IPC平台商也做方案,甚至成品”。平台商成本很高,在
    的头像 发表于 01-25 11:00 1101次阅读
    <b class='flag-5'>IPC</b>平台商的市场格局

    Meteor Lake CPU有望实现更低的IPC效能

     评判不同世代CPU优劣时,IPC常被视为架构改良的重要考量因素。若同一时钟周期内完成任务增加,反映架构上的进化。然而,IPC的测量受工作负荷影响,数据传输速率又受到缓存容量及指令搭配方式等变量的极大制约。
    的头像 发表于 01-08 10:08 647次阅读
    Meteor Lake CPU有望实现更低的<b class='flag-5'>IPC</b>效能

    IPC-D-620和IPC/WHMA-A-620操作手册与指南

    电子发烧友网站提供《IPC-D-620和IPC/WHMA-A-620操作手册与指南.pdf》资料免费下载
    发表于 12-25 09:42 67次下载