1# HDF Development Example 2 3 4The following is a HDF-based driver development example. 5 6 7## Adding Driver Configuration 8 9Add the driver configuration to the HDF configuration file, for example, **vendor/hisilicon/xxx/hdf_config/device_info**. 10 11 12``` 13root { 14 device_info { 15 match_attr = "hdf_manager"; 16 template host { 17 hostName = ""; 18 priority = 100; 19 template device { 20 template deviceNode { 21 policy = 0; 22 priority = 100; 23 preload = 0; 24 permission = 0664; 25 moduleName = ""; 26 serviceName = ""; 27 deviceMatchAttr = ""; 28 } 29 } 30 } 31 sample_host :: host { 32 hostName = "sample_host"; 33 sample_device :: device { 34 device0 :: deviceNode { 35 policy = 2; 36 priority = 100; 37 preload = 1; 38 permission = 0664; 39 moduleName = "sample_driver"; 40 serviceName = "sample_service"; 41 } 42 } 43 } 44 } 45} 46``` 47 48 49## Writing the Driver Code 50 51Write the driver code based on the HDF. For more details, see [Driver Development](../driver/driver-hdf-development.md). 52 53 54```c 55#include <fcntl.h> 56#include <sys/stat.h> 57#include <sys/ioctl.h> 58#include "hdf_log.h" 59#include "hdf_base.h" 60#include "hdf_device_desc.h" 61 62#define HDF_LOG_TAG sample_driver 63 64#define SAMPLE_WRITE_READ 123 65 66static int32_t HdfSampleDriverDispatch( 67 struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply) 68{ 69 HDF_LOGI("%{public}s: received cmd %{public}d", __func__, id); 70 if (id == SAMPLE_WRITE_READ) { 71 const char *readData = HdfSbufReadString(data); 72 if (readData != NULL) { 73 HDF_LOGE("%{public}s: read data is: %{public}s", __func__, readData); 74 } 75 if (!HdfSbufWriteInt32(reply, INT32_MAX)) { 76 HDF_LOGE("%{public}s: reply int32 fail", __func__); 77 } 78 return HdfDeviceSendEvent(client->device, id, data); 79 } 80 return HDF_FAILURE; 81} 82 83static void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) 84{ 85 // Release resources. 86 return; 87} 88 89static int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) 90{ 91 if (deviceObject == NULL) { 92 return HDF_FAILURE; 93 } 94 static struct IDeviceIoService testService = { 95 .Dispatch = HdfSampleDriverDispatch, 96 }; 97 deviceObject->service = &testService; 98 return HDF_SUCCESS; 99} 100 101static int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) 102{ 103 if (deviceObject == NULL) { 104 HDF_LOGE("%{public}s::ptr is null!", __func__); 105 return HDF_FAILURE; 106 } 107 HDF_LOGI("Sample driver Init success"); 108 return HDF_SUCCESS; 109} 110 111static struct HdfDriverEntry g_sampleDriverEntry = { 112 .moduleVersion = 1, 113 .moduleName = "sample_driver", 114 .Bind = HdfSampleDriverBind, 115 .Init = HdfSampleDriverInit, 116 .Release = HdfSampleDriverRelease, 117}; 118 119HDF_INIT(g_sampleDriverEntry); 120``` 121 122 123## Implementing Interaction Between the Application and the Driver 124 125Write the code for interaction between the user-mode application and the driver. Place the code in the **drivers/hdf_core/adapter/uhdf** directory for compilation. For details about **BUILD.gn**, see **drivers/hdf_core/framework/sample/platform/uart/dev/BUILD.gn**. 126 127 128```c 129#include <fcntl.h> 130#include <sys/stat.h> 131#include <sys/ioctl.h> 132#include <unistd.h> 133#include "hdf_log.h" 134#include "hdf_sbuf.h" 135#include "hdf_io_service_if.h" 136 137#define HDF_LOG_TAG sample_test 138#define SAMPLE_SERVICE_NAME "sample_service" 139 140#define SAMPLE_WRITE_READ 123 141 142int g_replyFlag = 0; 143 144static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) 145{ 146 const char *string = HdfSbufReadString(data); 147 if (string == NULL) { 148 HDF_LOGE("fail to read string in event data"); 149 g_replyFlag = 1; 150 return HDF_FAILURE; 151 } 152 HDF_LOGI("%{public}s: dev event received: %{public}u %{public}s", (char *)priv, id, string); 153 g_replyFlag = 1; 154 return HDF_SUCCESS; 155} 156 157static int SendEvent(struct HdfIoService *serv, char *eventData) 158{ 159 int ret = 0; 160 struct HdfSBuf *data = HdfSbufObtainDefaultSize(); 161 if (data == NULL) { 162 HDF_LOGE("fail to obtain sbuf data"); 163 return 1; 164 } 165 166 struct HdfSBuf *reply = HdfSbufObtainDefaultSize(); 167 if (reply == NULL) { 168 HDF_LOGE("fail to obtain sbuf reply"); 169 ret = HDF_DEV_ERR_NO_MEMORY; 170 goto out; 171 } 172 173 if (!HdfSbufWriteString(data, eventData)) { 174 HDF_LOGE("fail to write sbuf"); 175 ret = HDF_FAILURE; 176 goto out; 177 } 178 179 ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); 180 if (ret != HDF_SUCCESS) { 181 HDF_LOGE("fail to send service call"); 182 goto out; 183 } 184 185 int replyData = 0; 186 if (!HdfSbufReadInt32(reply, &replyData)) { 187 HDF_LOGE("fail to get service call reply"); 188 ret = HDF_ERR_INVALID_OBJECT; 189 goto out; 190 } 191 HDF_LOGI("Get reply is: %{public}d", replyData); 192out: 193 HdfSbufRecycle(data); 194 HdfSbufRecycle(reply); 195 return ret; 196} 197 198int main() 199{ 200 char *sendData = "default event info"; 201 struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); 202 if (serv == NULL) { 203 HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); 204 return HDF_FAILURE; 205 } 206 207 static struct HdfDevEventlistener listener = { 208 .callBack = OnDevEventReceived, 209 .priv ="Service0" 210 }; 211 212 if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { 213 HDF_LOGE("fail to register event listener"); 214 return HDF_FAILURE; 215 } 216 if (SendEvent(serv, sendData)) { 217 HDF_LOGE("fail to send event"); 218 return HDF_FAILURE; 219 } 220 221 while (g_replyFlag == 0) { 222 sleep(1); 223 } 224 225 if (HdfDeviceUnregisterEventListener(serv, &listener)) { 226 HDF_LOGE("fail to unregister listener"); 227 return HDF_FAILURE; 228 } 229 230 HdfIoServiceRecycle(serv); 231 return HDF_SUCCESS; 232} 233``` 234 235> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/> 236> The user-mode application uses the message sending API of the HDF, and the compilation of the user-mode application depends on the dynamic libraries **hdf_core** and **osal** provided by the HDF. Therefore, you need to add the following dependencies to the .gn file: 237> 238> deps = [ 239> 240> "//drivers/hdf_core/adapter/uhdf/manager:hdf_core", 241> 242> "//drivers/hdf_core/adapter/uhdf/posix:hdf_posix_osal", 243> 244> ] 245