• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 驱动消息机制管理
2
3
4## 使用场景
5
6当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。
7
8
9## 接口说明
10
11消息机制的功能主要有以下两种:
12
131. 用户态应用发送消息到驱动。
14
152. 用户态应用接收驱动主动上报事件。
16
17  **表1** 消息机制接口
18
19| 方法 | 描述 |
20| -------- | -------- |
21| struct HdfIoService \*HdfIoServiceBind(const char \*serviceName); | 用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。 |
22| void HdfIoServiceRecycle(struct HdfIoService \*service); | 释放驱动服务。 |
23| int HdfDeviceRegisterEventListener(struct HdfIoService \*target, struct HdfDevEventlistener \*listener); | 用户态程序注册接收驱动上报事件的操作方法。 |
24| int HdfDeviceSendEvent(struct HdfDeviceObject \*deviceObject, uint32_t id, struct HdfSBuf \*data); | 驱动主动上报事件接口。 |
25
26
27## 开发步骤
28
291. 将驱动配置信息中服务策略policy字段设置为2(SERVICE_POLICY_CAPACITY,参考[policy定义](../driver/driver-hdf-servicemanage.md))。
30
31   ```
32   device_sample :: Device {
33       policy = 2;
34       ...
35   }
36   ```
37
382. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。
39
403. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。
41
42   ```c
43   // Dispatch是用来处理用户态发下来的消息
44   int32_t SampleDriverDispatch(struct HdfDeviceIoClient *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
45   {
46       HDF_LOGI("sample driver lite A dispatch");
47       return HDF_SUCCESS;
48   }
49   int32_t SampleDriverBind(struct HdfDeviceObject *device)
50   {
51       HDF_LOGI("test for lite os sample driver A Open!");
52       if (device == NULL) {
53           HDF_LOGE("test for lite os sample driver A Open failed!");
54           return HDF_FAILURE;
55       }
56       static struct ISampleDriverService sampleDriverA = {
57           .ioService.Dispatch = SampleDriverDispatch,
58           .ServiceA = SampleDriverServiceA,
59           .ServiceB = SampleDriverServiceB,
60       };
61       device->service = (struct IDeviceIoService *)(&sampleDriverA);
62       return HDF_SUCCESS;
63   }
64   ```
65
664. 驱动定义消息处理函数中的cmd类型。
67
68   ```c
69   #define SAMPLE_WRITE_READ 1    // 读写操作码1
70   ```
71
725. 用户态获取服务接口并发送消息到驱动。
73
74   ```c
75   int SendMsg(const char *testMsg)
76   {
77       if (testMsg == NULL) {
78           HDF_LOGE("test msg is null");
79           return HDF_FAILURE;
80       }
81       struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
82       if (serv == NULL) {
83           HDF_LOGE("fail to get service");
84           return HDF_FAILURE;
85       }
86       struct HdfSBuf *data = HdfSbufObtainDefaultSize();
87       if (data == NULL) {
88           HDF_LOGE("fail to obtain sbuf data");
89           return HDF_FAILURE;
90       }
91       struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
92       if (reply == NULL) {
93           HDF_LOGE("fail to obtain sbuf reply");
94           ret = HDF_DEV_ERR_NO_MEMORY;
95           goto out;
96       }
97       if (!HdfSbufWriteString(data, testMsg)) {
98           HDF_LOGE("fail to write sbuf");
99           ret = HDF_FAILURE;
100           goto out;
101       }
102       int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
103       if (ret != HDF_SUCCESS) {
104           HDF_LOGE("fail to send service call");
105           goto out;
106       }
107   out:
108       HdfSbufRecycle(data);
109       HdfSbbufRecycle(reply);
110       HdfIoServiceRecycle(serv);
111       return ret;
112   }
113   ```
114
1156. 用户态接收该驱动上报的消息。
116   1. 用户态编写驱动上报消息的处理函数。
117
118       ```c
119       static int OnDevEventReceived(void *priv,  uint32_t id, struct HdfSBuf *data)
120       {
121           OsalTimespec time;
122           OsalGetTime(&time);
123           HDF_LOGI("%{public}s received event at %{public}llu.%{public}llu", (char *)priv, time.sec, time.usec);
124
125           const char *string = HdfSbufReadString(data);
126           if (string == NULL) {
127               HDF_LOGE("fail to read string in event data");
128               return HDF_FAILURE;
129           }
130           HDF_LOGI("%{public}s: dev event received: %{public}d %{public}s",  (char *)priv, id, string);
131           return HDF_SUCCESS;
132       }
133       ```
134   2. 用户态注册接收驱动上报消息的操作方法。
135
136       ```c
137       int RegisterListen()
138       {
139           struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
140           if (serv == NULL) {
141               HDF_LOGE("fail to get service");
142               return HDF_FAILURE;
143           }
144           static struct HdfDevEventlistener listener = {
145               .callBack = OnDevEventReceived,
146               .priv ="Service0"
147           };
148           if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
149               HDF_LOGE("fail to register event listener");
150               return HDF_FAILURE;
151           }
152           ......
153           HdfDeviceUnregisterEventListener(serv, &listener);
154           HdfIoServiceRecycle(serv);
155           return HDF_SUCCESS;
156       }
157       ```
158   3. 驱动上报事件。
159
160       ```c
161       int32_t SampleDriverDispatch(HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
162       {
163           ... // process api call here
164           return HdfDeviceSendEvent(client->device, cmdCode, data);
165       }
166       ```
167