中铁建设中南公司官方网站重庆网站推广产品
web/
2025/10/3 4:33:55/
文章来源:
中铁建设中南公司官方网站,重庆网站推广产品,ui设计尺寸规范,关于建设网站的合作合同范本鸿蒙linux内核的L1设备服务开发详解
鸿蒙基于linux内核的L1设备的系统基于面向服务架构#xff0c;提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。
一、简介
在L1设备…鸿蒙linux内核的L1设备服务开发详解
鸿蒙基于linux内核的L1设备的系统基于面向服务架构提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务进程、进程间服务调用的开发能力。现对此基座下的服务进行剖析并以实例方式进行讲解。
一、简介
在L1设备中服务分为两类 core system service foundation\systemabilitymgr\safwk_lite\BUILD.gn deps添加依赖由foundation进程启动加载。此种方式的服务挂载在foundation进程中。 system and application service
以应用的方式进行启动可以在/base/startup/init/service/etc/init.cfg中添加start service方式启动或者以可执行程序的方式进行启动。此种方式的服务是以本身的进程启动。
二、服务的开发
首先SA服务包含两部份:服务端、子功能端服务提供了子功能的接口有默认的接口和自定义子功能接口子功能接口又包含了进程内接口与进程间接口。后续章节会一一进行说明。
2.1 服务端实现
2.1.1 服务声明
#include service.h
#include message.h
#include common.htypedef struct ExampleService {INHERIT_SERVICE;Identity identity;
} ExampleService;INHERIT_SERVICE在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\service.h中定义如下
#define INHERIT_SERVICE \const char *(*GetName)(Service * service); \BOOL (*Initialize)(Service * service, Identity identity); \BOOL (*MessageHandle)(Service * service, Request * request); \TaskConfig (*GetTaskConfig)(Service * service)该宏定义了服务的生命周期函数的函数指针。
Identity在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\message.h中定义如下
struct Identity {/** Service ID */int16 serviceId;/** Feature ID */int16 featureId;/** Message queue ID */MQueueId queueId;
};该宏定义了服务ID、默认子功能ID及消息队列ID。
MQueueId定义在foundation\industrialbus\modules\common.h
typedef void *MQueueId;关于默认子功能及消息队列指针此处按下不表在相应部份再进行说明此时服务结构定义只需要添加两个宏即可。
2.1.2 实现服务的生命周期函数
实现该服务对象指向的生命周期函数。
服务生命周期函数实现示例如下
#define EXAMPLE_SERVICE moduleservice
// 返回服务名称
static const char *GetName(Service *service)
{(void)service;return EXAMPLE_SERVICE;
}
// 初始化服务
static BOOL Initialize(Service *service, Identity identity)
{ExampleService *example (ExampleService *)service;// 保存服务的唯一身份标识用来自己的IUnknown接口对服务发消息时使用。example-identity identity;return TRUE;
}
static BOOL MessageHandle(Service *service, Request *msg)
{ExampleService *example (ExampleService *)service;(void)example;switch (msg-msgId) {default:break;}return FALSE;
}
static TaskConfig GetTaskConfig(Service *service)
{(void)service;TaskConfig config {LEVEL_HIGH, PRI_NORMAL,0x800, MODULE_QUEUE_SIZE, SINGLE_TASK};return config;
}2.1.3 创建服务对象
实例化ExampleService服务对象将对象的生命函数指针指向其实现其实现的生命周期函数。
// 创建服务对象
static ExampleService g_example {.GetName GetName,.Initialize Initialize,.MessageHandle MessageHandle,.GetTaskConfig GetTaskConfig,{-1, -1, NULL}
};identity初始化时serviceId,featureId均为-1queueId为空在生命周期函数Initialize中赋值系统分配的identity。
2.1.4 注册服务
向SAMGR注册服务及接口
static void Init(void)
{SAMGR_GetInstance()-RegisterService((Service *)g_example);
}定义服务的初始化入口
SYSEX_SERVICE_INIT(Init);2.2 子功能端
通过以上操作后服务驻存在系统中服务没有对外的接口此时需要添加子功能feature提供服务对外的接口。
子功能按分为两类进程内子功能、跨进程子功能
2.2.1 定义子功能
子功能按通信方式分为两类进程内子功能、跨进程子功能。
子功能还可以分为服务默认子功能与自定义子功能。
默认子功能不需要子功能生命周期,其生命周期由服务的生命周期管理。
2.2.1.1 进程内子功能接口
#include iunknown.h
typedef struct {INHERIT_IUNKNOWN;BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} DefaultFeatureApi;2.2.1.2 跨进程子功能接口
#include iproxy_server.h
typedef struct {INHERIT_SERVER_IPROXY;BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} CrossProcessFeatureApi;进程内子功能与跨进程子功能的声明表现在使用两个宏INHERIT_IUNKNOWN与INHERIT_SERVER_IPROXY
INHERIT_IUNKNOWN定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define INHERIT_IUNKNOWN \int (*QueryInterface)(IUnknown *iUnknown, int version, void **target); \int (*AddRef)(IUnknown *iUnknown); \int (*Release)(IUnknown *iUnknown)INHERIT_SERVER_IPROXY定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define INHERIT_SERVER_IPROXY \INHERIT_IUNKNOWN; \int32 (*Invoke)(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)跨进程feature的定义相对进程内定义多出来的Invoke函数指针跨进程的方法通过此方法完成进程间通信、参数序列化与反序列化。
2.2.1.3 默认子功能
默认子功能需要将声明放在服务结构中进行声明。
以2.1.1中声明的服务为例只需要将DefaultFeatureApi或CrossProcessFeatureApi添加至服务ExampleService中。
默认进程内子功能
// 默认进程内子功能
typedef struct ExampleService {INHERIT_SERVICE;INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);Identity identity;
} ExampleService;默认跨进程子功能
// 自定义跨进程子功能
typedef struct ExampleService {INHERIT_SERVICE;INHERIT_IUNKNOWNENTRY(CrossProcessFeatureApi);Identity identity;
} ExampleService;INHERIT_IUNKNOWNENTRY宏添加了子功能的版本也引用计数定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define INHERIT_IUNKNOWNENTRY(T) \uint16 ver; \int16 ref; \T iUnknown2.2.1.4 自定义子功能
首先自定义子功能结构然后定义子功能接口ExampleFeatureApi子功能接口也分为进程间接口与跨进程接口。
// 定义子功能结构
typedef struct ExampleFeature {INHERIT_FEATURE;INHERIT_IUNKNOWNENTRY(ExampleFeatureApi);Identity identity;
} ExampleFeature;进程间子功能接口定义
#include iunknown.h
typedef struct {INHERIT_IUNKNOWN;BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} ExampleFeatureApi;跨进程子功能接口定义
#include iproxy_server.h
typedef struct {INHERIT_SERVER_IPROXY;BOOL (*FeatureCall)(IUnknown *iUnknown, const char *buff);
} ExampleFeatureApi;INHERIT_FEATURE定义在foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\feature.h
#define INHERIT_FEATURE \
const char *(*GetName)(Feature *feature); \
void (*OnInitialize)(Feature *feature, Service *parent, Identity identity); \
void (*OnStop)(Feature *feature, Identity identity); \
BOOL (*OnMessage)(Feature *feature, Request *request); \
BOOL (*IsDistributed)(void)该宏定义了子功能的生命周期函数的函数指针。
2.2.2 服务子功能实现
进程间子功能接口实现
static BOOL FeatureCall(IUnknown *iUnknown, const char *buff)
{(void)iUnknown;HILOG_INFO(1,buff:%s\n, buff);HILOG_INFO(1,[LPC Test][SyncCall API] Default Success!\n);return TRUE;
}跨进程子功能接口实现
enum MessageId {MSG_PROC,MSG_TIME_PROC,
};
static BOOL FeatureCall(IUnknown *iUnknown, const char *body)
{Request request {.msgId MSG_PROC, .msgValue 0};request.len (uint32_t)(strlen(body) 1);request.data malloc(request.len);if (request.data NULL) {return FALSE;}if (strcpy_s(request.data, request.len, body) ! EOK) {free(request.data);return FALSE;}ExampleFeature *feature GET_OBJECT(iUnknown, ExampleFeature, iUnknown);return SAMGR_SendRequest(g_example.identity, request, NULL);
}FeatureCall由跨进程方法Invoke调用然后子功能通过SAMGR_SendRequest发送请求至内核。
2.2.2 实现子功能的生命周期函数
默认子功能不需要子功能生命周期,实现子功能对象指向的生命周期函数。
子功能生命周期函数实现示例如下
#define EXAMPLE_FEATURE modulefeature
enum MessageId {MSG_PROC,MSG_TIME_PROC,
};
static const char *FEATURE_GetName(Feature *feature)
{(void)feature;return EXAMPLE_FEATURE;
}
static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
{ExampleFeature *demoFeature (ExampleFeature *)feature;demoFeature-identity identity;printf(serviceId:%d,featureId:%d,queueId:%p\n, identity.serviceId, identity.featureId, identity.queueId);printf(demoFeature:%p,g_example:%p\n, demoFeature, g_example);printf(serviceId:%d,featureId:%d,queueId:%p\n,g_example.identity.serviceId, g_example.identity.featureId, g_example.identity.queueId);
}
static void FEATURE_OnStop(Feature *feature, Identity identity)
{(void)feature;(void)identity;g_example.identity.queueId NULL;g_example.identity.featureId -1;g_example.identity.serviceId -1;
}
static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
{(void)feature;if (request-msgId MSG_PROC) {printf([LPC Test][OnMessage: S:%s, F:%s] msgIdMSG_PROC %s \n,EXAMPLE_SERVICE, feature-GetName(feature),(char *)request-data);Response response {.data Yes, you did!, .len 0};SAMGR_SendResponse(request, response);return TRUE;} else {if (request-msgId MSG_TIME_PROC) {printf([LPC Test] OnMessage: S:%s, F:%s] Time Message Get Value%s!,EXAMPLE_SERVICE, feature-GetName(feature),request-msgValue ? TRUE : FALSE);// AsyncTimeCall(GET_IUNKNOWN(g_example));return FALSE;}}printf([LPC Test][OnMessage S:%s, F:%s] Inner Error! \n,EXAMPLE_SERVICE, feature-GetName(feature));return FALSE;
}FEATURE_OnMessage处理异步处理应答的消息。
2.2.3 创建功能对象
创建进程内通信子功能对象
static ExampleFeature g_example {.GetName FEATURE_GetName,.OnInitialize FEATURE_OnInitialize,.OnStop FEATURE_OnStop,.OnMessage FEATURE_OnMessage,DEFAULT_IUNKNOWN_ENTRY_BEGIN,.FeatureCall FeatureCall,DEFAULT_IUNKNOWN_ENTRY_END,.identity {-1, -1, NULL},
};创建跨进程通信子功能对象
static ExampleFeature g_example {.GetName FEATURE_GetName,.OnInitialize FEATURE_OnInitialize,.OnStop FEATURE_OnStop,.OnMessage FEATURE_OnMessage,SERVER_IPROXY_IMPL_BEGIN,..Invoke Invoke,.FeatureCall FeatureCall,IPROXY_END,.identity {-1, -1, NULL},
};DEFAULT_IUNKNOWN_ENTRY_BEGIN…DEFAULT_IUNKNOWN_ENTRY_END
// foundation\systemabilitymgr\samgr_lite\interfaces\kits\samgr\iunknown.h
#define DEFAULT_VERSION 0x20
#define DEFAULT_IUNKNOWN_IMPL \.QueryInterface IUNKNOWN_QueryInterface, \.AddRef IUNKNOWN_AddRef, \.Release IUNKNOWN_Release#define IUNKNOWN_ENTRY_BEGIN(version) \.ver (version), \.ref 1, \.iUnknown { \DEFAULT_IUNKNOWN_IMPL#define DEFAULT_IUNKNOWN_ENTRY_BEGIN IUNKNOWN_ENTRY_BEGIN(DEFAULT_VERSION)#define DEFAULT_IUNKNOWN_ENTRY_END IUNKNOWN_ENTRY_END此宏表示实现接口查询与引用计数方法使用系统实现的IUNKNOWN_QueryInterface、IUNKNOWN_AddRef、IUNKNOWN_Release三个方法。
SERVER_IPROXY_IMPL_BEGIN…IPROXY_END
// foundation\systemabilitymgr\samgr_lite\interfaces\kits\registry\iproxy_server.h
#define SERVER_PROXY_VER 0x80
#define SERVER_IMPL_PROXY_VER ((uint16)SERVER_PROXY_VER | (uint16)DEFAULT_VERSION)#define SERVER_IPROXY_IMPL_BEGIN IUNKNOWN_ENTRY_BEGIN(SERVER_IMPL_PROXY_VER)#define IPROXY_END IUNKNOWN_ENTRY_END此宏表示实现接口查询与引用计数方法使用系统实现的IUNKNOWN_QueryInterface、IUNKNOWN_AddRef、IUNKNOWN_Release三个方法。
两个宏校验的版本号不同。
在跨进程子功能中需要实现Invoke接口。
typedef enum {FEATURE_CALL,MY_MODULE_ASYNC_CALLBACK,
} MyModuleMsgID;static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{ExampleFeatureApi *api (ExampleFeatureApi *)iProxy;ExampleFeature *feature GET_OBJECT(api, ExampleFeature, iUnknown);printf(xxxxxxxxxxxxxxxxxxxxxxxxxxx api:%p,g_example:%p,feature:%p\n, api, g_example, feature);BOOL ret;size_t tempLen 0;size_t len 0;switch (funcId) {case FEATURE_CALL:buf ReadString(req, tempLen);printf([feature] tempLen:%u\n, tempLen);printf([feature] req: %s\n, buf);break;default:WriteBool(reply, FALSE);break;}return 0;
}2.2.4 注册子功能
默认子功能
默认子功能的注册在服务注册之后。
static void Init(void)
{SAMGR_GetInstance()-RegisterService((Service *)g_example);SAMGR_GetInstance()-RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
}SYSEX_SERVICE_INIT(Init);自定义子功能
static void Init(void)
{SAMGR_GetInstance()-RegisterFeature(EXAMPLE_SERVICE, (Feature *)g_example);SAMGR_GetInstance()-RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));printf([Register Test][Reg S:%s, F:%s]!\n,EXAMPLE_SERVICE, EXAMPLE_FEATURE);
}SYSEX_FEATURE_INIT(Init);2.2.5 服务与子功能权限
修改文件base\security\permission_lite\services\ipc_auth\include\policy_preset.h
FeaturePolicy mymoduleFeature[] {{modulefeature,{{.type RANGE,.uidMin 0,.uidMax __INT_MAX__,},},},
};
// 在g_presetPolicies[]里面增加{moduleservice, mymoduleFeature, 1},注意服务名“moduleservice与子功能名modulefeature”长度最长15个字节。
2.2 服务调用
2.2.1 进程内调用
#include iunknown.h
static DefaultFeatureApi *g_defaultProxy;
IUnknown *iUnknown1 SAMGR_GetInstance()-GetDefaultFeatureApi(EXAMPLE_SERVICE);
if (iUnknown1 NULL) {return -1;
}
int32_t ret iUnknown1-QueryInterface(iUnknown1, DEFAULT_VERSION, (void **)g_defaultProxy);
if (ret ! 0 || g_defaultProxy NULL) {return -1;
}
ret g_defaultProxy-FeatureCall((IUnknown *)g_defaultProxy, Hi L1 first SA);
if (ret ! 0) {return -1;
}
ret g_defaultProxy-Release((IUnknown *)g_defaultProxy);2.2.2 跨进程调用
#include iunknown.htypedef struct {int result;size_t messageLen;uint8_t *message;
} ServiceRspMsg;
static CrossProcessFeatureApi *g_clientProxy;IUnknown *iUnknown2 SAMGR_GetInstance()-GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown2 NULL) {return -1;
}
int32_t ret iUnknown2-QueryInterface(iUnknown2, CLIENT_PROXY_VER, (void **)g_clientProxy);
if (ret ! 0 || g_clientProxy NULL) {return -1;
}
IpcIo request;
char data[250];
IpcIoInit(request, data, sizeof(data), 0);
WriteString(request, I want to async call good result!);
ServiceRspMsg reply { 0 };
ret g_clientProxy-Invoke((IUnknown *)g_clientProxy, FEATURE_CALL, request, NULL, NULL);
if (ret ! EXAMPLE_SUCCESS) {printf([AsyncCall] ret:%d\n\r, ret);
}
if (ret ! 0) {return -1;
}
ret g_clientProxy-Release((IUnknown *)g_defaultProxy);执行步骤g_clientProxy-Invoke----------异步FeatureCall方法----------SAMGR_SendRequest----------FEATURE_OnMessage----------(IPCRPC)----------服务Invoke
2.3 参数序列化
// 序列化
IpcIo request;
char data[250];
IpcIoInit(request, data, sizeof(data), 0);
WriteString(request, I want to async call good result!);
// 反序列化
buf ReadString(req, tempLen);2.4 跨进程回调函数调用
首先调用方定义回调函数指针与回调方法实现
typedef int (*AsyncHandlerFunc)(IOwner owner, int code);static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
{struct CurrentNotify *notify (struct CurrentNotify *)owner;int32_t ret;ReadUint32(reply, ret);printf(CurrentCallback................ %d\n, ret);notify-handler(notify-data, ret);return 0;
}
struct CurrentNotify {IOwner data;AsyncHandlerFunc handler;
};
......
ReplyData dataReply;
dataReply.id 55;
IOwner notify dataReply; //自定义结构体
struct CurrentNotify customData {.data notify, .handle AsyncHandler
};
ret g_clientProxy-Invoke((IUnknown *)g_clientProxy, MY_MODULE_ASYNC_CALLBACK, request, customData, CurrentCallback);
if (ret ! 0) {printf([AsyncCallBack] ret:%d\n\r, ret);
}实现子功能的回调接口
static BOOL AsyncCallBack(IUnknown *iUnknown, const char *body, Handler handler)
{Request request {.msgId MSG_PROC, .msgValue 0};request.len (uint32_t)(strlen(body) 1);request.data malloc(request.len);if (request.data NULL) {return FALSE;}if (strcpy_s(request.data, request.len, body) ! EOK) {free(request.data);return FALSE;}// ExampleFeature *feature GET_OBJECT(iUnknown, ExampleFeature, iUnknown);printf([LPC Test][AsyncCallBack API] Send request! \n);return SAMGR_SendRequest(g_example.identity, request, handler);
}Invoke反序列化结果
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{ExampleFeatureApi *api (ExampleFeatureApi *)iProxy;ExampleFeature *feature GET_OBJECT(api, ExampleFeature, iUnknown);printf(xxxxxxxxxxxxxxxxxxxxxxxxxxx api:%p,g_example:%p,feature:%p\n, api, g_example, feature);BOOL ret;size_t tempLen 0;uint8_t *buf NULL;switch (funcId) {case FEATURE_CALL:buf ReadString(req, tempLen);printf([feature] tempLen:%u\n, tempLen);printf([feature] req: %s\n, buf);break;case MY_MODULE_ASYNC_CALLBACK: { // convert to sync proxybuf ReadString(req, tempLen);printf(xxxxxxxxxxxxxxxxxxxxxxxxxxx buf:%s\n, buf);WriteUint32(reply, 1);break;default:WriteBool(reply, FALSE);break;}return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86016.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!