系统服务框架子系统

简介

这个仓库用于存放系统服务框架的代码。由于平台资源有限,且硬件平台多样,因此需要屏蔽不同硬件架构和资源的不同、以及运行形态的不同,提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台,分为两种平硬件平台,以下简称M核、A核。

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

A核:处理架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。

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

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

面向服务的架构:

系统服务框架子系统 - 图1

Provider:服务的提供者,为系统提供能力(对外接口)。

Consumer:服务的消费者,调用服务提供的功能(对外接口)。

Samgr:做为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。

系统服务开发框架主体对象:

系统服务框架子系统 - 图2

  • SamgrLite:主要提供服务的注册与发现能力。
  • Service:开发服务时,需要实现的服务的生命周期接口。
  • Feature:开发功能时,需要实现的功能的生命周期接口。
  • IUnknown:基于IUnknown开发服务或功能的对外接口。
  • IClientProxy:IPC调用时,消费者的消息发送代理。
  • IServerProxy:IPC调用时,开发者需要实现的,生产者的消息处理代理。

目录

表 1 系统服务框架源代码目录结构

名称 描述
interfaces/kits/samgr_lite/samgr M核和A核系统服务框架对外接口定义。
interfaces/kits/samgr_lite/registry A核进程间服务调用的对外接口定义。
interfaces/kits/samgr_lite/communication/broadcast M核和A核进程内事件广播服务的对外接口定义。
services/samgr_lite/samgr/adapter POSIX和CMSIS接口适配层来屏蔽A核M核接口差异。
services/samgr_lite/samgr/registry M核服务注册发现的桩函数。
services/samgr_lite/samgr/source M核和A核系统服务开发框架基础代码。
services/samgr_lite/samgr_client A核进程间服务调用的注册与发现。
services/samgr_lite/samgr_server A核进程间服务调用的IPC地址管理和访问控制。
services/samgr_lite/samgr_endpoint A核IPC通信消息收发包管理。
services/samgr_lite/communication/broadcast M核和A核进程内事件广播服务。

约束

系统服务开发框架统一使用C开发。

同进程内服务间调用统一使用IUnknown接口对外象,消息接口统一由IUnknown接口传递给本服务。

服务名和功能名必需使用常量字符串且长度小于16个字节。

M核:系统依赖上bootstrap服务,在系统启动函数中调用HOS_SystemInit()函数。

A核:系统依赖samgr库,在main函数中调用SAMGR_Bootstrap()函数。

开发服务

  • 继承并重新定义服务:

```

  1. typedef struct ExampleService {
  2. INHERIT_SERVICE;
  3. INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
  4. Identity identity;
  5. } ExampleService; ``` - 实现服务的生命周期函数:

```

  1. static const char GetName(Service service)
  2. {
  3. return EXAMPLE_SERVICE;
  4. }

  5. static BOOL Initialize(Service *service, Identity identity)

  6. {
  7. ExampleService example = (ExampleService )service;
  8. // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。
  9. example->identity = identity;
  10. return TRUE;
  11. }
  12. static BOOL MessageHandle(Service service, Request msg)
  13. {
  14. ExampleService example = (ExampleService )service;
  15. switch (msg->msgId) {
  16. case MSG_SYNC:
  17. // 业务处理
  18. break;
  19. default:break;
  20. }
  21. return FALSE;
  22. }
  23. static TaskConfig GetTaskConfig(Service *service)
  24. {
  25. TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
  26. 0x800, 20, SHARED_TASK};
  27. return config;
  28. } ``` - 创建服务对象:

```

  1. static ExampleService g_example = {
  2. .GetName = GetName,
  3. .Initialize = Initialize,
  4. .MessageHandle = MessageHandle,
  5. .GetTaskConfig = GetTaskConfig,
  6. SERVER_IPROXY_IMPL_BEGIN,
  7. .Invoke = NULL,
  8. .SyncCall = SyncCall,
  9. IPROXY_END,
  10. }; ``` - 向SAMGR注册服务及接口:

```

  1. static void Init(void)
  2. {
  3. SAMGR_GetInstance()->RegisterService((Service *)&g_example);
  4. SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
  5. } ``` - 定义服务的初始化入口:

```

  1. SYSEX_SERVICE_INIT(Init); ```

开发服务的子功能

  • 继承并重新定义功能:

```

  1. typedef struct DemoFeature {
  2. INHERIT_FEATURE;
  3. INHERIT_IUNKNOWNENTRY(DemoApi);
  4. Identity identity;
  5. Service *parent;
  6. } DemoFeature; ``` - 实现功能的生命周期函数:

```

  1. static const char FEATURE_GetName(Feature feature)
  2. {
  3. return EXAMPLE_FEATURE;
  4. }

  5. static void FEATURE_OnInitialize(Feature feature, Service parent, Identity identity)

  6. {
  7. DemoFeature demoFeature = (DemoFeature )feature;
  8. demoFeature->identity = identity;
  9. demoFeature->parent = parent;
  10. }

  11. static void FEATURE_OnStop(Feature *feature, Identity identity)

  12. {
  13. g_example.identity.queueId = NULL;
  14. g_example.identity.featureId = -1;
  15. g_example.identity.serviceId = -1;
  16. }

  17. static BOOL FEATURE_OnMessage(Feature feature, Request request)

  18. {
  19. if (request->msgId == MSG_PROC) {
  20. Response response = {.data = "Yes, you did!", .len = 0};
  21. SAMGR_SendResponse(request, &response);
  22. return TRUE;
  23. } else {
  24. if (request->msgId == MSG_TIME_PROC) {
  25. LOS_Msleep(WAIT_FEATURE_PROC * 10);
  26. if (request->msgValue) {
  27. SAMGR_PrintServices();
  28. } else {
  29. SAMGR_PrintOperations();
  30. }
  31. AsyncTimeCall(GET_IUNKNOWN(g_example));
  32. return FALSE;
  33. }
  34. }
  35. return FALSE;
  36. } ``` - 创建功能对象:

```

  1. static DemoFeature g_example = {
  2. .GetName = FEATURE_GetName,
  3. .OnInitialize = FEATURE_OnInitialize,
  4. .OnStop = FEATURE_OnStop,
  5. .OnMessage = FEATURE_OnMessage,
  6. DEFAULT_IUNKNOWN_ENTRY_BEGIN,
  7. .AsyncCall = AsyncCall,
  8. .AsyncTimeCall = AsyncTimeCall,
  9. .SyncCall = SyncCall,
  10. .AsyncCallBack = AsyncCallBack,
  11. DEFAULT_IUNKNOWN_ENTRY_END,
  12. .identity = {-1, -1, NULL},
  13. }; ``` - 向SAMGR注册功能及接口:

```

  1. static void Init(void){
  2. SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
  3. SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
  4. } ``` - 定义功能的初始化入口:

```

  1. SYSEX_FEATURE_INIT(Init); ```

开发进程内对外接口

  • 定义IUnknown接口:

```

  1. typedef struct DemoApi {
  2. INHERIT_IUNKNOWN;
  3. BOOL (AsyncCall)(IUnknown iUnknown, const char *buff);
  4. BOOL (AsyncTimeCall)(IUnknown iUnknown);
  5. BOOL (SyncCall)(IUnknown iUnknown, struct Payload *payload);
  6. BOOL (AsyncCallBack)(IUnknown iUnknown, const char *buff, Handler handler);
  7. } DemoApi; ``` - 定义IUnknown的引用对象:

```

  1. typedef struct DemoRefApi {
  2. INHERIT_IUNKNOWNENTRY(DemoApi);
  3. } DemoRefApi; ``` - 初始化接口对象:

```

  1. static DemoRefApi api = {
  2. DEFAULT_IUNKNOWN_ENTRY_BEGIN,
  3. .AsyncCall = AsyncCall,
  4. .AsyncTimeCall = AsyncTimeCall,
  5. .SyncCall = SyncCall,
  6. .AsyncCallBack = AsyncCallBack,
  7. DEFAULT_IUNKNOWN_ENTRY_END,
  8. }; ``` - 注册服务接口:

```

  1. SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api)); ```

调用进程内服务

  • 获取服务的对外接口:

```

  1. DemoApi *demoApi = NULL;
  2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
  3. if (iUnknown == NULL) {
  4. return NULL;
  5. }
  6. int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
  7. if (result != 0 || demoApi == NULL) {
  8. return NULL;
  9. } ``` - 接口调用:

```

  1. if (demoApi->AsyncCallBack == NULL) {
  2. return NULL;
  3. }
  4. demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler); ``` - 释放接口:

```

  1. int32 ref = demoApi->Release((IUnknown *)demoApi); ```

开发跨进程间对外接口

  • 继承IServerProxy替代继承IUnknown:INHERIT_SERVER_IPROXY

```

  1. typedef struct DemoFeatureApi {
  2. INHERIT_SERVER_IPROXY;
  3. BOOL (AsyncCall)(IUnknown iUnknown, const char *buff);
  4. BOOL (AsyncTimeCall)(IUnknown iUnknown);
  5. BOOL (SyncCall)(IUnknown iUnknown, struct Payload *payload);
  6. BOOL (AsyncCallBack)(IUnknown iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
  7. } DemoFeatureApi; ``` - 初始化IServerProxy的Invoke函数:

```

  1. static DemoFeature g_example = {
  2. SERVER_IPROXY_IMPL_BEGIN,
  3. .Invoke = Invoke,
  4. .AsyncCall = AsyncCall,
  5. .AsyncTimeCall = AsyncTimeCall,
  6. .SyncCall = SyncCall,
  7. .AsyncCallBack = AsyncCallBack,
  8. IPROXY_END,
  9. }; ``` - 实现Invoke函数来处理Ipc消息:

```

  1. static int32 Invoke(IServerProxy iProxy, int funcId, void origin, IpcIo req, IpcIo reply)
  2. {
  3. DemoFeatureApi api = (DemoFeatureApi )iProxy;
  4. BOOL ret;
  5. size_t len = 0;
  6. switch (funcId) {
  7. case ID_ASYNCALL:
  8. ret = api->AsyncCall((IUnknown )iProxy, (char )IpcIoPopString(req, &len));
  9. IpcIoPushBool(reply, ret);
  10. break;
  11. case ID_ASYNTIMECALL:
  12. ret = api->AsyncTimeCall((IUnknown *)iProxy);
  13. IpcIoPushBool(reply, ret);
  14. break;
  15. case ID_SYNCCALL: {
  16. struct Payload payload;
  17. payload.id = IpcIoPopInt32(req);
  18. payload.value = IpcIoPopInt32(req);
  19. payload.name = (char *)IpcIoPopString(req, &len);
  20. ret = api->SyncCall((IUnknown *)iProxy, &payload);
  21. IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
  22. }
  23. break;
  24. case ID_ASYNCCALLBACK: { // convert to sync proxy
  25. IpcIoPushString(reply, "Yes, you did!");
  26. IpcIoPushBool(reply, TRUE);
  27. }
  28. break;
  29. default:
  30. IpcIoPushBool(reply, FALSE);
  31. break;
  32. }
  33. return EC_SUCCESS;
  34. } ``` - 注册接口:与进程内接口注册一致

```

  1. SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example)); ```

调用跨进程间服务

  • 获取跨进程服务的对外接口:

```

  1. IClientProxy *demoApi = NULL;
  2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
  3. if (iUnknown == NULL) {
  4. return NULL;
  5. }
  6. int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
  7. if (result != 0 || demoApi == NULL) {
  8. return NULL;
  9. } ``` - 调用Ipc消息接口:

```

  1. IpcIo request;char data[250];
  2. IpcIoInit(&request, data, sizeof(data), 0);
  3. demoApi->Invoke(demoApi, 0, &request, NULL, NULL); ``` - 释放接口:

```

  1. int32 ref = demoApi->Release((IUnknown *)demoApi); ```

开发跨进程间服务调用客户端代理

  • 定义IPC接口客户端代理:

```

  1. typedef struct DemoClientProxy {
  2. INHERIT_CLIENT_IPROXY;
  3. BOOL (AsyncCall)(IUnknown iUnknown, const char *buff);
  4. BOOL (AsyncTimeCall)(IUnknown iUnknown);
  5. BOOL (SyncCall)(IUnknown iUnknown, struct Payload *payload);
  6. BOOL (AsyncCallBack)(IUnknown iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
  7. } DemoClientProxy;
  8. typedef struct DemoClientEntry {
  9. INHERIT_IUNKNOWNENTRY(DemoClientProxy);
  10. } DemoClientEntry; ``` - 实现客户端代理封装Ipc消息接口:

```

  1. static BOOL AsyncCall(IUnknown iUnknown, const char buff)
  2. {
  3. DemoClientProxy proxy = (DemoClientProxy )iUnknown;
  4. IpcIo request;
  5. char data[MAX_DATA_LEN];
  6. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
  7. IpcIoPushString(&request, buff);
  8. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
  9. return ret == EC_SUCCESS;
  10. }

  11. static BOOL AsyncTimeCall(IUnknown *iUnknown)

  12. {
  13. DemoClientProxy proxy = (DemoClientProxy )iUnknown;
  14. IpcIo request;
  15. char data[MAX_DATA_LEN];
  16. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
  17. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
  18. return ret == EC_SUCCESS;
  19. }

  20. static int Callback(IOwner owner, int code, IpcIo *reply)

  21. {
  22. size_t len = 0;
  23. return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
  24. }

  25. static BOOL SyncCall(IUnknown iUnknown, struct Payload payload)

  26. {
  27. DemoClientProxy proxy = (DemoClientProxy )iUnknown;
  28. IpcIo request;
  29. char data[MAX_DATA_LEN];
  30. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
  31. IpcIoPushInt32(&request, payload->id);
  32. IpcIoPushInt32(&request, payload->value);
  33. IpcIoPushString(&request, payload->name);
  34. int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
  35. data[MAX_DATA_LEN - 1] = 0;
  36. HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
  37. return ret == EC_SUCCESS;
  38. }

  39. struct CurrentNotify {

  40. IOwner notify;
  41. INotifyFunc handler;
  42. };

  43. static int CurrentCallback(IOwner owner, int code, IpcIo *reply)

  44. {
  45. struct CurrentNotify notify = (struct CurrentNotify )owner;
  46. size_t len = 0;
  47. char response = (char )IpcIoPopString(reply, &len);
  48. HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
  49. notify->handler(notify->notify, response);
  50. return EC_SUCCESS;
  51. }

  52. static BOOL AsyncCallBack(IUnknown iUnknown, const char buff, IOwner notify, INotifyFunc handler)

  53. {
  54. struct CurrentNotify owner = {notify, handler};
  55. DemoClientProxy proxy = (DemoClientProxy )iUnknown;
  56. IpcIo request;
  57. char data[MAX_DATA_LEN];
  58. IpcIoInit(&request, data, MAX_DATA_LEN, 0);
  59. IpcIoPushString(&request, buff);
  60. int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
  61. return ret == EC_SUCCESS;
  62. } ``` - 实现客户端代理的工厂方法:

```

  1. void DEMO_CreatClient(const char service, const char *feature, uint32 size)
  2. {
  3. (void)service;
  4. (void)feature;
  5. uint32 len = size + sizeof(DemoClientEntry);
  6. uint8 *client = malloc(len);
  7. (void)memset_s(client, len, 0, len);
  8. DemoClientEntry entry = (DemoClientEntry )&client[size];
  9. entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
  10. entry->ref = 1;
  11. entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
  12. entry->iUnknown.AddRef = IUNKNOWN_AddRef;
  13. entry->iUnknown.Release = IUNKNOWN_Release;
  14. entry->iUnknown.Invoke = NULL;
  15. entry->iUnknown.AsyncCall = AsyncCall;
  16. entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
  17. entry->iUnknown.SyncCall = SyncCall;
  18. entry->iUnknown.AsyncCallBack = AsyncCallBack;
  19. return client;
  20. }
  21. void DEMO_DestroyClient(const char service, const char feature, void *iproxy)
  22. {
  23. free(iproxy);
  24. } ``` - 将客户端代理的工厂方法注册到SAMGR:

```

  1. SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient); ``` - 获取跨进程服务的对外接口:

```

  1. DemoClientProxy *demoApi = NULL;
  2. IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
  3. if (iUnknown == NULL) {
  4. return NULL;
  5. }
  6. int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
  7. if (result != 0 || demoApi == NULL) {
  8. return NULL;
  9. } ``` - 调用跨进程服务的客户端代理接口:

```

  1. if (demoApi->AsyncCallBack == NULL) {
  2. return NULL;
  3. }
  4. demoApi->AsyncCallBack((IUnknown *)demoApi,
  5. "I wanna async call callback good result!", NULL, AsyncHandler); ``` - 释放接口:

```

  1. int32 ref = demoApi->Release((IUnknown *)demoApi); ```

涉及仓

distributedschedule_interfaces_innerkits_samgr_lite

distributedschedule_services_samgr_lite