HDF驱动框架探路(三):基于3516配置一套可以打通的HDF驱动程序

开发 前端
本文的就是着重解决这个问题,也就是自己去配置一个HDF驱动模块。本文是基于3516的小型系统去验证的。

[[437608]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

老规矩还是将最终希望跑出来的效果放出来。如下:

HDF驱动框架探路(三):基于3516配置一套可以打通的HDF驱动程序-鸿蒙HarmonyOS技术社区

前言

大家如果有读过第二篇文章的话,可能发现了在该文中内核态的驱动程序是直接引用了源码中已经存在的一个HDF驱动模块。所以本文的就是着重解决这个问题,也就是自己去配置一个HDF驱动模块。

本文是基于3516的小型系统去验证的。

本文框架图

HDF驱动框架探路(三):基于3516配置一套可以打通的HDF驱动程序-鸿蒙HarmonyOS技术社区

观察上图,其实本文是将上文的流程进一步细化,上文中的驱动程序细分成了三个部分,分别是:HCS文件配置、内核态代码、liteos_a配置编译进内核。这三个部分合起来就是自己搭建HDF驱动程序的步骤。

1. HDF配置

这里的HDF配置是按照源码中已经存在的sample_driver模块来的

打开文件vendor/hisilicon/hispark_taurus/hdf_config/hdf_test/hdf_test_manager/device_info.hcs,然后加入下述代码中的device2。

  1. device1 :: deviceNode { 
  2.                 policy = 2; 
  3.                 priority = 10; 
  4.                 preload = 0; 
  5.                 permission = 0644; 
  6.                 moduleName = "sample_driver"
  7.                 serviceName = "sample_service"
  8.             } 
  9.             device2 :: deviceNode {             // DeviceNode of the sample driver 
  10.           policy = 2;                     // Driver service release policy. For details, see section Driver Service Management. 
  11.           priority= 10;                  // Driver startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the device loading sequence is random. 
  12.           preload = 0;                    // On-demand loading of the driver. For details, see "NOTE" at the end of this section
  13.           permission = 0664;              // Permission for the driver to create device nodes. 
  14.           moduleName = "talkweb_driver";       // Driver name. The value of this field must be the same as the value of moduleName in the driver entry structure. 
  15.           serviceName = "talkweb_service";     // Name of the service released by the driver. The name must be unique
  16.       } 
  17.         } 
  18.         device_platform_test :: device { 
  19.             platform_test:: deviceNode { 
  20.                 policy = 1; 
  21.                 priority = 150; 
  22.                 preload = 0; 
  23.                 permission = 0644; 
  24.                 moduleName = "PLATFORM_TEST_DRIVER"
  25.                 serviceName = "PLATFORM_TEST"
  26.                 deviceMatchAttr = "platform_test"
  27.             } 
  28.         } 

2. liteos_a编译配置

该步骤的作用是将第三步中的驱动程序编译进入内核。

2.1 在BUILD.gn文件中配置

打开drivers/adapter/khdf/liteos/test/BUILD.gn文件

  1. --- a/khdf/liteos/test/BUILD.gn 
  2. +++ b/khdf/liteos/test/BUILD.gn 
  3. @@ -37,6 +37,7 @@ hdf_driver(module_name) { 
  4.    sources = [ 
  5.      "$HDF_TEST_FRAMWORK_ROOT/common/hdf_main_test.c"
  6.      "$HDF_TEST_FRAMWORK_ROOT/manager/sample_driver_test.c"
  7. +    "$HDF_TEST_FRAMWORK_ROOT/talkwebtest/talkweb.c"
  8.      "$HDF_TEST_FRAMWORK_ROOT/osal/osal_all_test.c"
  9.      "$HDF_TEST_FRAMWORK_ROOT/osal/osal_file_test.c"
  10.      "$HDF_TEST_FRAMWORK_ROOT/osal/osal_get_case_test.c"

2.2 在Makefile中进行添加配置

drivers/adapter/khdf/liteos/test/Makefile

  1. --- a/khdf/liteos/test/Makefile 
  2. +++ b/khdf/liteos/test/Makefile 
  3. @@ -34,6 +34,7 @@ HDF_TEST_FRAMWORK_ROOT = $(LITEOSTOPDIR)/../../drivers/framework/test/unittest 
  4.   
  5.  LOCAL_SRCS := $(HDF_TEST_FRAMWORK_ROOT)/common/hdf_main_test.c \ 
  6.                $(HDF_TEST_FRAMWORK_ROOT)/manager/sample_driver_test.c \ 
  7. +              $(HDF_TEST_FRAMWORK_ROOT)/talkwebtest/talkweb.c \ 
  8.                $(HDF_TEST_FRAMWORK_ROOT)/osal/osal_test_entry.c \ 
  9.                $(HDF_TEST_FRAMWORK_ROOT)/osal/osal_all_test.c \ 
  10.                $(HDF_TEST_FRAMWORK_ROOT)/osal/osal_file_test.c \ 

3. 驱动程序

进入drivers/framework/test/unittest目录下,新建talkwebtest目录

3.1 在上述目录下新建talkweb.h文件,将下述代码放入

  1. #ifndef HDF_SAMPLE_DRIVER_H 
  2. #define HDF_SAMPLE_DRIVER_H 
  3.  
  4. #include "hdf_object.h" 
  5.  
  6. #define SAMPLE_SERVICE "sample_service" 
  7.  
  8. typedef enum { 
  9.     SAMPLE_DRIVER_REGISTER_DEVICE = 0, 
  10.     SAMPLE_DRIVER_UNREGISTER_DEVICE, 
  11.     SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE, 
  12.     SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE, 
  13.     SAMPLE_DRIVER_PM_STATE_INJECT, 
  14. } SAMPLE_DRIVER_CMDID; 
  15.  
  16. struct HdfDeviceObject *GetDeviceObject(void); 
  17.  
  18. #endif // HDF_MAIN_TEST_H 

3.2 在上述目录下新建talkweb.c文件,将下述代码放入

  1. /* 
  2.  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 
  3.  * 
  4.  * HDF is dual licensed: you can use it either under the terms of 
  5.  * the GPL, or the BSD license, at your option
  6.  * See the LICENSE file in the root of this repository for complete details. 
  7.  */ 
  8. #include "talkweb.h" 
  9. #include "devsvc_manager_clnt.h" 
  10. #include "devmgr_service.h" 
  11. #include "hdf_log.h" 
  12. #include "hdf_device_desc.h" 
  13. #include "hdf_pm.h" 
  14.  
  15. #include "device_resource_if.h" 
  16. #include "osal_io.h" 
  17. #include "osal_mem.h" 
  18. #include "gpio_if.h" 
  19. #include "osal_irq.h" 
  20. #include "osal_time.h"  
  21. //#define HDF_LOG_TAG led_driver // 打印日志所包含的标签,如果不定义则用默认>    定义的HDF_TAG标签 
  22. #define LED_WRITE_READ 88   
  23.  
  24. #define HDF_LOG_TAG sample_driver_test 
  25.  
  26. #ifndef INT32_MAX 
  27. #define INT32_MAX 0x7fffffff 
  28. #endif 
  29.  
  30. void HdftalkwebDriverRelease(struct HdfDeviceObject *deviceObject) 
  31.     (void)deviceObject; 
  32.     return
  33.  
  34. int32_t talkwebDriverRegisterDevice(struct HdfSBuf *data) 
  35.     const char *moduleName = NULL
  36.     const char *serviceName = NULL
  37.     struct HdfDeviceObject *devObj = NULL
  38.     if (data == NULL) { 
  39.         return HDF_FAILURE; 
  40.     } 
  41.  
  42.     moduleName = HdfSbufReadString(data); 
  43.     if (moduleName == NULL) { 
  44.         return HDF_FAILURE; 
  45.     } 
  46.     serviceName = HdfSbufReadString(data); 
  47.     if (serviceName == NULL) { 
  48.         return HDF_FAILURE; 
  49.     } 
  50.  
  51.     devObj = HdfRegisterDevice(moduleName, serviceName, NULL); 
  52.     if (devObj == NULL) { 
  53.         return HDF_FAILURE; 
  54.     } 
  55.     return HDF_SUCCESS; 
  56.  
  57. int32_t talkwebDriverUnregisterDevice(struct HdfSBuf *data) 
  58.     const char *moduleName = NULL
  59.     const char *serviceName = NULL
  60.     if (data == NULL) { 
  61.         return HDF_FAILURE; 
  62.     } 
  63.  
  64.     moduleName = HdfSbufReadString(data); 
  65.     if (moduleName == NULL) { 
  66.         return HDF_FAILURE; 
  67.     } 
  68.     serviceName = HdfSbufReadString(data); 
  69.     if (serviceName == NULL) { 
  70.         return HDF_FAILURE; 
  71.     } 
  72.     HdfUnregisterDevice(moduleName, serviceName); 
  73.     return HDF_SUCCESS; 
  74.  
  75. int32_t talkwebDriverSendEvent(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, bool broadcast) 
  76.     return broadcast ? HdfDeviceSendEvent(client->device, id, data) : HdfDeviceSendEventToClient(client, id, data); 
  77.  
  78. int32_t talkwebDriverPowerStateInject(uint32_t powerState) 
  79.     int ret; 
  80.     struct IDevmgrService *devmgrService = DevmgrServiceGetInstance(); 
  81.     if (devmgrService == NULL || devmgrService->PowerStateChange == NULL) { 
  82.         return HDF_ERR_INVALID_OBJECT; 
  83.     } 
  84.     ret = devmgrService->PowerStateChange(devmgrService, powerState); 
  85.  
  86.     HDF_LOGI("%s: inject power state(%d) done, ret = %d", __func__, powerState, ret); 
  87.     return ret; 
  88.  
  89.   
  90. static int32_t CtlLED(int mode) 
  91.     int32_t ret; 
  92.     uint16_t valRead; 
  93.     /* LED的GPIO管脚号 */ 
  94.     uint16_t gpio = 5 * 8 + 1;  // 红外补光灯 
  95.     // uint16_t gpio = 2 * 8 + 3;  // 绿色指示灯 
  96.     // uint16_t gpio = 3 * 8 + 4;  // 红色指示灯 
  97.   
  98.     /* 将GPIO管脚配置为输出 */ 
  99.     ret = GpioSetDir(gpio, GPIO_DIR_OUT); 
  100.     if (ret != 0) 
  101.     {    
  102.         HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); 
  103.         return ret; 
  104.     }    
  105.   
  106.     if (mode == -1)  
  107.     {    
  108.         // 翻转输出口 
  109.         (void)GpioRead(gpio, &valRead); 
  110.         ret = GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); 
  111.     }    
  112.     else 
  113.     {    
  114.         ret = GpioWrite(gpio, mode); 
  115.     }    
  116.   
  117.     if (ret != 0) 
  118.     {    
  119.         HDF_LOGE("GpioWrite: failed, ret %d\n", ret); 
  120.         return ret; 
  121.     }    
  122.     return ret; 
  123.  
  124.  
  125. int32_t talkwebDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 
  126.         HDF_LOGD("%s::qzk-enter", __func__); 
  127.     uint32_t powerState = 0; 
  128.     int32_t ret = HDF_SUCCESS; 
  129.     if (reply == NULL || client == NULL) { 
  130.         return HDF_FAILURE; 
  131.     } 
  132.     int32_t result = HDF_FAILURE; 
  133.     switch (cmdId) { 
  134.         case LED_WRITE_READ: 
  135.             const char *recv = HdfSbufReadString(data); 
  136.             if (recv != NULL
  137.             { 
  138.                 //HDF_LOGI("recv: %s", recv); 
  139.                 result = CtlLED(-1); 
  140.                 // CtlLED(GPIO_VAL_HIGH); 
  141.                 if (!HdfSbufWriteInt32(reply, result)){ 
  142.                     //HDF_LOGE("replay is fail"); 
  143.                 } 
  144.                 return HdfDeviceSendEvent(client->device, cmdId, data); 
  145.             } 
  146.             break; 
  147.         case SAMPLE_DRIVER_REGISTER_DEVICE: { 
  148.             ret = talkwebDriverRegisterDevice(data); 
  149.             HdfSbufWriteInt32(reply, ret); 
  150.             break; 
  151.         } 
  152.         case SAMPLE_DRIVER_UNREGISTER_DEVICE: 
  153.             ret = talkwebDriverUnregisterDevice(data); 
  154.             HdfSbufWriteInt32(reply, ret); 
  155.             break; 
  156.         case SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE: 
  157.             ret =  talkwebDriverSendEvent(client, cmdId, data, false); 
  158.             HdfSbufWriteInt32(reply, INT32_MAX); 
  159.             break; 
  160.         case SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE: 
  161.             ret = talkwebDriverSendEvent(client, cmdId, data, true); 
  162.             HdfSbufWriteInt32(reply, INT32_MAX); 
  163.             break; 
  164.         case SAMPLE_DRIVER_PM_STATE_INJECT: 
  165.             HdfSbufReadUint32(data, &powerState); 
  166.             return talkwebDriverPowerStateInject(powerState); 
  167.         default
  168.             break; 
  169.     } 
  170.  
  171.     return ret; 
  172.  
  173. int HdftalkwebDriverBind(struct HdfDeviceObject *deviceObject) 
  174.     static struct IDeviceIoService testService = { 
  175.         .Dispatch = talkwebDriverDispatch, 
  176.         .Open = NULL
  177.         .Release = NULL
  178.     }; 
  179.     HDF_LOGD("%s::enter", __func__); 
  180.     if (deviceObject == NULL) { 
  181.         return HDF_FAILURE; 
  182.     } 
  183.  
  184.     deviceObject->service = &testService; 
  185.     return HDF_SUCCESS; 
  186.  
  187. int HdftalkwebDozeResume(struct HdfDeviceObject *deviceObject) 
  188.     HDF_LOGI("%s:called", __func__); 
  189.     return HDF_SUCCESS; 
  190.  
  191. int HdftalkwebDozeSuspend(struct HdfDeviceObject *deviceObject) 
  192.     HDF_LOGI("%s:called", __func__); 
  193.     return HDF_SUCCESS; 
  194.  
  195. int HdftalkwebResume(struct HdfDeviceObject *deviceObject) 
  196.     HDF_LOGI("%s:called", __func__); 
  197.     return HDF_SUCCESS; 
  198.  
  199. int HdftalkwebSuspend(struct HdfDeviceObject *deviceObject) 
  200.     HDF_LOGI("%s:called", __func__); 
  201.     return HDF_SUCCESS; 
  202.  
  203. struct talkwebDriverPmListener { 
  204.     struct IPowerEventListener powerListener; 
  205.     void *p; 
  206. }; 
  207.  
  208. int HdftalkwebDriverInit(struct HdfDeviceObject *deviceObject) 
  209.     static struct talkwebDriverPmListener pmListener = {0}; 
  210.     int ret; 
  211.     HDF_LOGI("%s::enter!", __func__); 
  212.     if (deviceObject == NULL) { 
  213.         HDF_LOGE("%s::ptr is null!", __func__); 
  214.         return HDF_FAILURE; 
  215.     } 
  216.     HDF_LOGD("%s:Init success", __func__); 
  217.  
  218.     pmListener.powerListener.DozeResume = HdftalkwebDozeResume; 
  219.     pmListener.powerListener.DozeSuspend = HdftalkwebDozeSuspend; 
  220.     pmListener.powerListener.Resume = HdftalkwebResume; 
  221.     pmListener.powerListener.Suspend = HdftalkwebSuspend; 
  222.  
  223.     ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener); 
  224.     HDF_LOGI("%s:register power listener, ret = %d", __func__, ret); 
  225.  
  226.     return HDF_SUCCESS; 
  227.  
  228.  
  229. struct HdfDriverEntry g_talkwebDriverEntry = { 
  230.     .moduleVersion = 1, 
  231.     .moduleName = "talkweb_driver"
  232.     .Bind = HdftalkwebDriverBind, 
  233.     .Init = HdftalkwebDriverInit, 
  234.     .Release = HdftalkwebDriverRelease, 
  235. }; 
  236.  
  237. HDF_INIT(g_talkwebDriverEntry); 

4. 应用态程序

这里的应用态程序的代码和编译方法,直接可以采用上文的就可以。

这里只需要修改SAMPLE_SERVICE_NAME这个宏。

  1. #define SAMPLE_SERVICE_NAME "talkweb_service" 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-11-26 15:34:27

鸿蒙HarmonyOS应用

2023-03-16 15:18:16

2021-11-22 16:46:59

鸿蒙HarmonyOS应用

2021-12-15 15:30:38

鸿蒙HarmonyOS应用

2021-09-07 15:48:28

鸿蒙HarmonyOS应用

2022-08-08 19:35:37

HDF驱动开发鸿蒙

2021-12-23 10:02:58

鸿蒙HarmonyOS应用

2023-03-20 16:21:26

ADC数字转换器

2022-04-20 20:28:40

HDF 驱动框架鸿蒙操作系统

2021-12-15 10:02:25

鸿蒙HarmonyOS应用

2023-09-06 15:35:14

2023-09-14 15:49:42

PWM鸿蒙

2021-09-10 15:12:04

鸿蒙HarmonyOS应用

2023-03-24 14:47:24

NAPI框架HDF框架

2022-05-16 11:50:45

HDF驱动框架

2023-03-21 18:06:49

ADC数字转换器

2022-01-04 15:35:51

鸿蒙HarmonyOS应用

2023-03-20 16:05:49

HDF传感器驱动开发

2009-06-15 14:18:00

netbeans配置JDBC驱动程序

2009-07-06 18:17:46

JDBC驱动程序
点赞
收藏

51CTO技术栈公众号