HDF开发实例

下面基于HDF框架,提供一个完整的样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。

添加配置

在HDF框架的配置文件(例如vendor/hisi/hi35xx/hi3516dv300/config/device_info/device_info.hcs)中添加该驱动的配置信息,如下所示:


1. root {
2. device_info {
3. match_attr = "hdf_manager";
4. template host {
5. hostName = "";
6. priority = 100;
7. template device {
8. template deviceNode {
9. policy = 0;
10. priority = 100;
11. preload = 0;
12. permission = 0664;
13. moduleName = "";
14. serviceName = "";
15. deviceMatchAttr = "";
16. }
17. }
18. }
19. sample_host :: host {
20. hostName = "sample_host";
21. sample_device :: device {
22. device0 :: deviceNode {
23. policy = 2;
24. priority = 100;
25. preload = 1;
26. permission = 0664;
27. moduleName = "sample_driver";
28. serviceName = "sample_service";
29. }
30. }
31. }
32. }
33. }

编写驱动代码

基于HDF框架编写的sample驱动代码如下:


1. #include <fcntl.h>
2. #include <sys/stat.h>
3. #include <sys/ioctl.h>
4. #include "hdf_log.h"
5. #include "hdf_base.h"
6. #include "hdf_device_desc.h"

8. #define HDF_LOG_TAG sample_driver

10. #define SAMPLE_WRITE_READ 123

12. int32_t HdfSampleDriverDispatch(
13. struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
14. {
15. HDF_LOGE("%s: received cmd %d", __func__, id);
16. if (id == SAMPLE_WRITE_READ) {
17. const char *readData = HdfSbufReadString(data);
18. if (readData != NULL) {
19. HDF_LOGE("%s: read data is: %s", __func__, readData);
20. }
21. if (!HdfSbufWriteInt32(reply, INT32_MAX)) {
22. HDF_LOGE("%s: reply int32 fail", __func__);
23. }
24. return HdfDeviceSendEvent(deviceObject, id, data);
25. }
26. return HDF_FAILURE;
27. }

29. void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
30. {
31. // release resources here
32. return;
33. }

35. int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
36. {
37. if (deviceObject == NULL) {
38. return HDF_FAILURE;
39. }
40. static struct IDeviceIoService testService = {
41. .Dispatch = HdfSampleDriverDispatch,
42. };
43. deviceObject->service = &testService;
44. return HDF_SUCCESS;
45. }

47. int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
48. {
49. if (deviceObject == NULL) {
50. HDF_LOGE("%s::ptr is null!", __func__);
51. return HDF_FAILURE;
52. }
53. HDF_LOGE("Sample driver Init success");
54. return HDF_SUCCESS;
55. }

57. struct HdfDriverEntry g_sampleDriverEntry = {
58. .moduleVersion = 1,
59. .moduleName = "sample_driver",
60. .Bind = HdfSampleDriverBind,
61. .Init = HdfSampleDriverInit,
62. .Release = HdfSampleDriverRelease,
63. };

65. HDF_INIT(g_sampleDriverEntry);

编写用户程序和驱动交互代码

基于HDF框架编写的用户态程序和驱动交互的代码如下:


1. #include <fcntl.h>
2. #include <sys/stat.h>
3. #include <sys/ioctl.h>
4. #include <unistd.h>
5. #include "hdf_log.h"
6. #include "hdf_sbuf.h"
7. #include "hdf_io_service_if.h"

9. #define HDF_LOG_TAG "sample_test"
10. #define SAMPLE_SERVICE_NAME "sample_service"

12. #define SAMPLE_WRITE_READ 123

14. int g_replyFlag = 0;

16. static int OnDevEventReceived(void *priv,  uint32_t id, struct HdfSBuf *data)
17. {
18. const char *string = HdfSbufReadString(data);
19. if (string == NULL) {
20. HDF_LOGE("fail to read string in event data");
21. g_replyFlag = 1;
22. return HDF_FAILURE;
23. }
24. HDF_LOGE("%s: dev event received: %u %s",  (char *)priv, id, string);
25. g_replyFlag = 1;
26. return HDF_SUCCESS;
27. }

29. static int SendEvent(struct HdfIoService *serv, char *eventData)
30. {
31. int ret = 0;
32. struct HdfSBuf *data = HdfSBufObtainDefaultSize();
33. if (data == NULL) {
34. HDF_LOGE("fail to obtain sbuf data");
35. return 1;
36. }

38. struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
39. if (reply == NULL) {
40. HDF_LOGE("fail to obtain sbuf reply");
41. ret = HDF_DEV_ERR_NO_MEMORY;
42. goto out;
43. }

45. if (!HdfSbufWriteString(data, eventData)) {
46. HDF_LOGE("fail to write sbuf");
47. ret = HDF_FAILURE;
48. goto out;
49. }

51. ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
52. if (ret != HDF_SUCCESS) {
53. HDF_LOGE("fail to send service call");
54. goto out;
55. }

57. int replyData = 0;
58. if (!HdfSbufReadInt32(reply, &replyData)) {
59. HDF_LOGE("fail to get service call reply");
60. ret = HDF_ERR_INVALID_OBJECT;
61. goto out;
62. }
63. HDF_LOGE("Get reply is: %d", replyData);
64. out:
65. HdfSBufRecycle(data);
66. HdfSBufRecycle(reply);
67. return ret;
68. }

70. int main()
71. {
72. char *sendData = "default event info";
73. struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME, 0);
74. if (serv == NULL) {
75. HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME);
76. return HDF_FAILURE;
77. }

79. static struct HdfDevEventlistener listener = {
80. .callBack = OnDevEventReceived,
81. .priv ="Service0"
82. };

84. if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) {
85. HDF_LOGE("fail to register event listener");
86. return HDF_FAILURE;
87. }
88. if (SendEvent(serv, sendData)) {
89. HDF_LOGE("fail to send event");
90. return HDF_FAILURE;
91. }

93. /* wait for event receive event finishing */
94. while (g_replyFlag == 0) {
95. sleep(1);
96. }

98. if (HdfDeviceUnregisterEventListener(serv, &listener)) {
99. HDF_LOGE("fail to  unregister listener");
100. return HDF_FAILURE;
101. }

103. HdfIoServiceRecycle(serv);
104. return HDF_SUCCESS;
105. }

HDF开发实例 - 图1 说明: 用户态应用程序使用了HDF框架中的消息发送接口,因此在编译用户态程序的过程中需要依赖HDF框架对外提供的hdf_core和osal的动态库,在gn编译文件中添加如下依赖项: deps = [ “//drivers/hdf/lite/manager:hdf_core”, “//drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal”, ]