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"
  7. #define HDF_LOG_TAG sample_driver
  8. #define SAMPLE_WRITE_READ 123
  9. int32_t HdfSampleDriverDispatch(
  10. struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
  11. {
  12. HDF_LOGE("%s: received cmd %d", __func__, id);
  13. if (id == SAMPLE_WRITE_READ) {
  14. const char *readData = HdfSbufReadString(data);
  15. if (readData != NULL) {
  16. HDF_LOGE("%s: read data is: %s", __func__, readData);
  17. }
  18. if (!HdfSbufWriteInt32(reply, INT32_MAX)) {
  19. HDF_LOGE("%s: reply int32 fail", __func__);
  20. }
  21. return HdfDeviceSendEvent(deviceObject, id, data);
  22. }
  23. return HDF_FAILURE;
  24. }
  25. void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
  26. {
  27. // release resources here
  28. return;
  29. }
  30. int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
  31. {
  32. if (deviceObject == NULL) {
  33. return HDF_FAILURE;
  34. }
  35. static struct IDeviceIoService testService = {
  36. .Dispatch = HdfSampleDriverDispatch,
  37. };
  38. deviceObject->service = &testService;
  39. return HDF_SUCCESS;
  40. }
  41. int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
  42. {
  43. if (deviceObject == NULL) {
  44. HDF_LOGE("%s::ptr is null!", __func__);
  45. return HDF_FAILURE;
  46. }
  47. HDF_LOGE("Sample driver Init success");
  48. return HDF_SUCCESS;
  49. }
  50. struct HdfDriverEntry g_sampleDriverEntry = {
  51. .moduleVersion = 1,
  52. .moduleName = "sample_driver",
  53. .Bind = HdfSampleDriverBind,
  54. .Init = HdfSampleDriverInit,
  55. .Release = HdfSampleDriverRelease,
  56. };
  57. 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"
  8. #define HDF_LOG_TAG "sample_test"
  9. #define SAMPLE_SERVICE_NAME "sample_service"
  10. #define SAMPLE_WRITE_READ 123
  11. int g_replyFlag = 0;
  12. static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
  13. {
  14. const char *string = HdfSbufReadString(data);
  15. if (string == NULL) {
  16. HDF_LOGE("fail to read string in event data");
  17. g_replyFlag = 1;
  18. return HDF_FAILURE;
  19. }
  20. HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string);
  21. g_replyFlag = 1;
  22. return HDF_SUCCESS;
  23. }
  24. static int SendEvent(struct HdfIoService *serv, char *eventData)
  25. {
  26. int ret = 0;
  27. struct HdfSBuf *data = HdfSBufObtainDefaultSize();
  28. if (data == NULL) {
  29. HDF_LOGE("fail to obtain sbuf data");
  30. return 1;
  31. }
  32. struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
  33. if (reply == NULL) {
  34. HDF_LOGE("fail to obtain sbuf reply");
  35. ret = HDF_DEV_ERR_NO_MEMORY;
  36. goto out;
  37. }
  38. if (!HdfSbufWriteString(data, eventData)) {
  39. HDF_LOGE("fail to write sbuf");
  40. ret = HDF_FAILURE;
  41. goto out;
  42. }
  43. ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
  44. if (ret != HDF_SUCCESS) {
  45. HDF_LOGE("fail to send service call");
  46. goto out;
  47. }
  48. int replyData = 0;
  49. if (!HdfSbufReadInt32(reply, &replyData)) {
  50. HDF_LOGE("fail to get service call reply");
  51. ret = HDF_ERR_INVALID_OBJECT;
  52. goto out;
  53. }
  54. HDF_LOGE("Get reply is: %d", replyData);
  55. out:
  56. HdfSBufRecycle(data);
  57. HdfSBufRecycle(reply);
  58. return ret;
  59. }
  60. int main()
  61. {
  62. char *sendData = "default event info";
  63. struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME, 0);
  64. if (serv == NULL) {
  65. HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME);
  66. return HDF_FAILURE;
  67. }
  68. static struct HdfDevEventlistener listener = {
  69. .callBack = OnDevEventReceived,
  70. .priv ="Service0"
  71. };
  72. if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) {
  73. HDF_LOGE("fail to register event listener");
  74. return HDF_FAILURE;
  75. }
  76. if (SendEvent(serv, sendData)) {
  77. HDF_LOGE("fail to send event");
  78. return HDF_FAILURE;
  79. }
  80. /* wait for event receive event finishing */
  81. while (g_replyFlag == 0) {
  82. sleep(1);
  83. }
  84. if (HdfDeviceUnregisterEventListener(serv, &listener)) {
  85. HDF_LOGE("fail to unregister listener");
  86. return HDF_FAILURE;
  87. }
  88. HdfIoServiceRecycle(serv);
  89. return HDF_SUCCESS;
  90. }

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