HarmonyOS 鸿蒙驱动消息机制管理

219 阅读4分钟

驱动消息机制管理

使用场景

当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。

接口说明

消息机制的功能主要有以下两种:

  1. 用户态应用发送消息到驱动。
  2. 用户态应用接收驱动主动上报事件。

表1 消息机制接口

方法描述
struct HdfIoService HdfIoServiceBind(const char serviceName);用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。
void HdfIoServiceRecycle(struct HdfIoService *service);释放驱动服务。
int HdfDeviceRegisterEventListener(struct HdfIoService target, struct HdfDevEventlistener listener);用户态程序注册接收驱动上报事件的操作方法。
int HdfDeviceSendEvent(struct HdfDeviceObject deviceObject, uint32_t id, struct HdfSBuf data);驱动主动上报事件接口。

开发步骤

1.将驱动配置信息中服务策略policy字段设置为2(SERVICE_POLICY_CAPACITY,参考policy定义)。

   device_sample :: Device {
       policy = 2;
       ...
   }

2.配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。

3.在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。

   // Dispatch是用来处理用户态发下来的消息
   int32_t SampleDriverDispatch(struct HdfDeviceIoClient *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
   {
       HDF_LOGI("sample driver lite A dispatch");
       return HDF_SUCCESS;
   }
   int32_t SampleDriverBind(struct HdfDeviceObject *device)
   {
       HDF_LOGI("test for lite os sample driver A Open!");
       if (device == NULL) {
           HDF_LOGE("test for lite os sample driver A Open failed!");
           return HDF_FAILURE;
       }
       static struct ISampleDriverService sampleDriverA = {
           .ioService.Dispatch = SampleDriverDispatch,
           .ServiceA = SampleDriverServiceA,
           .ServiceB = SampleDriverServiceB,
       };
       device->service = (struct IDeviceIoService *)(&sampleDriverA);
       return HDF_SUCCESS;
   }

4.驱动定义消息处理函数中的cmd类型。

   #define SAMPLE_WRITE_READ 1    // 读写操作码1

4.用户态获取服务接口并发送消息到驱动。

   int SendMsg(const char *testMsg)
   {
       if (testMsg == NULL) {
           HDF_LOGE("test msg is null");
           return HDF_FAILURE;
       }
       struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
       if (serv == NULL) {
           HDF_LOGE("fail to get service");
           return HDF_FAILURE;
       }
       struct HdfSBuf *data = HdfSbufObtainDefaultSize();
       if (data == NULL) {
           HDF_LOGE("fail to obtain sbuf data");
           return HDF_FAILURE;
       }
       struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
       if (reply == NULL) {
           HDF_LOGE("fail to obtain sbuf reply");
           ret = HDF_DEV_ERR_NO_MEMORY;
           goto out;
       }
       if (!HdfSbufWriteString(data, testMsg)) {
           HDF_LOGE("fail to write sbuf");
           ret = HDF_FAILURE;
           goto out;
       }
       int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
       if (ret != HDF_SUCCESS) {
           HDF_LOGE("fail to send service call");
           goto out;
       }
   out:
       HdfSbufRecycle(data);
       HdfSbbufRecycle(reply);
       HdfIoServiceRecycle(serv);
       return ret;
   }

6.用户态接收该驱动上报的消息。

  • 用户态编写驱动上报消息的处理函数。
       static int OnDevEventReceived(void *priv,  uint32_t id, struct HdfSBuf *data)
       {
           OsalTimespec time;
           OsalGetTime(&time);
           HDF_LOGI("%{public}s received event at %{public}llu.%{public}llu", (char *)priv, time.sec, time.usec);

           const char *string = HdfSbufReadString(data);
           if (string == NULL) {
               HDF_LOGE("fail to read string in event data");
               return HDF_FAILURE;
           }
           HDF_LOGI("%{public}s: dev event received: %{public}d %{public}s",  (char *)priv, id, string);
           return HDF_SUCCESS;
       }
  • 用户态注册接收驱动上报消息的操作方法。
       int RegisterListen()
       {
           struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
           if (serv == NULL) {
               HDF_LOGE("fail to get service");
               return HDF_FAILURE;
           }
           static struct HdfDevEventlistener listener = {
               .callBack = OnDevEventReceived,
               .priv ="Service0"
           };
           if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
               HDF_LOGE("fail to register event listener");
               return HDF_FAILURE;
           }
           ......
           HdfDeviceUnregisterEventListener(serv, &listener);
           HdfIoServiceRecycle(serv);
           return HDF_SUCCESS;
       }
  • 驱动上报事件。
       int32_t SampleDriverDispatch(HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
       {
           ... // process api call here
           return HdfDeviceSendEvent(client->device, cmdCode, data);
       }

最后分享一份鸿蒙(HarmonyOS)开发学习指南需要的可以

关注VX公众号:Android 老皮

《鸿蒙(HarmonyOS)开发学习指南》

第一章 快速入门

1、开发准备

2、构建第一个ArkTS应用(Stage模型)

3、构建第一个ArkTS应用(FA模型)

4、构建第一个JS应用(FA模型)

5、........

图片

第二章 开发基础知识

1、应用程序包基础知识

2、应用配置文件(Stage模型)

3、应用配置文件概述(FA模型)

4、.......

图片

第三章 资源分类与访问

1、 资源分类与访问

2、 创建资源目录和资源文件

3、 资源访问

4、.......

图片

第四章 学习ArkTs语言

1、初识ArkTS语言

2、基本语法

3、状态管理

4、其他状态管理

5、渲染控制

6、......

图片

第五章 UI开发

1.方舟开发框架(ArkUI)概述

2.基于ArkTS声明式开发范式

3.兼容JS的类Web开发范式

4.......

图片

第六章 Web开发

1.Web组件概述

2.使用Web组件加载页面

3.设置基本属性和事件

4.在应用中使用前端页面JavaScript

5.ArkTS语言基础类库概述

6.并发

7.......

图片

11.网络与连接

12.电话服务

13.数据管理

14.文件管理

15.后台任务管理

16.设备管理

17......

图片

第七章 应用模型

1.应用模型概述

2.Stage模型开发指导

3.FA模型开发指导

4.......

图片