鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动) 原创 精华

阿拉神农
发布于 2021-5-8 11:01
浏览
5收藏

作者介绍:

中科创达OpenHarmony研究组

 

说明:

中科创达OpenHarmony研究组第一时间对https://gitee.com/openharmony上开源的代码进行了详尽的代码研读和学习。为此,我们打算编写一系列篇幅中等,内容精炼的源码分析文章来引领大家更进一步的走进鸿蒙OS。随着对代码的了解,广大开发者想亲自动手参与的意愿和信心也会随之增强——这也是鸿蒙OS开源的意义所在。

 

本篇内容摘要:

Samgr模块提供了面向服务体系结构(SOA)的开发框架基础,提供了Servcie、Feature和Founction的基本模型,以及注册和发现功能。是鸿蒙Framework非常重要的部分。系统中基于Samgr开发了许多服务,如Broadcast service, Bootstrap Servcie等,用户也可以基于Samgr开发框架开发自己的Service。

本篇介绍了OpenHarmony服务按序注册和启动的流程。

 

主要结构体

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

关键成员说明:

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注册的流程:

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

1. 系统service使用SYS_SERVICE_INIT,SYS_FEATURE_INIT,用户Service使用APP_SERVICE_INIT,APP_FEATURE_INIT来注册服务,对于M核,把服务的注册函数放到指定的段,在启动时找到此段调用所有的函数。对于A核这个宏定义使用了__attribute__(constructor)的特性,这个特性在在程序加载后,程序执行之前执行注册函数

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

2. 注册Servcie主要是把ServiceImpl追加到全局g_samgrImpl的成员services Vector,并根据Servcie在向量表中的序号来确定ServcieID。

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

3. 注册Feature主要是把FeatureImpl追加到对应服务的的features Vector,并根据Feature在向量表中的序号来确定FeatureID

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

下图是Service初始化流程:

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

4. 服务初始化的入口是SAMGR_Bootstrap(foundation/distributedschedule/services/samgr_lite/samgr/samgr_lite.c),主要实现以下功能:

a. 先更新全局g_samgrImpl的status:

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

而Status有如下的枚举:

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

那么更新的逻辑就是这样子了:

    如果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,一起初始化

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

5. 为收集的每个Servcie创建TaskPool和创建消息队列。并拿到消息队列的句柄,以后向某个Servcie线程发送消息时就会发送给相应的队列。

 

6. 将函数HandleInitRequest发送到消息队列,这个函数将会在Service线程创建启动后,在Service对应的线程中执行。如果没有申请到队列,或者没有申请到taskpool,就在当前线程中执行初始化操作

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

7. 为每个申请到队列和taskpool的service创建和启动Task。

下图是Task的执行流程

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

Task循环执行以下内容:

    从消息队列中获取exchange并拿到ServiceImpl

    如果消息类型为MSG_ACK或者MSG_DIRECT,就执行exchange->handler函数,结合上一步,初始化时执行HandleInitRequest

    如果是其他类型(Request),则会调用Feature的 OnMessage或者Servcie的MessageHandle,然后再执行handler。

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

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服务发送消息告知此阶段初始化已完成

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

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

鸿蒙OS开源代码精要解读之—— 系统服务框架子系统(服务启动)-鸿蒙开发者社区

12. 以此类推,最终按顺序完成sys service, app service, dynamic的初始化。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2021-5-8 11:32:29修改
5
收藏 5
回复
举报
3条回复
按时间正序
/
按时间倒序
liangkz_梁开祝
liangkz_梁开祝

是我的菜。

回复
2021-5-8 11:15:04
鸿蒙张荣超
鸿蒙张荣超

赞赞赞!

回复
2021-5-9 22:55:41
DaHuangXiao
DaHuangXiao

受益匪浅

回复
2022-4-9 15:56:55
回复
    相关推荐