• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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