往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
- OpenHarmony(鸿蒙南向开发)——轻量系统芯片移植指南(一)
- OpenHarmony(鸿蒙南向开发)——轻量系统芯片移植指南(二)
- OpenHarmony(鸿蒙南向开发)——轻量系统芯片移植指南(三)
- OpenHarmony(鸿蒙南向开发)——轻量系统芯片内核移植
- OpenHarmony(鸿蒙南向开发)——小型系统芯片移植指南(一)
- OpenHarmony(鸿蒙南向开发)——小型系统芯片移植指南(二)
- OpenHarmony(鸿蒙南向开发)——小型系统芯片移植指南(三)
- 持续更新中……
移植概述
驱动主要包含两部分,平台驱动和器件驱动。平台驱动主要包括通常在SOC内的GPIO、I2C、SPI等;器件驱动则主要包含通常在SOC外的器件,如 LCD、TP、WLAN等
图1 OpenHarmony 驱动分类
HDF驱动被设计为可以跨OS使用的驱动程序,HDF驱动框架会为驱动达成这个目标提供有力的支撑。开发HDF驱动中,请尽可能只使用HDF驱动框架提供的接口,否则会导致驱动丧失跨OS使用的特性。在开始驱动开发前,建议先了解HDF驱动框架。
平台驱动移植
在这一步,我们会在源码目录//device/vendor_name/soc_name/drivers
目录下创建平台驱动,如果你要移植的SOC的厂商还没有创建仓库的话,请联系 sig_devboard 创建。
建议的目录结构:
device
├── vendor_name
│ ├── drivers
│ │ │ ├── common
│ │ │ ├── Kconfig # 厂商驱动内核菜单入口
│ │ │ └── lite.mk # 构建的入口
│ ├── soc_name
│ │ ├── drivers
│ │ │ ├── dmac
│ │ │ ├── gpio
│ │ │ ├── i2c
│ │ │ ├── LICENSE
│ │ │ ├── mipi_dsi
│ │ │ ├── mmc
│ │ │ ├── pwm
│ │ │ ├── README.md # docs 如果需要的话
│ │ │ ├── README_zh.md
│ │ │ ├── rtc
│ │ │ ├── spi
│ │ │ ├── uart
│ │ │ └── watchdog
│ ├── board_name
HDF为所有的平台驱动都创建了驱动模型,移植平台驱动的主要工作是向模型注入实例。 这些模型你可以在源码目录//drivers/hdf_core/framework/support/platform/include
中找到定义。
本节我们会以GPIO为例,讲解如何移植平台驱动,移植过程包含以下步骤:
- 创建GPIO驱动
在源码目录//device/vendor_name/soc_name/drivers/gpio
中创建文件soc_name_gpio.c
。内容模板如下:
#include "gpio_core.h"
// 定义GPIO结构体,如果需要的话
struct SocNameGpioCntlr {
struct GpioCntlr cntlr; // 这是HDF GPIO驱动框架需要的结构体
int myData; // 以下是当前驱动自身需要的
};
// Bind 方法在HDF驱动中主要用户对外发布服务,这里我们不需要,直接返回成功即可
static int32_t GpioBind(struct HdfDeviceObject *device)
{
(void)device;
return HDF_SUCCESS;
}
// Init方法时驱动初始化的入口,我们需要在Init方法中完成模型实例的注册
static int32_t GpioInit(struct HdfDeviceObject *device)
{
SocNameGpioCntlr *impl = CreateGpio(); // 你的创建代码
ret = GpioCntlrAdd(&impl->cntlr); // 注册GPIO模型实例
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: err add controller:%d", __func__, ret);
return ret;
}
return HDF_SUCCESS;
}
// Release方法会在驱动卸载时被调用,这里主要完成资源回收
static void GpioRelease(struct HdfDeviceObject *device)
{
// GpioCntlrFromDevice 方法能从抽象的设备对象中获得init方法注册进去的模型实例。
struct GpioCntlr *cntlr = GpioCntlrFromDevice(device);
//资源释放...
}
struct HdfDriverEntry g_gpioDriverEntry = {
.moduleVersion = 1,
.Bind = GpioBind,
.Init