23

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

 3 years ago
source link: https://blog.csdn.net/Innost/article/details/109023401
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

作者介绍

中科创达OpenHarmony研究组

说明

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

本篇内容摘要:

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

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

主要结构体

im2QZff.png!mobile

关键成员说明:

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

zUVrmiV.png!mobile

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

nqUJ3ay.png!mobile

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

nAVFBzb.png!mobile

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

VNFBru3.png!mobile

下图是Service初始化流程:

va2meaR.png!mobile

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

a. 先更新全局g_samgrImpl的status:

6ZNbA3Q.png!mobile

而Status有如下的枚举:

If2ABvE.png!mobile

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

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

jIfqYby.png!mobile

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

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

aqaUfuM.png!mobile

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

下图是Task的执行流程

Q3mEJfM.png!mobile

Task 循环执行以下内容:

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

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

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

2ymyqir.png!mobile

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

faeyuee.png!mobile

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK