当前位置:网站首页>Openharmony - detailed source code of Kernel Object Events
Openharmony - detailed source code of Kernel Object Events
2022-06-28 18:49:00 【Openharmony developer community】
In recent years , Domestic open source to achieve leapfrog development , And become an enterprise to improve its innovation ability 、 Productivity 、 Key to collaboration and transparency . As OpenAtom OpenHarmony( hereinafter referred to as “OpenHarmony”) One of the co construction units of open source projects , Shenkaihong takes becoming the leader of intelligent IOT operating system as its strategic goal , be based on OpenHarmony Focus on Intelligent Internet of things operating system (KaihongOS) Technology R & D and continuous innovation .
As shenkaihong OS Kernel developer , We plough deeply all the year round OpenHarmony Kernel development , I hope to share some work experience , Help you master open source knowledge .
OpenHarmony LiteOS-M The kernel is oriented to IoT The lightweight Internet of things operating system kernel built in the field , Have a small volume 、 low power consumption 、 High performance features , Its code structure is simple , Realized the process 、 Threads 、 Memory and other management mechanisms , Provides common task rooms IPC、 Soft timer and other common modules , It greatly reduces the difficulty of embedded device development . at present OpenHarmony The event of provides an inter task IPC, That is, one or more tasks can trigger kernel scheduling by writing one or more different events , Put another task waiting to read events into running state , So as to realize the synchronization between tasks .
For embedded developers and technology enthusiasts , Learn more about common tasks IPC, Help learn and develop the kernel . This article will analyze from data structure and algorithm OpenHarmony Event mechanism , Let's have a deep understanding of the kernel tasks IPC principle .
Key data structure
Before reading the source code of the event , First, understand the key data structure of the next event PEVENT_CB_S:
typedef struct tagEvent { UINT32 uwEventID; LOS_DL_LIST stEventList; /**< Event control block linked list */ } EVENT_CB_S, *PEVENT_CB_S;
uwEventID: That is, mark the event type of the task , Every bit Can identify an event , Most support 31 Events ( The first 25bit Retain ).
stEventList: That is, the bidirectional circular linked list of the event control block , Understanding this field is the key to understanding events . The only constant node in a two-way circular linked list is the head node , And here it is stEventList It's the head node . When there is a task waiting for an event, but the event has not yet occurred , The task will be attached to the waiting list ; When the event occurs , The system wakes up tasks waiting for events , The task will be removed from the linked list .
Event initialization
The following is the event initialization source code :
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 amount to EVENT_CB_S *, therefore eventCB Is a pointer .
Explain that the event control block is created by the task itself , The kernel event module is only responsible for maintenance . The task defines its own event control block variables , adopt LOS_EventInit initialization , No event has occurred at this time , The event linked list is empty .
To express it in a diagram is :

Event write operation
Tasks can be done through LOS_EventWrite To trigger one or more events :
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 It's about , Save the or operation used by the event , So one or more tasks can write one or more events , Write once or more , And each time for a different event , Writing the same event multiple times is equivalent to writing it only once ;
2 It's about , When an event occurs, it is necessary to check whether there are tasks waiting for the event , The event linked list is not empty, indicating that there are tasks waiting for events ;
3 It's about , Traverse the event list , Wake up qualified tasks .
LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext,LosTaskCB,pendList) Mentioned earlier , The head node is an empty node , The first traversal starts from the next node of the head node , Then find out in turn nextTask, Until the node returns to the head ;
4 It's about , Read mode for events , Find the task that meets the condition and wake it up ;
5 It's about , Once the task waiting for the event is matched , Then execute task scheduling , The awakened task is performed .
The actual operation of writing events is shown in the following figure :

Event read operation
LiteOS Functions that provide users with two events :
● LOS_EventPoll(): According to the event value passed in by the task 、 Mask and verification mode , Return the event that meets the condition , The task can actively check whether the event occurs without being suspended ;
● LOS_EventRead(): Read event , It can be understood as blocking reading , If it doesn't happen , You can specify the waiting time , Suspend current task .
Here is LOS_EventPoll() The implementation of the :
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 It's about , If the read mode is LOS_WAITMODE_OR, As long as one event occurs, the reading succeeds , Return to the event that occurred ;
2 It's about , If the read mode LOS_WAITMODE_AND, Reading is successful only when all check events occur , And return all occurrences ;
3 It's about , How to handle the event tag in the event control block after the event is successfully read ? Through here LOS_WAITMODE_CLR To decide whether to clear the event marker .
It can be seen that the above two event reading methods are implemented : One is that multiple events can occur as long as one event occurs , The other is that only when all events occur .
Here is 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 It's about , Actively query whether the desired event has occurred ;
2 It's about , If it doesn't happen , Hang the current task in the waiting event list ;
3 It's about , If it doesn't happen , The task of reading the current event is suspended , Give up CPU;
4 It's about , When the event occurs, the task waiting for the event is scheduled to be obtained again CPU Resume execution , Read event .
The whole process of event reading and writing is linked as shown in the following figure :

Event destroy
Consistent follow-through , After the event consumption is completed, the remaining tasks are to clear the event and wait for the event .
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; ...}
stay LOS_EventClear By making eventMask=0 To clear the event , stay LOS_EventDestroy Clear event linked list pointer in .
Summary
Look at the description above , I'm sure you're right OpenHarmony LiteOS-M The operating mechanism of kernel events has been better understood , Developers can better use the... Of events API To synchronize tasks , You can also try to modify the kernel event notification mechanism further , Make a better one for your task IPC Mechanism .
OpenHarmony Ecological construction is inseparable from the participation of every developer , I hope more developers can share their experience and achievements in open source projects , Jointly OpenHarmony Contribute to ecological construction .

边栏推荐
- curl: (56) Recv failure: Connection reset by peer
- BioVendor游离轻链(κ和λ)Elisa 试剂盒检测步骤
- id门禁卡复制到手机_怎么把手机变成门禁卡 手机NFC复制门禁卡图文教程
- Huawei cloud AOM released version 2.0, and three features appeared
- Tensorboard Usage Summary
- tensorboard 使用总结
- OOM out of memory 内存溢出
- OneFlow源码解析:算子签名的自动推断
- Openfire 3.8.2集群配置
- leetcode 1689. Partitioning Into Minimum Number Of Deci-Binary Numbers(最少的“二进制数“个数)
猜你喜欢

idea其他分支合并到dev分支

openGauss内核:SQL解析过程分析

1 invalid import format(s) Postman Collection Format v1 is no longer supported and can not be import

进阶高级-业务事务设计 开发入门

双功能交联剂丨Lumiprobe 磺基花青7二羧酸研究

Tensorboard Usage Summary

Database comparison tool

1 goal, 3 fields, 6 factors and 9 links of digital transformation

C# 41. int与string互转

Qt 中 QObjectCleanupHandler 使用总结
随机推荐
sqrt()函数的详解和用法「建议收藏」
1 goal, 3 fields, 6 factors and 9 links of digital transformation
AOSP清华镜像下载错误解决
180.1.连续登录N天(数据库)
Advanced - Introduction to business transaction design and development
Tensorboard Usage Summary
An in-depth analysis of the election mechanism in kubernetes
Seata implementation of sharing JDBC distributed transaction
Upload file list (repeated file names are marked with brackets)
curl: (56) Recv failure: Connection reset by peer
独立站卖家如何高效管理复杂的Facebook主页?
微信小程序接入百度统计报错 Cannot read property ‘mtj‘ of undefined
Database comparison tool
1 invalid import format(s) Postman Collection Format v1 is no longer supported and can not be import
About Statistical Distributions
19.2 container classification, array and vector container refinement
Anonymous function this pointing and variable promotion
正版ST-link/V2 J-LINK JTAG/SWD引脚定义和注意事项
OpenHarmony—内核对象事件之源码详解
业务层修改--根据现有框架的反推修改