加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核添加HDF驱动子系统

发布时间:2023-04-03 12:44:05 所属栏目:Linux 来源:
导读:HDF驱动子系统是OpenHarmony重要的特色功能之一,其主要的功能是实现驱动程序在多内核多平台的物联网环境,实现一次驱动开发,多端部署。之前移植OHOS3.0使用了传统的linux驱动,比较遗憾,今天尝试将HDF驱动子系统加

HDF驱动子系统是OpenHarmony重要的特色功能之一,其主要的功能是实现驱动程序在多内核多平台的物联网环境,实现一次驱动开发,多端部署。之前移植OHOS3.0使用了传统的linux驱动,比较遗憾,今天尝试将HDF驱动子系统加入编译框架。开始前先了解几个名词。

HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述源码,JSON存储。

HC-GEN(HDF Configuration Generator)是 HCS 配置转换工具,可以将 HDF 配置文件HCS转换为二进制HCB。

HCB(HDF Configuration Binary)二进制文件,驱动可使用 HDF 框架提供的配置解析接口获取配置。

内核打补丁

如何在内核加入HDF驱动,linux内核下主要实现是下面两个目录:

drivers/adapter/khdf/linux 和 drivers/framework

这两个目录是通过链接的方式加入到内核编译的,流程如下:

kernel/linux/build/kernel.mk:75

$(hide) cd $(KERNEL_SRC_TMP_PATH) && patch -p1 < $(HDF_PATCH_FILE) && patch -p1 < $(DEVICE_PATCH_FILE)

可以参考3516的HDF补丁:kernel/linux/patches/linux-5.10/hi3516dv300_patch/hdf.patch

# 添加到linux内核的补丁

drivers/hdf/framework -> /drivers/framework/       # 驱动子系统驱动框架、配置管理、配置解析、驱动通用框架模型、硬件通用平台能力接口等

drivers/hdf/khdf -> /drivers/adapter/khdf/linux/   # 在linux内核中部署OpenHarmony驱动框架

drivers/hdf/Makefile                               # 由hdf.patch提供

include/hdf -> /drivers/framework/include/         # 驱动框架对外提供能力的头文件

内核配置

只是打上补丁还不行,还得在内核的编译配置文件中加入HDF选项。最开始的做法就是参考3516的配置选择,但是发现有些配置会导致编译失败。测试发现下面的配置是可以编译成功的。

[*] Enable HDF manager                     

(2)  Set HDF support platform             

[*]  Enable HDF platform driver           

[*]    Enable HDF platform mipi dsi driver

[*]    Enable HDF platform gpio driver    

[*]    Enable HDF platform i2c driver     

[*]    Enable HDF platform watchdog driver

[*] hi35xx pwm driver                      

[*] Enable HDF platform pwm driver         

[*] Enable HDF platform uart driver        

[ ] Enable HDF platform sdio driver        

[ ] Enable HDF platform emmc driver        

[*] Enable HDF platform mmc driver         

[*] Enable HDF platform spi driver         

[*] Enable HDF platform rtc driver         

[*] Enable HDF linux test                  

[*] Enable HDF Display driver              

[ ]  Enable HDF Lcdkit driver             

[*]  Enable HDF Icn9700 driver            

[ ]  Enable HDF St7789 driver             

[*] Enable HDF input driver                

[*]  Enable HDF tp 5P5 GT911 driver       

[*]  Enable HDF tp 2P35 FT6236 driver     

[ ] Enable HDF wifi                        

[ ] Enable HDF Bluetooth                   

[*] Enable HDF sensor driver               

[ ]  Enable HDF accel sensor driver       

[ ]  Enable HDF gyro sensor driver        

[ ]  Enable HDF barometer sensor driver   

[ ]  Enable HDF hall sensor driver        

[*] Enable HDF storage driver              

[ ] Enable HDF USB PNP Notify driver       

[ ] Enable F_GENERIC driver                

[ ] Enable HDF Audio driver                

[*] Enable HDF vibrator driver             

[*]  Enable HDF linear vibrator driver    

[ ] Enable HDF dsoftbus driver

CONFIG_DRIVERS_HDF=y

CONFIG_HDF_SUPPORT_LEVEL=2

CONFIG_DRIVERS_HDF_PLATFORM=y

CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y

CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y

CONFIG_DRIVERS_HDF_PLATFORM_I2C=y

CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG=y

CONFIG_PWM_HI35XX=y

CONFIG_DRIVERS_HDF_PLATFORM_PWM=y

CONFIG_DRIVERS_HDF_PLATFORM_UART=y

# CONFIG_DRIVERS_HDF_PLATFORM_SDIO is not set

# CONFIG_DRIVERS_HDF_PLATFORM_EMMC is not set

CONFIG_DRIVERS_HDF_PLATFORM_MMC=y

CONFIG_DRIVERS_HDF_PLATFORM_SPI=y

CONFIG_DRIVERS_HDF_PLATFORM_RTC=y

CONFIG_DRIVERS_HDF_TEST=y

CONFIG_DRIVERS_HDF_DISP=y

# CONFIG_DRIVERS_HDF_LCDKIT is not set

CONFIG_DRIVERS_HDF_LCD_ICN9700=y

# CONFIG_DRIVERS_HDF_LCD_ST7789 is not set

CONFIG_DRIVERS_HDF_INPUT=y

CONFIG_DRIVERS_HDF_TP_5P5_GT911=y

CONFIG_DRIVERS_HDF_TP_2P35_FT6236=y

# CONFIG_DRIVERS_HDF_WIFI is not set

# CONFIG_DRIVERS_HDF_BT is not set

CONFIG_DRIVERS_HDF_SENSOR=y

# CONFIG_DRIVERS_HDF_SENSOR_ACCEL is not set

# CONFIG_DRIVERS_HDF_SENSOR_GYRO is not set

# CONFIG_DRIVERS_HDF_SENSOR_BAROMETER is not set

# CONFIG_DRIVERS_HDF_SENSOR_HALL is not set

CONFIG_DRIVERS_HDF_STORAGE=y

# CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY is not set

# CONFIG_DRIVERS_HDF_USB_F_GENERIC is not set

# CONFIG_DRIVERS_HDF_AUDIO is not set

CONFIG_DRIVERS_HDF_VIBRATOR=y

CONFIG_DRIVERS_HDF_VIBRATOR_LINEAR=y

# CONFIG_DRIVERS_HDF_DSOFTBUS is not set

# end of Device Drivers

[*] Enable HDF linux test 是需要设置的,如果没有设置CONFIG_DRIVERS_HDF_TEST,目录结构就出问题了,会报这样的错误。

drivers/hdf/khdf/Makefile:22: PRODUCT_PATH=vendor/raspberrypi/RPI4B

scripts/Makefile.build:44: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile: No such file or directory

make[5]: *** No rule to make target 'drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile'. Stop.

CC [M] drivers/net/wireless/mac80211_hwsim.o

make[4]: *** [scripts/Makefile.build:497: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config] Error 2

make[3]: *** [scripts/Makefile.build:497: drivers/hdf/khdf] Error 2

make[2]: *** [scripts/Makefile.build:497: drivers/hdf] Error 2

make[2]: *** Waiting for unfinished jobs....

 下面3个选项要关闭,不然会报下面的错误。

[ ] Enable HDF platform sdio driver

[ ] Enable HDF platform emmc driver

[ ] Enable HDF wifi

drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioRescan':

sdio_adapter.c:(.text+0x20): undefined reference to `hisi_sdio_rescan'

sdio_adapter.c:(.text+0x34): undefined reference to `himci_get_mmc_host'

drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioFindFunc':

sdio_adapter.c:(.text+0xc84): undefined reference to `himci_get_mmc_host'

sdio_adapter.c:(.text+0xc9c): undefined reference to `himci_get_mmc_host'

sdio_adapter.c:(.text+0xcb4): undefined reference to `himci_get_mmc_host'drivers/../../../../../../drivers/adapter/khdf/linux/platform/emmc/emmc_adapter.o: In function `Hi35xxLinuxEmmcBind':

emmc_adapter.c:(.text+0x214): undefined reference to `himci_get_mmc_host'drivers/../../../../../../device/hisilicon/drivers/wifi/driver/hi3881/oal/oal_sdio_host.o: In function `sdio_card_detect_change':

oal_sdio_host.c:(.text+0x2ce8): undefined reference to `hisi_sdio_rescan'

make[1]: *** [Makefile:1179: vmlinux] Error 1

make[1]: Leaving directory '/home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10'

make: *** [kernel.mk:80: /home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10/arch/arm/boot/zImage] Error 2

ninja: build stopped: subcommand failed.

编译过程

为了方便测试可以单独进行内核编译,比如我的编译命令是这样的。

 可以分析下HDF这部分的编译过程。

linux-5.10/drivers/hdf/Makefile,hdf.patch会添加这个Makefile,将khdf文件夹加入编译。

obj-$(CONFIG_DRIVERS_HDF) += khdf/

 linux-5.10/drivers/hdf/khdf/Makefile

export HDF_ROOT := drivers/hdf

obj-$(CONFIG_DRIVERS_HDF) += osal/

obj-$(CONFIG_DRIVERS_HDF) += network/

obj-$(CONFIG_DRIVERS_HDF) += config/

SUPPORT_LEVEL_STD_H := $(shell [ "$(CONFIG_HDF_SUPPORT_LEVEL)" -ge 2 ] && echo true)

$(warning PRODUCT_PATH=$(PRODUCT_PATH))    # 会检查PRODUCT_PATH变量

ifeq ($(PRODUCT_PATH),)

$(error PRODUCT_PATH not)

endif

# 这里有条注释指明了*.hcs配置文件的存放路径

# for L2+, hcs config should in vendor/product_company/product_name/config/khdf

ifeq ($(SUPPORT_LEVEL_STD_H), true)

SUB_DIR:=khdf/

endif

# HDF test的配置会使hcs目录结构不一样,我当时没有设置CONFIG_DRIVERS_HDF_TEST就掉这个坑里了。

ifeq ($(CONFIG_DRIVERS_HDF), y)

ifeq ($(CONFIG_DRIVERS_HDF_TEST), y)

obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR)/hdf_test/

obj-$(CONFIG_DRIVERS_HDF) += test/

else

obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR)

endif

endif

# ... 后面按照配置添加一些编译目录 ...

drivers/adapter/khdf/linux/Makefile:会调用 obj-(CONFIG_DRIVERS_HDF) += ../../../../(CONFIGD​RIVERSH​DF)+=../../../../(PRODUCT_PATH)/hdf_config/$(SUB_DIR)/hdf_test/ 这是OHOS3.0默认的HCS文件存放路径。官方的注释也说明了,所以将设备对应的*.hcs存放到 vendor/raspberrypi/RPI4B/hdf_config/khdf 文件夹,参考 3516 的 vendor/hisilicon/Hi3516DV300/hdf_config/khdf/hdf.hcs 就可了。

#include "device_info/device_info.hcs"

#include "platform/i2c_config.hcs"

#include "platform/hi35xx_watchdog_config.hcs"

#include "platform/hi35xx_pwm_config.hcs"

#include "platform/hi35xx_uart_config.hcs"

#include "platform/sdio_config.hcs"

#include "platform/emmc_config.hcs"

#include "platform/hi35xx_spi_config.hcs"

#include "input/input_config.hcs"

#include "wifi/wlan_platform.hcs"

#include "wifi/wlan_chip_hi3881.hcs"

#include "sensor/sensor_config.hcs"

#include "audio/audio_config.hcs"

#include "audio/codec_config.hcs"

#include "audio/dai_config.hcs"

#include "audio/dma_config.hcs"

#include "audio/dsp_config.hcs"

#include "vibrator/vibrator_config.hcs"

#include "vibrator/linear_vibrator_config.hcs"

#include "lcd/lcd_config.hcs"

root {

   module = "hisilicon,hi35xx_chip";

}

参考 3516 的 vendor/hisilicon/Hi3516DV300/hdf_config/khdf/Makefile

其中:PRODUCT_PATH环境变量的来源:kernel/linux/build/kernel_module_build.sh:42:export PRODUCT_PATH=$4

ifeq ($(LOCAL_HCS_ROOT),)

 LOCAL_HCS_ROOT := $(PRODUCT_PATH)

endif

SOURCE_ROOT:=$(abspath ../../../../../)

HC_GEN_DIR := $(abspath $(SOURCE_ROOT)/drivers/framework/tools/hc-gen)

HC_GEN := $(HC_GEN_DIR)/build/hc-gen

LOCAL_HCS_ROOT := $(abspath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))

HCS_DIR := $(LOCAL_HCS_ROOT)

ifneq ($(TARGET_BOARD_PLATFORM),)

 HCS_DIR := $(LOCAL_HCS_ROOT)/$(TARGET_BOARD_PLATFORM)

else

 ifneq ($(CONFIG_ARCH_HI3516DV300),)

   HCS_DIR := $(LOCAL_HCS_ROOT)

 endif

 ifneq ($(CONFIG_ARCH_HI3518EV300),)

   HCS_DIR := $(LOCAL_HCS_ROOT)

 endif

endif

$(info HCS_DIR = $(HCS_DIR))

HCB_FLAGS := -b -i -a

HCS_OBJ := hdf_hcs_hex.o

HCS_OBJ_SRC := $(subst .o,.c,$(notdir $(HCS_OBJ)))

CONFIG_GEN_HEX_SRC := $(addprefix $(LOCAL_HCS_ROOT)/, $(HCS_OBJ_SRC))

CONFIG_HCS_SRC := $(subst _hcs_hex.o,.hcs,$(addprefix $(HCS_DIR)/, $(HCS_OBJ)))

$(obj)/$(HCS_OBJ): $(CONFIG_GEN_HEX_SRC)

   $(Q)$(CC) $(c_flags) -c -o $@ $<

   $(Q)rm -f $<

$(CONFIG_GEN_HEX_SRC): $(LOCAL_HCS_ROOT)/%_hcs_hex.c: $(HCS_DIR)/%.hcs | $(HC_GEN)

   $(Q)echo gen hdf built-in config

   $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi

   $(Q)$(HC_GEN) $(HCB_FLAGS) -o $(subst _hex.c,,$(@)) $<

$(CONFIG_GEN_SRCS): $(CONFIG_OUT_DIR)%.c: $(HCS_DIR)/%.hcs | $(HC_GEN)

   $(Q)echo gen hdf driver config

   $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi

   $(Q)$(HC_GEN) -t -o $@ $<

$(HC_GEN):

   $(HIDE)make -C $(HC_GEN_DIR)

obj-$(CONFIG_DRIVERS_HDF) += $(HCS_OBJ) 

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!