了解更多开源请访问:开源基础软件社区https://ost。51cto.com接下来我们要学习如何开发驱动程序。HDF框架介绍HDF(HardwareDriverFramework)是OpenHarmony的驱动子系统,包括驱动框架、配置管理、配置分析、驱动通用框架模型、硬件通用平台能力接口等。下图是一个标准的框架模型系统,但没有VFS,在小型或轻型系统中使用时也没有这种复杂的分层。关于标准系统,小型轻量级系统的详细介绍,可以在以下链接查看官方说明:参考链接:https://gitee.com/openharmony/drivers_hdf_core本示例参考了BearPi的设计,使用BearPiHM_Micro开发板VerifyDriver开发流程图LR写驱动-->写驱动配置-->写私有配置-->添加驱动应用-->编译生成写驱动:led.c,BUILD.gn//实现Hdf结构,HdfDriverEntry(在hdf_device_desc.h中定义)类型全局变量structHdfDriverEntryg_ledDriverEntry={.moduleVersion=1,.moduleName="HDF_LED",.Bind=HdfLedDriverBind,.Init=HdfLedDriverInit,.Release=HdfLedDriverRelease,};//调用HDF_INIT将驱动入口注册到HDF框架中HDF_INIT(g_ledDriverEntry);实现相应的方法:初始化//LeddevicestructurestructTestLed{uint32_tgpioNum;};staticstructTestLedg_testLed;//读取驱动的私有配置staticint32_tLedReadDrs(structTestLed*led,conststructDeviceResourceNode*node){int32_tret;structDeviceResourceIface*drsOps=NULL;drsOps=DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if(drsOps==NULL||drsOps->GetUint32==NULL){HDF_LOGE("%s:无效的drsops!",__func__);返回HDF_FAILURE;}/*读取led.hcs中led_gpio_num的值*/ret=drsOps->GetUint32(node,"led_gpio_num",&led->gpioNum,0);if(ret!=HDF_SUCCESS){HDF_LOGE("%s:readledgpionumfail!",__func__);returnret;}returnHDF_SUCCESS;}//HDF框架:驱动初始化int32_tHdfLedDriverInit(structHdfDeviceObject*device){structTestLed*led=&g_testLed;int32_tret;if(device==NULL||device->property==NULL){HDF_LOGE("%s:deviceorpropertyNULL!",__func__);returnHDF_ERR_INVALID_OBJECT;}/*读取hcs私有属性值*/ret=LedReadDrs(led,device->property);if(ret!=HDF_SUCCESS){HDF_LOGE("%s:getleddeviceresourcefail:%d",__func__,ret);returnret;}/*将GPIO引脚配置为输出*/ret=GpioSetDir(led->gpioNum,GPIO_DIR_OUT);if(ret!=0){HDF_LOGE("GpioSerDir:failed,ret%d\n",ret);returnret;}HDF_LOGD("LeddriverInitsuccess");returnHDF_SUCCESS;}实现对应方法:初始化//HDF框架:驱动绑定int32_tHdfLedDriverBind(structHdfDeviceObject*deviceObject){if(deviceObject==NULL){HDF_LOGE("Leddriver绑定失败!”);返回HDF_ERR_INVALID_OBJECT;}staticstructIDeviceIoServiceledDriver={.Dispatch=LedDriverDispatch,};deviceObject->service=(structIDeviceIoService*)(&ledDriver);HDF_LOGD("Leddriverbindsuccess");returnHDF_SUCCESS;}实现对应方法:驱动资源释放//HDF框架:驱动资源释放voidHdfLedDriverRelease(structHdfDeviceObject*deviceObject){if(deviceObject==NULL){HDF_LOGE("Led驱动释放失败!");return;}HDF_LOGD("Led驱动释放成功");return;}驱动编译gnscriptimport("//drivers/adapter/khdf/liteos/hdf.gni")hdf_driver("hdf_led"){sources=["led.c",]}驱动配置在vendor目录下鸿蒙源码目录是不同厂商的开发板。其下有一个hdf_config目录,对应有一个device_info.hcs设备硬件配置文件。将以下内容添加到此文件中。device_led::device{//led设备节点device0::deviceNode{//leddriver的DeviceNode节点policy=2;//policy字段为驱动服务发布的策略,在驱动服务管理章节有详细介绍priority=10;//驱动启动优先级(0-200),值越大优先级越低,建议默认配置100,相同优先级不保证设备preload=1的加载顺序;//驱动按需加载字段permission=0777;//驱动创建设备节点权限moduleName="HDF_LED";//驱动名称,该字段的值必须与驱动入口结构体的moduleName值保持一致serviceName="hdf_led";//驱动对外服务的名称必须是唯一的deviceMatchAttr="st_stm32mp157_led";//驱动私有数据匹配的关键字必须等于驱动私有数据配置表中的match_attr值}}同时,同级目录下还需要添加led_config.hcs文件。root{LedDriverConfig{led_gpio_num=13;match_attr="st_stm32mp157_led";//该字段的值必须和device_info.hcs中deviceMatchAttr的值一致}}同时,还需要修改同目录下的hdf.hcs文件,添加如下代码:#include"led/led_config.hcs”编译生成。./build.sh--product-namePRODUCT_NAME//如果看到success,则编译成功。通过findout/[PRODUCT_NAME]-name"my_led"可以看到对应的应用摘要。device_info.hcs文件中的moduleName必须与驱动文件中的moduleName字段匹配,这样驱动才会被加载。device_info.hcs文件中的deviceMatchAttr字段必须与私有配置文件中led_config.hcs中的match_attr字段匹配,私有配置才能生效。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。
