• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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