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_tHdfSampleDriverDispatch(
  10. structHdfDeviceObject*deviceObject,int id,structHdfSBuf*data,structHdfSBuf*reply)
  11. {
  12. HDF_LOGE("%s: received cmd %d", __func__, id);
  13. if(id == SAMPLE_WRITE_READ){
  14. constchar*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. returnHdfDeviceSendEvent(deviceObject, id, data);
  22. }
  23. return HDF_FAILURE;
  24. }
  25. voidHdfSampleDriverRelease(structHdfDeviceObject*deviceObject)
  26. {
  27. // release resources here
  28. return;
  29. }
  30. intHdfSampleDriverBind(structHdfDeviceObject*deviceObject)
  31. {
  32. if(deviceObject == NULL){
  33. return HDF_FAILURE;
  34. }
  35. staticstructIDeviceIoService testService ={
  36. .Dispatch=HdfSampleDriverDispatch,
  37. };
  38. deviceObject->service =&testService;
  39. return HDF_SUCCESS;
  40. }
  41. intHdfSampleDriverInit(structHdfDeviceObject*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. structHdfDriverEntry 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. staticintOnDevEventReceived(void*priv,uint32_t id,structHdfSBuf*data)
  13. {
  14. constchar*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. staticintSendEvent(structHdfIoService*serv,char*eventData)
  25. {
  26. int ret =0;
  27. structHdfSBuf*data =HdfSBufObtainDefaultSize();
  28. if(data == NULL){
  29. HDF_LOGE("fail to obtain sbuf data");
  30. return1;
  31. }
  32. structHdfSBuf*reply =HdfSBufObtainDefaultSize();
  33. if(reply == NULL){
  34. HDF_LOGE("fail to obtain sbuf reply");
  35. ret = HDF_DEV_ERR_NO_MEMORY;
  36. gotoout;
  37. }
  38. if(!HdfSbufWriteString(data, eventData)){
  39. HDF_LOGE("fail to write sbuf");
  40. ret = HDF_FAILURE;
  41. gotoout;
  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. gotoout;
  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. gotoout;
  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. structHdfIoService*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. staticstructHdfDevEventlistener 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”, ]