1# 驱动消息机制管理<a name="ZH-CN_TOPIC_0000001052657065"></a> 2 3- [使用场景](#section33014541954) 4- [接口说明](#section538852311616) 5- [开发步骤](#section946912121153) 6 7## 使用场景<a name="section33014541954"></a> 8 9当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。 10 11## 接口说明<a name="section538852311616"></a> 12 13消息机制的功能主要有以下两种: 14 151. 用户态应用发送消息到驱动。 162. 用户态应用接收驱动主动上报事件。 17 18**表 1** 消息机制接口 19 20<a name="table208212674114"></a> 21<table><thead align="left"><tr id="row08282618416"><th class="cellrowborder" valign="top" width="46.379999999999995%" id="mcps1.2.3.1.1"><p id="p382132664112"><a name="p382132664112"></a><a name="p382132664112"></a>方法</p> 22</th> 23<th class="cellrowborder" valign="top" width="53.620000000000005%" id="mcps1.2.3.1.2"><p id="p4826264419"><a name="p4826264419"></a><a name="p4826264419"></a>描述</p> 24</th> 25</tr> 26</thead> 27<tbody><tr id="row1582426174114"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p182341916144420"><a name="p182341916144420"></a><a name="p182341916144420"></a>struct HdfIoService *HdfIoServiceBind(const char *serviceName)</p> 28</td> 29<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p58272614113"><a name="p58272614113"></a><a name="p58272614113"></a>用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。</p> 30</td> 31</tr> 32<tr id="row578565084913"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p15786185024918"><a name="p15786185024918"></a><a name="p15786185024918"></a>void HdfIoServiceRecycle(struct HdfIoService *service);</p> 33</td> 34<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p47861750154912"><a name="p47861750154912"></a><a name="p47861750154912"></a>释放驱动服务。</p> 35</td> 36</tr> 37<tr id="row1382112617413"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p482182611415"><a name="p482182611415"></a><a name="p482182611415"></a>int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);</p> 38</td> 39<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p18825261412"><a name="p18825261412"></a><a name="p18825261412"></a>用户态程序注册接收驱动上报事件的操作方法。</p> 40</td> 41</tr> 42<tr id="row498956124019"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p6412911184019"><a name="p6412911184019"></a><a name="p6412911184019"></a>int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);</p> 43</td> 44<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p1698915634018"><a name="p1698915634018"></a><a name="p1698915634018"></a>驱动主动上报事件接口。</p> 45</td> 46</tr> 47</tbody> 48</table> 49 50## 开发步骤<a name="section946912121153"></a> 51 521. 将驱动配置信息中服务策略policy字段设置为2(SERVICE\_POLICY\_CAPACITY,参考[policy定义](driver-hdf-servicemanage.md))。 53 54 ``` 55 device_sample :: Device { 56 policy = 2; 57 ... 58 } 59 ``` 60 612. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。 623. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。 63 64 ``` 65 // Dispatch是用来处理用户态发下来的消息 66 int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) 67 { 68 HDF_LOGE("sample driver lite A dispatch"); 69 return 0; 70 } 71 int32_t SampleDriverBind(struct HdfDeviceObject *device) 72 { 73 HDF_LOGE("test for lite os sample driver A Open!"); 74 if (device == NULL) { 75 HDF_LOGE("test for lite os sample driver A Open failed!"); 76 return -1; 77 } 78 static struct ISampleDriverService sampleDriverA = { 79 .ioService.Dispatch = SampleDriverDispatch, 80 .ServiceA = SampleDriverServiceA, 81 .ServiceB = SampleDriverServiceB, 82 }; 83 device->service = (struct IDeviceIoService *)(&sampleDriverA); 84 return 0; 85 } 86 ``` 87 884. 驱动定义消息处理函数中的cmd类型。 89 90 ``` 91 #define SAMPLE_WRITE_READ 1 // 读写操作码1 92 ``` 93 945. 用户态获取服务接口并发送消息到驱动。 95 96 ``` 97 int SendMsg(const char *testMsg) 98 { 99 if (testMsg == NULL) { 100 HDF_LOGE("test msg is null"); 101 return -1; 102 } 103 struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 104 if (serv == NULL) { 105 HDF_LOGE("fail to get service"); 106 return -1; 107 } 108 struct HdfSBuf *data = HdfSBufObtainDefaultSize(); 109 if (data == NULL) { 110 HDF_LOGE("fail to obtain sbuf data"); 111 return -1; 112 } 113 struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); 114 if (reply == NULL) { 115 HDF_LOGE("fail to obtain sbuf reply"); 116 ret = HDF_DEV_ERR_NO_MEMORY; 117 goto out; 118 } 119 if (!HdfSbufWriteString(data, testMsg)) { 120 HDF_LOGE("fail to write sbuf"); 121 ret = HDF_FAILURE; 122 goto out; 123 } 124 int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); 125 if (ret != HDF_SUCCESS) { 126 HDF_LOGE("fail to send service call"); 127 goto out; 128 } 129 out: 130 HdfSBufRecycle(data); 131 HdfSBufRecycle(reply); 132 HdfIoServiceRecycle(serv); 133 return ret; 134 } 135 ``` 136 1376. 用户态接收该驱动上报的消息。 138 1. 用户态编写驱动上报消息的处理函数。 139 140 ``` 141 static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) 142 { 143 OsalTimespec time; 144 OsalGetTime(&time); 145 HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); 146 147 const char *string = HdfSbufReadString(data); 148 if (string == NULL) { 149 HDF_LOGE("fail to read string in event data"); 150 return -1; 151 } 152 HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); 153 return 0; 154 } 155 ``` 156 157 2. 用户态注册接收驱动上报消息的操作方法。 158 159 ``` 160 int RegisterListen() 161 { 162 struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 163 if (serv == NULL) { 164 HDF_LOGE("fail to get service"); 165 return -1; 166 } 167 static struct HdfDevEventlistener listener = { 168 .callBack = OnDevEventReceived, 169 .priv ="Service0" 170 }; 171 if (HdfDeviceRegisterEventListener(serv, &listener) != 0) { 172 HDF_LOGE("fail to register event listener"); 173 return -1; 174 } 175 ...... 176 HdfDeviceUnregisterEventListener(serv, &listener); 177 HdfIoServiceRecycle(serv); 178 return 0; 179 } 180 ``` 181 182 3. 驱动上报事件。 183 184 ``` 185 int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) 186 { 187 ... // process api call here 188 return HdfDeviceSendEvent(deviceObject, cmdCode, data); 189 } 190 ``` 191 192 193 194