1# 平台驱动移植<a name="ZH-CN_TOPIC_0000001170794079"></a> 2 3在这一步,我们会在源码目录//device/vendor\_name/soc\_name/drivers 目录下创建平台驱动,如果你要移植的SOC的厂商还没有创建仓库的话,请联系[sig-devboard](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md)创建。 4 5建议的目录结构: 6 7``` 8device 9├── vendor_name 10│ ├── drivers 11│ │ │ ├── common 12│ │ │ ├── Kconfig # 厂商驱动内核菜单入口 13│ │ │ └── lite.mk # 构建的入口 14│ ├── soc_name 15│ │ ├── drivers 16│ │ │ ├── dmac 17│ │ │ ├── gpio 18│ │ │ ├── i2c 19│ │ │ ├── LICENSE 20│ │ │ ├── mipi_dsi 21│ │ │ ├── mmc 22│ │ │ ├── pwm 23│ │ │ ├── README.md # docs 如果需要的话 24│ │ │ ├── README_zh.md 25│ │ │ ├── rtc 26│ │ │ ├── spi 27│ │ │ ├── uart 28│ │ │ └── watchdog 29│ ├── board_name 30``` 31 32HDF为所有的平台驱动都创建了驱动模型,移植平台驱动的主要工作是向模型注入实例。 这些模型你可以在源码目录//drivers/framework/support/platform/include中找到定义。 33 34本节我们会以GPIO为例,讲解如何移植平台驱动,移植过程包含以下步骤: 35 361. 创建GPIO驱动 37 38 在源码目录//device/vendor\_name/soc\_name/drivers/gpio中创建文件soc\_name\_gpio.c 内容模板如下: 39 40 ``` 41 #include "gpio_core.h" 42 43 // 定义GPIO结构体,如果需要的话 44 struct SocNameGpioCntlr { 45 struct GpioCntlr cntlr; // 这是HDF GPIO驱动框架需要的结构体 46 int myData; // 以下是当前驱动自身需要的 47 }; 48 49 // Bind 方法在HDF驱动中主要用户对外发布服务,这里我们不需要,直接返回成功即可 50 static int32_t GpioBind(struct HdfDeviceObject *device) 51 { 52 (void)device; 53 return HDF_SUCCESS; 54 } 55 56 // Init方法时驱动初始化的入口,我们需要在Init方法中完成模型实例的注册 57 static int32_t GpioInit(struct HdfDeviceObject *device) 58 { 59 SocNameGpioCntlr *impl = CreateGpio(); // 你的创建代码 60 ret = GpioCntlrAdd(&impl->cntlr); // 注册GPIO模型实例 61 if (ret != HDF_SUCCESS) { 62 HDF_LOGE("%s: err add controller:%d", __func__, ret); 63 return ret; 64 } 65 return HDF_SUCCESS; 66 } 67 68 // Release方法会在驱动卸载时被调用,这里主要完成资源回收 69 static void GpioRelease(struct HdfDeviceObject *device) 70 { 71 // GpioCntlrFromDevice 方法能从抽象的设备对象中获得init方法注册进去的模型实例。 72 struct GpioCntlr *cntlr = GpioCntlrFromDevice(device); 73 //资源释放... 74 } 75 76 struct HdfDriverEntry g_gpioDriverEntry = { 77 .moduleVersion = 1, 78 .Bind = GpioBind, 79 .Init = GpioInit, 80 .Release = GpioRelease, 81 .moduleName = "SOC_NAME_gpio_driver", // 这个名字我们稍后会在配置文件中用到,用来加载驱动。 82 }; 83 HDF_INIT(g_gpioDriverEntry); // 注册一个GPIO的驱动入口 84 ``` 85 862. 创建厂商驱动构建入口 87 88 如前所述device/vendor\_name/drivers/lite.mk是厂商驱动的构建的入口。我们需要从这个入口开始,进行构建 89 90 ``` 91 #文件device/vendor_name/drivers/lite.mk 92 93 SOC_VENDOR_NAME := $(subst $/",,$(LOSCFG_DEVICE_COMPANY)) 94 SOC_NAME := $(subst $/",,$(LOSCFG_PLATFORM)) 95 BOARD_NAME := $(subst $/",,$(LOSCFG_PRODUCT_NAME)) 96 97 # 指定SOC进行构建 98 LIB_SUBDIRS += $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ 99 ``` 100 1013. 创建SOC驱动构建入口 102 103 ``` 104 #文件device/vendor_name/soc_name/drivers/lite.mk 105 106 SOC_DRIVER_ROOT := $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR_NAME)/$(SOC_NAME)/drivers/ 107 108 # 判断如果打开了GPIO的内核编译开关 109 ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO), y) 110 # 构建完成要链接一个叫hdf_gpio的对象 111 LITEOS_BASELIB += -lhdf_gpio 112 # 增加构建目录gpio 113 LIB_SUBDIRS += $(SOC_DRIVER_ROOT)/gpio 114 endif 115 116 # 后续其他驱动在此基础上追加 117 ``` 118 1194. 创建GPIO构建入口 120 121 ``` 122 include $(LITEOSTOPDIR)/config.mk 123 include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk 124 125 # 指定输出对象的名称,注意要与SOC驱动构建入口里的LITEOS_BASELIB 保持一致 126 MODULE_NAME := hdf_gpio 127 128 # 增加HDF框架的INCLUDE 129 LOCAL_CFLAGS += $(HDF_INCLUDE) 130 131 # 要编译的文件 132 LOCAL_SRCS += soc_name_gpio.c 133 134 # 编译参数 135 LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror -fsigned-char -fno-strict-aliasing -fno-common 136 137 include $(HDF_DRIVER) 138 ``` 139 1405. 配置产品加载驱动 141 142 产品的所有设备信息被定义在源码文件//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs中。 143 144 平台驱动请添加到platform的host中。 145 146 > **说明:** 147 >moduleName要与驱动定义中的相同。 148 149 ``` 150 root { 151 ... 152 platform :: host { 153 device_gpio :: device { 154 device0 :: deviceNode { 155 policy = 0; 156 priority = 10; 157 permission = 0644; 158 moduleName = "SOC_NAME_gpio_driver"; 159 } 160 } 161 } 162 } 163 ``` 164 165 166