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