# HDF Development Example The following is a HDF-based driver development example. ## Adding Driver Configuration Add the driver configuration to the HDF configuration file, for example, **vendor/hisilicon/xxx/hdf_config/device_info**. ``` root { device_info { match_attr = "hdf_manager"; template host { hostName = ""; priority = 100; template device { template deviceNode { policy = 0; priority = 100; preload = 0; permission = 0664; moduleName = ""; serviceName = ""; deviceMatchAttr = ""; } } } sample_host :: host { hostName = "sample_host"; sample_device :: device { device0 :: deviceNode { policy = 2; priority = 100; preload = 1; permission = 0664; moduleName = "sample_driver"; serviceName = "sample_service"; } } } } } ``` ## Writing the Driver Code Write the driver code based on the HDF. For more details, see [Driver Development](../driver/driver-hdf-development.md). ``` #include #include #include #include "hdf_log.h" #include "hdf_base.h" #include "hdf_device_desc.h" #define HDF_LOG_TAG "sample_driver" #define SAMPLE_WRITE_READ 123 int32_t HdfSampleDriverDispatch( struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply) { HDF_LOGE("%s: received cmd %d", __func__, id); if (id == SAMPLE_WRITE_READ) { const char *readData = HdfSbufReadString(data); if (readData != NULL) { HDF_LOGE("%s: read data is: %s", __func__, readData); } if (!HdfSbufWriteInt32(reply, INT32_MAX)) { HDF_LOGE("%s: reply int32 fail", __func__); } return HdfDeviceSendEvent(deviceObject, id, data); } return HDF_FAILURE; } void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) { // Release resources. return; } int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { return HDF_FAILURE; } static struct IDeviceIoService testService = { .Dispatch = HdfSampleDriverDispatch, }; deviceObject->service = &testService; return HDF_SUCCESS; } int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("%s::ptr is null!", __func__); return HDF_FAILURE; } HDF_LOGE("Sample driver Init success"); return HDF_SUCCESS; } struct HdfDriverEntry g_sampleDriverEntry = { .moduleVersion = 1, .moduleName = "sample_driver", .Bind = HdfSampleDriverBind, .Init = HdfSampleDriverInit, .Release = HdfSampleDriverRelease, }; HDF_INIT(g_sampleDriverEntry); ``` ## Implementing Interaction Between the Application and the Driver Write the code for interaction between the user-mode application and the driver. Place the code in the **drivers/adapter/uhdf** directory for compilation. For details about **build.gn**, see **drivers/framework/sample/platform/uart/dev/build.gn**. ``` #include #include #include #include #include "hdf_log.h" #include "hdf_sbuf.h" #include "hdf_io_service_if.h" #define HDF_LOG_TAG "sample_test" #define SAMPLE_SERVICE_NAME "sample_service" #define SAMPLE_WRITE_READ 123 int g_replyFlag = 0; static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) { const char *string = HdfSbufReadString(data); if (string == NULL) { HDF_LOGE("fail to read string in event data"); g_replyFlag = 1; return HDF_FAILURE; } HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string); g_replyFlag = 1; return HDF_SUCCESS; } static int SendEvent(struct HdfIoService *serv, char *eventData) { int ret = 0; struct HdfSBuf *data = HdfSBufObtainDefaultSize(); if (data == NULL) { HDF_LOGE("fail to obtain sbuf data"); return 1; } 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, eventData)) { HDF_LOGE("fail to write sbuf"); ret = HDF_FAILURE; goto out; } ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); if (ret != HDF_SUCCESS) { HDF_LOGE("fail to send service call"); goto out; } int replyData = 0; if (!HdfSbufReadInt32(reply, &replyData)) { HDF_LOGE("fail to get service call reply"); ret = HDF_ERR_INVALID_OBJECT; goto out; } HDF_LOGE("Get reply is: %d", replyData); out: HdfSBufRecycle(data); HdfSBufRecycle(reply); return ret; } int main() { char *sendData = "default event info"; struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); if (serv == NULL) { HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME); return HDF_FAILURE; } static struct HdfDevEventlistener listener = { .callBack = OnDevEventReceived, .priv ="Service0" }; if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) { HDF_LOGE("fail to register event listener"); return HDF_FAILURE; } if (SendEvent(serv, sendData)) { HDF_LOGE("fail to send event"); return HDF_FAILURE; } while (g_replyFlag == 0) { sleep(1); } if (HdfDeviceUnregisterEventListener(serv, &listener)) { HDF_LOGE("fail to unregister listener"); return HDF_FAILURE; } HdfIoServiceRecycle(serv); return HDF_SUCCESS; } ``` > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
> 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: > > deps = [ > > "//drivers/adapter/uhdf/manager:hdf_core", > > "//drivers/adapter/uhdf/posix:hdf_posix_osal", > > ]