别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述#星光计划2.0# linux内核增加HDF驱动子系统相关的知识,希望能为你提供帮助。
【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】
前言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)
【#星光计划2.0# linux内核增加HDF驱动子系统】可以参考3516的HDF补丁:kernel\\linux\\patches\\linux-5.10\\hi3516dv300_patch\\hdf.patch
patching file drivers/Kconfig
patching file drivers/Makefile
patching file drivers/hdf/Makefile
patching symbolic link drivers/hdf/framework
patching symbolic link drivers/hdf/khdf
patching symbolic link include/hdf# 添加到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 driverCONFIG_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.
编译过程为了方便测试可以单独进行内核编译,比如我的编译命令是这样的。
./build.sh --product-name RPI4B --ccache --build-target raspberrypi_products
可以分析下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) += ../../../../$(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)
endifSOURCE_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 -aHCS_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)
查看结果编译完成后,可以上传内核镜像到开发板,来查看HDF驱动框架是否启动成功。
加入HDF前
# ls dev/
__parameters__hwrngtty1tty28tty46tty7
__trigger__inputtty10tty29tty47tty8
autofskmsgtty11tty3tty48tty9
binderlinux,cmatty12tty30tty49ttyAMA0
blockloop-controltty13tty31tty5ttyS0
busmemtty14tty32tty50ttyprintk
cachefilesmemcgtty15tty33tty51unix
charnulltty16tty34tty52urandom
consoleporttty17tty35tty53vchiq
cpuctlptmxtty18tty36tty54vcs
cpusetptstty19tty37tty55vcs1
drirandomtty2tty38tty56vcsa
fdrawctltty20tty39tty57vcsa1
freezersndtty21tty4tty58vcsu
fscklogsstderrtty22tty40tty59vcsu1
fullstdintty23tty41tty6vga_arbiter
gpiochip0stdouttty24tty42tty60vndbinder
gpiochip1systemtty25tty43tty61watchdog
graphicsttytty26tty44tty62watchdog0
hwbindertty0tty27tty45tty63zero
加入HDF后
# ls dev/
HDF_PLATFORM_I2C_MANAGERloop-controltty24tty54
HDF_PLATFORM_UART_1memtty25tty55
HDF_TESTmemcgtty26tty56
I2C_TESTnulltty27tty57
__parameters__porttty28tty58
__trigger__ptmxtty29tty59
autofsptstty3tty6
binderrandomtty30tty60
blockrawctltty31tty61
bussample_servicetty32tty62
cachefilessndtty33tty63
charstderrtty34tty7
consolestdintty35tty8
cpuctlstdouttty36tty9
cpusetsystemtty37ttyAMA0
dev_mgrttytty38ttyS0
dritty0tty39ttyprintk
fdtty1tty4unix
freezertty10tty40urandom
fscklogstty11tty41vchiq
fulltty12tty42vcs
gpiochip0tty13tty43vcs1
gpiochip1tty14tty44vcsa
graphicstty15tty45vcsa1
hdf_bltty16tty46vcsu
hdf_input_hosttty17tty47vcsu1
hdf_misc_vibratortty18tty48vga_arbiter
hdf_sensor_manager_aptty19tty49vndbinder
hwbindertty2tty5watchdog
hwrngtty20tty50watchdog0
inputtty21tty51zero
kmsgtty22tty52
linux,cmatty23tty53
基本算是启动成功了,接下来考虑打算用HDF的方式添加一下设备。来验证HDF驱动框架是否运转正常。
想了解更多关于鸿蒙的内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com/#bkwz
::: hljs-center
文章图片
:::
推荐阅读
- 从一次 SQL 查询的全过程看 DolphinDB 的线程模型
- 学习Java必备的基础知识打卡12.16,要想学好必须扎实基本功(?建议收藏)#yyds干货盘点#
- Python | Python常用函数方法示例总结(API)#yyds干货盘点#
- 声临其境,轻松几步教你把音频变成3D环绕音
- #yyds干货盘点# MySQL性能优化(如何高效正确的使用索引)
- 更强大更灵活更全面丨一文搞懂DolphinDB窗口计算
- 如何快速找到Java开发工作()
- EasyNVR查看直播视频流显示黑屏原因排查
- Shell编程之循环语句和函数