Hi3861的SAMGR--系统服务框架子系统-1

系统
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[403501]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

1. 初步了解

先看README文档,位于LTS/foundation/distributedschedule/samgr_lite/README_zh.md。

我们对其中的部分内容先做一下初步的理解。

系统服务框架[system ability (SA) framework],是为了屏蔽不同的硬件架构、不同的平台资源、不同的运行形态等软硬件差异,而提供的统一的系统服务开发框架。

根据处理器的不同架构,如RISC-V架构(基于精简指令集RISC的开源架构)、ARM架构(如ARM的Cortex-M/Cortex-A等)、x86架构(主要用于PC市场,目前鸿蒙暂不支持,但指不定哪天就宣布支持了)等,目前分为两类硬件平台,以下简称M核(平台)、A核(平台)。

  • M核:处理器架构为Cortex-M或同等处理能力的硬件平台,系统内存一般低于512KB,无文件系统或者仅提供一个可有限使用的轻量级文件系统,遵循CMSIS接口规范。
  • A核:处理器架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。

系统服务框架基于面向服务的架构(SOA,Service-Oriented Architecture),提供了服务(service)开发、服务的子功能(feature)开发、对外接口(IUnknown)的开发、以及多服务共进程、进程间服务调用等开发能力。其中:

  • M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。
  • A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。

依赖关系上:

  • M核:系统依赖bootstrap服务,在系统启动函数中调用HOS_SystemInit()函数。
  • A核:系统依赖samgr库,在main函数中调用SAMGR_Bootstrap()函数。

我的简单理解:

  • samgr是一个系统服务开发框架,开发者可以根据这里规定的规则,开发自定义的服务和功能(service+feature)、接口等等。

示例程序在Hi3861/applications/sample/wifi-iot/app/samgr/,打开BUILD.gn的编译规则即可参与编译。

示例程序可能会有编译错误,可以获取gitee上的最新代码对比着进行修改,或者参考《WiFi IoT 编译samgr模块》 进行修改。

编译出来的程序可能会出现kernel panic,我估计很大的原因是一次性注册和启动的service/feature/task太多了,导致系统资源耗尽引起的,所以最好还是只编译部分需要验证的示例程序,不要一次全部编译完。我后面附上的log,就是只编译了service_example.c和feature_example.c抓取的。

  • samgr提供了对所有service、feature、接口的统一管理,包含了跨设备的service/feature的管理和调度,这是鸿蒙系统非常核心的特性之一。

2. 代码目录结构

先看一下LTS/foundation/distributedschedule/samgr_lite/ 的代码结构:

看上去相当复杂。

再看对应的Hi3861/foundation/distributedschedule/ 代码结构:

两相对比,其实大致上是一样的。

去 Hi3861/foundation/distributedschedule/service/samgr_lite/ 目录下看BUILD.gn文件的构建规则,把只在A核上编译的部分灰化,如上表,剩下的基本上就是M核要用到的了。

本文先只从Hi3861工程的角度来看samgr子系统,所以代码基本上只需要看:

  1. Hi3861/foundation/distributedschedule/service/samgr_lite/communication/broadcast/ 
  2.  
  3. Hi3861/foundation/distributedschedule/service/samgr_lite/samgr/source/ 

 因为samgr“依赖bootstrap服务”,所以连带也要看 Hi3861/base/startup/services/bootstrap_lite/ 的代码。

至于:

  1. Hi3861/foundation/distributedschedule/service/samgr_lite/samgr/adapter/ 

这是对调用者屏蔽了平台差异性的统一接口的声明和实现,暂不进一步深究。

  1. Hi3861/foundation/distributedschedule/service/samgr_lite/samgr/registry/ 

这里定义了三个弱引用的API:

  1. SAMGR_RegisterServiceApi() 
  2.  
  3. SAMGR_FindServiceApi() 
  4.  
  5. SAMGR_RegisterFactory() 

 它们在/samgr_server/source/ samgr_server.c 中有实现,估计和跨设备的服务调用有关,但是M核不编译samgr_server,所以,M核的上述三个API其实没做什么工作,这里也暂不进一步深究。

这样清理一下相关代码和模块关系就会发现简单很多,入手也会相对容易一些,下面我们就开始“Read the f**king source code :)”。

3. 大概流程

Hi3861平台在启动到HOS_SystemInit()时,

  1. void HOS_SystemInit(void) 
  2.     ...... 
  3.     printf("[system_init] [7-4]: SYS_INIT(service)=====================\n"); 
  4.     SYS_INIT(service); 
  5.  
  6.     printf("[system_init] [7-5]: SYS_INIT(feature)=====================\n"); 
  7.     SYS_INIT(feature); 
  8.     ...... 
  9.     printf("[system_init] [7-7]: SAMGR_Bootstrap()=====================\n"); 
  10.     SAMGR_Bootstrap(); 

 会分别通过上面三步来:向samgr注册系统服务(service)、注册系统服务提供的功能(feature)、通过samgr启动并开始管理系统服务和功能。

从抓回来的log看:

  1. [system_init] [7-4]: SYS_INIT(service)===================== 
  2.  
  3. [bootstrap_service] SYS_SERVICE_INIT(Init): Bootstrap 
  4.  
  5. [samgr_lite] SAMGR_GetInstance(mutex=NULL): NO SAMGR instance, Init() to create ONE 
  6.  
  7. [samgr_lite] Init. g_samgrImpl 
  8.  
  9. [samgr_lite] Init. mutex[956036]. sharedPool[0-8] reset to 0. status=0[BOOT_SYS] 
  10.  
  11. [samgr_lite] SAMGR_GetInstance(mutex=956036) 
  12.  
  13. [samgr_lite] RegisterService(Name:Bootstrap)->Sid[0] 
  14.  
  15.   
  16.  
  17. [broadcast_service] SYS_SERVICE_INIT(Init): Broadcast 
  18.  
  19. [samgr_lite] RegisterService(Name:Broadcast)->Sid[1] 
  20.  
  21.   
  22.  
  23. [hiview_service] SYS_SERVICE_INIT(Init): hiview 
  24.  
  25. [samgr_lite] RegisterService(Name:hiview)->Sid[2] 
  26.  
  27. [samgr_lite] RegisterFeatureApi(serviceName[hiview], feature[(null)]) 
  28.  
  29. [hiview_service] Init.InitHiviewComponent. 
  30.  
  31.   
  32.  
  33. [system_init] [7-5]: SYS_INIT(feature)===================== 
  34.  
  35. [pub_sub_feature] Init. SYS_FEATURE_INIT(Init) g_broadcastFeature: Provider and subscriber 
  36.  
  37. [samgr_lite] RegisterFeature(serviceName:Broadcast, featureName:Provider and subscriber)->Fid[0] 
  38.  
  39. [pub_sub_implement] BCE_CreateInstance: set g_pubSubImplement.feature = &g_broadcastFeature 
  40.  
  41. [samgr_lite] RegisterFeatureApi(serviceName[Broadcast], feature[Provider and subscriber]) 

会注册三个系统服务和一个系统feature。

第一个注册的系统服务是Bootstrap,这个时候samgr还没有实例,所以需要先初始化samgr的全局实例g_samgrImpl,然后才能通过RegisterService((Service *)&bootstrap)来向g_samgrImpl注册bootstrap服务。这时候g_samgrImpl会通过SAMGR_CreateServiceImpl()来为bootstrap创建一个ServiceImpl 对象,将该对象加入g_samgrImpl.services向量中,并返回它在向量中的位置[0],以此作为bootstrap 的ServiceID[0](文中或log中简写为Sid,同样FeatureID简写为Fid,QueueID简写为Qid)。

接下来注册的第二个服务broadcast和第三个服务hiview,就可以直接通过RegisterService((Service *)Xxx)记录进g_samgrImpl.services向量里了,Sid分别是[1]/[2]。

接下来再注册broadcast service的feature:PUB_SUB_FEATURE。feature的注册和运行需要依赖于对应的service,一个service可以有0个、1个或多个feature。通过RegisterFeature(service, feature)的调用,samgr也会先生成一个FeatureImpl对象,再将该对象加入到 g_samgrImpl.services向量中对应的service 的ServiceImpl 对象的向量features中去,以完成feature的注册。这一句看起来比较绕,简单来说,就是g_samgrImpl的services向量管理着所有登记在册的services的ServiceImpl ,而每个ServiceImpl又通过自己的features向量管理自己所有的features。【更具体的实现过程,后面会有详细的代码分析。】

在接下来的系统运行中,serviceName/serviceID(Sid) 和featureName/featureID(Fid) 都是非常重要的信息,samgr可以通过它们来找到对应的ServiceImpl/FeatureImpl对象,并提供相应的服务/功能。

  1. [system_init] [7-7]: SAMGR_Bootstrap()===================== 
  2.  
  3. [samgr_lite] SAMGR_Bootstrap. Begin:    size=3 
  4.  
  5.         InitializeAllServices: size=3 
  6.  
  7.         Add service: Bootstrap   to TaskPool: 0x0... 
  8.  
  9.                                                    TaskPool: 0xfa448... 
  10.  
  11.                                                            Qid: 956360... 
  12.  
  13.         Add service: Broadcast   to TaskPool: 0x0... 
  14.  
  15.                                                    TaskPool: 0xfaab8... 
  16.  
  17.                                                            Qid: 956404... 
  18.  
  19.         Add service: hiview      to TaskPool: 0x0... 
  20.  
  21.                                                  TaskPool: 0xfac78... 
  22.  
  23.                                                          Qid: 956448... 
  24.  
  25. [task_manager] SAMGR_StartTaskPool: 
  26.  
  27.         CreateTask[Bootstrap(Tid: 0xe8780), size(8192), Prio(25)]-OK! 
  28.  
  29. [task_manager] SAMGR_StartTaskPool: 
  30.  
  31.         CreateTask[Broadcast(Tid: 0xe871c), size(4096), Prio(32)]-OK! 
  32.  
  33. [task_manager] SAMGR_StartTaskPool: 
  34.  
  35.         CreateTask[hiview(Tid: 0xe87e4), size(2048), Prio(24)]-OK! 
  36.  
  37. [samgr_lite] SAMGR_Bootstrap. End

 这里就是samgr开始为各个登记在g_samgrImpl.services向量里的service创建Queue和TaskPool这些运行环境了,在SAMGR_StartTaskPool() 这一步依次创建和启动service任务/线程,线程入口是TaskEntry()函数,位于Hi3861/foundation/distributedschedule/services/samgr_lite/samgr/source/task_manager.c 文件内。

各个服务的TaskEntry线程,监控着各自的消息队列Queue,从中检出消息,获取Exchange封装的数据,根据里面的相关标记调用相关的msg handler来进行对应的处理。

上面的流程仅仅是启动了用SYS_SERVICE_INIT()和SYS_FEATURE_INIT() 标记的service和feature,而通过SYSEX_SERVICE_INIT/APP_SERVICE_INIT/ SYSEX_FEATURE_INIT/APP_FEATURE_INIT 标记的service和feature(如在前面提到的示例程序samgr里定义的一部分service和feature),则会在系统启动到 BOOT_APP 这一步时,通过发送消息BOOT_SYS_COMPLETED到Bootstrap的消息队列中,让Bootstrap调用MessageHandle()来处理该消息:通过调用INIT_APP_CALL(service)和INIT_APP_CALL(feature)来完成APP service和Feature的启动,从而提供用户定义的服务和功能。

上面是service/feature的注册和启动的大概过程,主要的工作都是samgr来实现的,这就是samgr_lite组件的基础代码部分所提供的功能。

log和简单的步骤描述,见附件log。

接下来我会对一些重要的结构体进行分解,对部分流程进行详细的分析。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-06-10 09:25:39

鸿蒙HarmonyOS应用

2021-06-18 10:02:10

鸿蒙HarmonyOS应用

2021-06-18 15:23:59

鸿蒙HarmonyOS应用

2021-07-05 09:35:36

鸿蒙HarmonyOS应用

2021-07-08 16:16:59

鸿蒙HarmonyOS应用

2021-07-07 09:45:20

鸿蒙HarmonyOS应用

2021-07-12 09:50:39

鸿蒙HarmonyOS应用

2021-04-30 09:43:27

鸿蒙HarmonyOS应用

2022-03-07 15:05:58

HTTPHi3861数据解析

2020-10-30 09:41:44

鸿蒙Hi3861WiFi小车

2022-03-15 15:00:59

Hi3861Pin接口鸿蒙

2020-10-16 09:50:37

Hi3861WiFi热点

2020-11-03 11:39:22

wifi小车

2022-05-30 15:21:27

Hi3861TCP通信

2020-11-02 12:07:11

鸿蒙 GPIO

2023-05-26 16:07:14

Hi3861Wifi模块

2020-10-12 09:36:04

鸿蒙

2020-10-28 10:03:43

Hi3861 GPIO点灯按键

2021-09-09 10:06:09

鸿蒙HarmonyOS应用

2022-03-04 15:51:43

TTS功能Hi3861科大讯飞
点赞
收藏

51CTO技术栈公众号