鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)
作者介绍:
中科创达OpenHarmony研究组
说明:
中科创达OpenHarmony研究组第一时间对https://codechina.csdn.net/openharmony上开源的代码进行了详尽的代码研读和学习。为此,我们打算编写一系列篇幅中等,内容精炼的源码分析文章来引领大家更进一步的走进鸿蒙OS。随着对代码的了解,广大开发者想亲自动手参与的意愿和信心也会随之增强——这也是鸿蒙OS开源的意义所在。
本篇内容摘要:
Samgr模块提供了面向服务体系结构(SOA)的开发框架基础,提供了Servcie、Feature和Founction的基本模型,以及注册和发现功能。是鸿蒙Framework非常重要的部分。系统中基于Samgr开发了许多服务,如Broadcast service, Bootstrap Servcie等,用户也可以基于Samgr开发框架开发自己的Service。
本篇介绍了OpenHarmony服务按序注册和启动的流程。
主要结构体
关键成员说明:
1. struct TaskConfig:在注册Service时提供,描述了Servcie对应的task的优先级,栈等信息
2. struct TaskPool:初始化Service时生成
- queueId:创建taskpool时生成,通过不同的queueId来向不同的Servcie task发送消息
3. struct Service:要注册的Servcie,用户需要实现如下四个函数:
- GetName:返回Servcie名称
- Initialize:Servcie初始化函数,一般是要保存Service初始化生成的身份信息用于后续收发消息
- MessageHandle:信息处理函数
- TaskConfig:返回Service对应的Task配置
4. struct Operations:记录Servcie的时间戳等信息
5. struct ServiceImpl:注册Servcie实际上注册的是ServiceImpl
- Service *service:注册的Servcie
- TaskPool *taskPool:初始化时申请的taskpool
- Vector features:Service下的子feature
- int16 serviceId:serviceId的值为servcie在Vector中的位置,这个值在加载时就已经确定。
- uint8 inited:初始化标志
6. struct SamgrLiteImpl:全局只有一个SamgrLiteImpl g_samgrImpl。
- BootStatus status:Service启动的状态,目前定义了以下状态值:
- BOOT_SYS:将要启动系统Service
- BOOT_SYS_WAIT:正在启动系统Service
- BOOT_APP:将要启动APP Servcie
- BOOT_APP_WAIT:正在启动APP Servcie
- BOOT_DYNAMIC:将要启动Dynamic Servcie
- BOOT_DYNAMIC_WAIT:正在启动Dynamic Service
- Vector services:注册Servcie时将一个servcieImpl结构体追加到Vector末尾,用于后面的初始化
启动流程
下图Servcie注册的流程:
1. 系统service使用SYS_SERVICE_INIT,SYS_FEATURE_INIT,用户Service使用APP_SERVICE_INIT,APP_FEATURE_INIT来注册服务,对于M核,把服务的注册函数放到指定的段,在启动时找到此段调用所有的函数。对于A核这个宏定义使用了__attribute__(constructor)的特性,这个特性在在程序加载后,程序执行之前执行注册函数
2. 注册Servcie主要是把ServiceImpl追加到全局g_samgrImpl的成员services Vector,并根据Servcie在向量表中的序号来确定ServcieID。
3. 注册Feature主要是把FeatureImpl追加到对应服务的的features Vector,并根据Feature在向量表中的序号来确定FeatureID
下图是Service初始化流程:
4. 服务初始化的入口是SAMGR_Bootstrap(foundation/distributedschedule/services/samgr_lite/samgr/samgr_lite.c),主要实现以下功能:
a. 先更新全局g_samgrImpl的status:
而Status有如下的枚举:
那么更新的逻辑就是这样子了:
如果status为BOOT_SYS == 0b,更新后是BOOT_SYS_WAIT == 1b;
如果status为BOOT_APP == 10b,更新后是BOOT_APP_WAIT == 11b;
如果status为BOOT_DYNAMIC == 100b,更新后是BOOT_DYNAMIC_WAIT == 101b;
如果status为BOOT_SYS_WAIT == 1b; BOOT_APP_WAIT == 11b; BOOT_DYNAMIC_WAIT == 101b;更新后不变。
g_samgrImpl的初始状态是BOOT_SYS,首次调用会更新为BOOT_SYS_WAIT
b. 收集全局g_samgrImpl->servcies Vector中还没有被初始化,状态为SVC_INIT的servcie,一起初始化
5. 为收集的每个Servcie创建TaskPool和创建消息队列。并拿到消息队列的句柄,以后向某个Servcie线程发送消息时就会发送给相应的队列。
6. 将函数HandleInitRequest发送到消息队列,这个函数将会在Service线程创建启动后,在Service对应的线程中执行。如果没有申请到队列,或者没有申请到taskpool,就在当前线程中执行初始化操作
7. 为每个申请到队列和taskpool的service创建和启动Task。
下图是Task的执行流程
Task循环执行以下内容:
从消息队列中获取exchange并拿到ServiceImpl
如果消息类型为MSG_ACK或者MSG_DIRECT,就执行exchange->handler函数,结合上一步,初始化时执行HandleInitRequest
如果是其他类型(Request),则会调用Feature的 OnMessage或者Servcie的MessageHandle,然后再执行handler。
8. Service task启动后会从队列中获取到HandleInitRequest并执行,主要做了以下的工作:
- 调用service的Initialize和feature OnInitialize函数,并将初始化过程中的ServcieID,FeatureID,和QueueID作为参数传出,service一般会保存该ID用于以后身份鉴别。
- 更新Servcie的状态为SVC_IDLE
- 检查全局g_samgrImpl的services vector是否还有未初始化的servcie(如图,pose >= size,则表示Service已经全部初始化完成),如果都完成了就更新status到下一个状态,并给Bootstrap服务发送消息告知此阶段初始化已完成
9. Bootstrap服务收到消息后就会加载下一阶段的程序。如果此时sys service已经完成,将会加载app
10. 用户Service使用APP_SERVICE_INIT,APP_FEATURE_INIT注册app service到全局g_samgrImpl的services vector中
11. SendBootRequest服务初始化入口SAMGR_Bootstrap作为handler传给bootstrap service,用户程序加载完成后bootstrap又会调用SAMGR_Bootstrap函数,返回第4步去初始化app servcie
12. 以此类推,最终按顺序完成sys service, app service, dynamic的初始化。
转载:https://blog.csdn.net/Innost/article/details/109023401