当前位置:网站首页>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 .

边栏推荐
- 电子商务盛行,怎么提高商店转换率?
- Shell unknown rollup 1
- 技术管理进阶——管理者如何做绩效沟通及把控风险
- Lumiprobe ProteOrange 蛋白质凝胶染料说明书
- 抗兔Dylight 488丨Abbkine通用型免疫荧光(IF)工具箱
- use. NETCORE's own background job, which simply simulates producers and consumers' processing of request response data in and out of the queue
- Baidu time factor addition
- Operations research note
- 正版ST-link/V2 J-LINK JTAG/SWD引脚定义和注意事项
- 324. swing sequencing II
猜你喜欢

Understanding of closures

内存泄露

Enhancing steam and engineering education from theory to practice

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

Advanced technology management - how managers communicate performance and control risks

19.2 container classification, array and vector container refinement

新工作第一天

【Unity3D】发射(RayCast)物理射线(Ray)

声网 VQA:将实时互动中未知的视频画质用户主观体验变可知

PHP使用栈解决迷宫问题
随机推荐
SqlTransaction
Sharing-JDBC分布式事务之Seata实现
use. NETCORE's own background job, which simply simulates producers and consumers' processing of request response data in and out of the queue
数据资产为王,如何解析企业数字化转型与数据资产管理的关系?
Steam education to break the barriers between disciplines
Lumiprobe ProteOrange 蛋白质凝胶染料说明书
Huawei cloud AOM released version 2.0, and three features appeared
CVPR2022 | 浙大、蚂蚁集团提出基于标签关系树的层级残差多粒度分类网络,建模多粒度标签间的层级知识
Michael Wooldridge, professeur à l'Université d'Oxford: comment la communauté de l'IA voit les réseaux neuronaux depuis près de 40 ans
Modular operation
获取当前日期0点及23点59时间戳
Shell unknown rollup 1
声网 VQA:将实时互动中未知的视频画质用户主观体验变可知
牛津大學教授Michael Wooldridge:AI社區近40年如何看待神經網絡
Collection of real test questions
中金财富开户安全吗?开过中金财富的讲一下
安装nodejs环境
浦发银行软件测试面试真题(小编面试亲测)
Advanced technology management - how managers communicate performance and control risks
Voice network VQA: make the user's subjective experience of unknown video quality in real-time interaction known