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

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

做者介绍bootstrap

中科创达OpenHarmony研究组app

说明框架

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

本篇内容摘要:源码分析

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

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

主要结构体

 

关键成员说明:spa

1. struct TaskConfig:在注册Service时提供,描述了Servcie对应的task的优先级,栈等信息.net

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的初始化。

相关文章
相关标签/搜索