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