Linux内核增加HDF驱动子系统

系统 Linux
HDF驱动子系统是OpenHarmony重要的特色功能之一,其主要的功能是实现驱动程序在多内核多平台的物联网环境,实现一次驱动开发,多端部署。

[[440302]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

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

  1. $(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

  1. patching file drivers/Kconfig 
  2. patching file drivers/Makefile 
  3. patching file drivers/hdf/Makefile 
  4. patching symbolic link drivers/hdf/framework 
  5. patching symbolic link drivers/hdf/khdf 
  6. patching symbolic link include/hdf 
  7.  
  8. # 添加到linux内核的补丁 
  9. drivers/hdf/framework -> /drivers/framework/        # 驱动子系统驱动框架、配置管理、配置解析、驱动通用框架模型、硬件通用平台能力接口等 
  10. drivers/hdf/khdf -> /drivers/adapter/khdf/linux/    # 在linux内核中部署OpenHarmony驱动框架 
  11. drivers/hdf/Makefile                                # 由hdf.patch提供 
  12. include/hdf -> /drivers/framework/include/          # 驱动框架对外提供能力的头文件 

内核配置

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

  1. [*] Enable HDF manager                      
  2. (2)   Set HDF support platform              
  3. [*]   Enable HDF platform driver            
  4. [*]     Enable HDF platform mipi dsi driver 
  5. [*]     Enable HDF platform gpio driver     
  6. [*]     Enable HDF platform i2c driver      
  7. [*]     Enable HDF platform watchdog driver 
  8. [*] hi35xx pwm driver                       
  9. [*] Enable HDF platform pwm driver          
  10. [*] Enable HDF platform uart driver         
  11. [ ] Enable HDF platform sdio driver         
  12. [ ] Enable HDF platform emmc driver         
  13. [*] Enable HDF platform mmc driver          
  14. [*] Enable HDF platform spi driver          
  15. [*] Enable HDF platform rtc driver          
  16. [*] Enable HDF linux test                   
  17. [*] Enable HDF Display driver               
  18. [ ]   Enable HDF Lcdkit driver              
  19. [*]   Enable HDF Icn9700 driver             
  20. [ ]   Enable HDF St7789 driver              
  21. [*] Enable HDF input driver                 
  22. [*]   Enable HDF tp 5P5 GT911 driver        
  23. [*]   Enable HDF tp 2P35 FT6236 driver      
  24. [ ] Enable HDF wifi                         
  25. [ ] Enable HDF Bluetooth                    
  26. [*] Enable HDF sensor driver                
  27. [ ]   Enable HDF accel sensor driver        
  28. [ ]   Enable HDF gyro sensor driver         
  29. [ ]   Enable HDF barometer sensor driver    
  30. [ ]   Enable HDF hall sensor driver         
  31. [*] Enable HDF storage driver               
  32. [ ] Enable HDF USB PNP Notify driver        
  33. [ ] Enable F_GENERIC driver                 
  34. [ ] Enable HDF Audio driver                 
  35. [*] Enable HDF vibrator driver              
  36. [*]   Enable HDF linear vibrator driver     
  37. [ ] Enable HDF dsoftbus driver 
  38.  
  39. CONFIG_DRIVERS_HDF=y 
  40. CONFIG_HDF_SUPPORT_LEVEL=2 
  41. CONFIG_DRIVERS_HDF_PLATFORM=y 
  42. CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y 
  43. CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y 
  44. CONFIG_DRIVERS_HDF_PLATFORM_I2C=y 
  45. CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG=y 
  46. CONFIG_PWM_HI35XX=y 
  47. CONFIG_DRIVERS_HDF_PLATFORM_PWM=y 
  48. CONFIG_DRIVERS_HDF_PLATFORM_UART=y 
  49. # CONFIG_DRIVERS_HDF_PLATFORM_SDIO is not set 
  50. # CONFIG_DRIVERS_HDF_PLATFORM_EMMC is not set 
  51. CONFIG_DRIVERS_HDF_PLATFORM_MMC=y 
  52. CONFIG_DRIVERS_HDF_PLATFORM_SPI=y 
  53. CONFIG_DRIVERS_HDF_PLATFORM_RTC=y 
  54. CONFIG_DRIVERS_HDF_TEST=y 
  55. CONFIG_DRIVERS_HDF_DISP=y 
  56. # CONFIG_DRIVERS_HDF_LCDKIT is not set 
  57. CONFIG_DRIVERS_HDF_LCD_ICN9700=y 
  58. # CONFIG_DRIVERS_HDF_LCD_ST7789 is not set 
  59. CONFIG_DRIVERS_HDF_INPUT=y 
  60. CONFIG_DRIVERS_HDF_TP_5P5_GT911=y 
  61. CONFIG_DRIVERS_HDF_TP_2P35_FT6236=y 
  62. # CONFIG_DRIVERS_HDF_WIFI is not set 
  63. # CONFIG_DRIVERS_HDF_BT is not set 
  64. CONFIG_DRIVERS_HDF_SENSOR=y 
  65. # CONFIG_DRIVERS_HDF_SENSOR_ACCEL is not set 
  66. # CONFIG_DRIVERS_HDF_SENSOR_GYRO is not set 
  67. # CONFIG_DRIVERS_HDF_SENSOR_BAROMETER is not set 
  68. # CONFIG_DRIVERS_HDF_SENSOR_HALL is not set 
  69. CONFIG_DRIVERS_HDF_STORAGE=y 
  70. # CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY is not set 
  71. # CONFIG_DRIVERS_HDF_USB_F_GENERIC is not set 
  72. # CONFIG_DRIVERS_HDF_AUDIO is not set 
  73. CONFIG_DRIVERS_HDF_VIBRATOR=y 
  74. CONFIG_DRIVERS_HDF_VIBRATOR_LINEAR=y 
  75. # CONFIG_DRIVERS_HDF_DSOFTBUS is not set 
  76. end of Device Drivers 

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

  1. drivers/hdf/khdf/Makefile:22: PRODUCT_PATH=vendor/raspberrypi/RPI4B 
  2. scripts/Makefile.build:44: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile: No such file or directory 
  3. make[5]: *** No rule to make target 'drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config/Makefile'.  Stop. 
  4. CC [M]  drivers/net/wireless/mac80211_hwsim.o 
  5. make[4]: *** [scripts/Makefile.build:497: drivers/hdf/khdf/../../../../vendor/raspberrypi/RPI4B/hdf_config] Error 2 
  6. make[3]: *** [scripts/Makefile.build:497: drivers/hdf/khdf] Error 2 
  7. make[2]: *** [scripts/Makefile.build:497: drivers/hdf] Error 2 
  8. make[2]: *** Waiting for unfinished jobs.... 

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

[ ] Enable HDF platform sdio driver

[ ] Enable HDF platform emmc driver

[ ] Enable HDF wifi

  1. drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioRescan': 
  2. sdio_adapter.c:(.text+0x20): undefined reference to `hisi_sdio_rescan' 
  3. sdio_adapter.c:(.text+0x34): undefined reference to `himci_get_mmc_host' 
  4. drivers/../../../../../../drivers/adapter/khdf/linux/platform/sdio/sdio_adapter.o: In function `Hi35xxLinuxSdioFindFunc': 
  5. sdio_adapter.c:(.text+0xc84): undefined reference to `himci_get_mmc_host' 
  6. sdio_adapter.c:(.text+0xc9c): undefined reference to `himci_get_mmc_host' 
  7. sdio_adapter.c:(.text+0xcb4): undefined reference to `himci_get_mmc_host' 
  8. drivers/../../../../../../drivers/adapter/khdf/linux/platform/emmc/emmc_adapter.o: In function `Hi35xxLinuxEmmcBind': 
  9. emmc_adapter.c:(.text+0x214): undefined reference to `himci_get_mmc_host' 
  10. drivers/../../../../../../device/hisilicon/drivers/wifi/driver/hi3881/oal/oal_sdio_host.o: In function `sdio_card_detect_change': 
  11. oal_sdio_host.c:(.text+0x2ce8): undefined reference to `hisi_sdio_rescan' 
  12. make[1]: *** [Makefile:1179: vmlinux] Error 1 
  13. make[1]: Leaving directory '/home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10' 
  14. make: *** [kernel.mk:80: /home/liangzili/ohos/out/KERNEL_OBJ/kernel/src_tmp/linux-5.10/arch/arm/boot/zImage] Error 2 
  15. ninja: build stopped: subcommand failed. 

编译过程

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

  1. ./build.sh --product-name RPI4B --ccache --build-target raspberrypi_products 

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

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

  1. obj-$(CONFIG_DRIVERS_HDF) += khdf/ 

 linux-5.10\drivers\hdf\khdf\Makefile

  1. export HDF_ROOT := drivers/hdf 
  2. obj-$(CONFIG_DRIVERS_HDF)  += osal/ 
  3. obj-$(CONFIG_DRIVERS_HDF)  += network/ 
  4. obj-$(CONFIG_DRIVERS_HDF)  += config/ 
  5.  
  6. SUPPORT_LEVEL_STD_H := $(shell [ "$(CONFIG_HDF_SUPPORT_LEVEL)" -ge 2 ] && echo true
  7.  
  8. $(warning PRODUCT_PATH=$(PRODUCT_PATH))     # 会检查PRODUCT_PATH变量 
  9. ifeq ($(PRODUCT_PATH),) 
  10. $(error PRODUCT_PATH not
  11. endif 
  12.  
  13. # 这里有条注释指明了*.hcs配置文件的存放路径 
  14. for L2+, hcs config should in vendor/product_company/product_name/config/khdf 
  15. ifeq ($(SUPPORT_LEVEL_STD_H), true
  16. SUB_DIR:=khdf/ 
  17. endif 
  18.  
  19. # HDF test的配置会使hcs目录结构不一样,我当时没有设置CONFIG_DRIVERS_HDF_TEST就掉这个坑里了。 
  20. ifeq ($(CONFIG_DRIVERS_HDF), y) 
  21. ifeq ($(CONFIG_DRIVERS_HDF_TEST), y) 
  22. obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR)/hdf_test/ 
  23. obj-$(CONFIG_DRIVERS_HDF) += test/ 
  24. else 
  25. obj-$(CONFIG_DRIVERS_HDF) += ../../../../$(PRODUCT_PATH)/hdf_config/$(SUB_DIR) 
  26. endif 
  27. endif 
  28. # ... 后面按照配置添加一些编译目录 ... 

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 就可了。

  1. #include "device_info/device_info.hcs" 
  2. #include "platform/i2c_config.hcs" 
  3. #include "platform/hi35xx_watchdog_config.hcs" 
  4. #include "platform/hi35xx_pwm_config.hcs" 
  5. #include "platform/hi35xx_uart_config.hcs" 
  6. #include "platform/sdio_config.hcs" 
  7. #include "platform/emmc_config.hcs" 
  8. #include "platform/hi35xx_spi_config.hcs" 
  9. #include "input/input_config.hcs" 
  10. #include "wifi/wlan_platform.hcs" 
  11. #include "wifi/wlan_chip_hi3881.hcs" 
  12. #include "sensor/sensor_config.hcs" 
  13. #include "audio/audio_config.hcs" 
  14. #include "audio/codec_config.hcs" 
  15. #include "audio/dai_config.hcs" 
  16. #include "audio/dma_config.hcs" 
  17. #include "audio/dsp_config.hcs" 
  18. #include "vibrator/vibrator_config.hcs" 
  19. #include "vibrator/linear_vibrator_config.hcs" 
  20. #include "lcd/lcd_config.hcs" 
  21.  
  22. root { 
  23.     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

  1. ifeq ($(LOCAL_HCS_ROOT),) 
  2.   LOCAL_HCS_ROOT := $(PRODUCT_PATH) 
  3. endif 
  4.  
  5. SOURCE_ROOT:=$(abspath ../../../../../) 
  6.  
  7. HC_GEN_DIR := $(abspath $(SOURCE_ROOT)/drivers/framework/tools/hc-gen) 
  8. HC_GEN := $(HC_GEN_DIR)/build/hc-gen 
  9. LOCAL_HCS_ROOT := $(abspath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))) 
  10.  
  11. HCS_DIR := $(LOCAL_HCS_ROOT) 
  12.  
  13. ifneq ($(TARGET_BOARD_PLATFORM),) 
  14.   HCS_DIR := $(LOCAL_HCS_ROOT)/$(TARGET_BOARD_PLATFORM) 
  15. else 
  16.   ifneq ($(CONFIG_ARCH_HI3516DV300),) 
  17.     HCS_DIR := $(LOCAL_HCS_ROOT) 
  18.   endif 
  19.   ifneq ($(CONFIG_ARCH_HI3518EV300),) 
  20.     HCS_DIR := $(LOCAL_HCS_ROOT) 
  21.   endif 
  22. endif 
  23. $(info HCS_DIR = $(HCS_DIR)) 
  24. HCB_FLAGS := -b -i -a 
  25.  
  26. HCS_OBJ := hdf_hcs_hex.o 
  27. HCS_OBJ_SRC := $(subst .o,.c,$(notdir $(HCS_OBJ))) 
  28.  
  29. CONFIG_GEN_HEX_SRC := $(addprefix $(LOCAL_HCS_ROOT)/, $(HCS_OBJ_SRC)) 
  30. CONFIG_HCS_SRC := $(subst _hcs_hex.o,.hcs,$(addprefix $(HCS_DIR)/, $(HCS_OBJ))) 
  31.  
  32. $(obj)/$(HCS_OBJ): $(CONFIG_GEN_HEX_SRC) 
  33.     $(Q)$(CC) $(c_flags) -c -o $@ $< 
  34.     $(Q)rm -f $< 
  35.  
  36. $(CONFIG_GEN_HEX_SRC):  $(LOCAL_HCS_ROOT)/%_hcs_hex.c: $(HCS_DIR)/%.hcs | $(HC_GEN) 
  37.     $(Q)echo gen hdf built-in config 
  38.     $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi 
  39.     $(Q)$(HC_GEN) $(HCB_FLAGS) -o $(subst _hex.c,,$(@)) $< 
  40.  
  41. $(CONFIG_GEN_SRCS): $(CONFIG_OUT_DIR)%.c: $(HCS_DIR)/%.hcs | $(HC_GEN) 
  42.     $(Q)echo gen hdf driver config 
  43.     $(Q)if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi 
  44.     $(Q)$(HC_GEN) -t -o $@ $< 
  45.  
  46. $(HC_GEN): 
  47.     $(HIDE)make -C $(HC_GEN_DIR) 
  48.  
  49. obj-$(CONFIG_DRIVERS_HDF) += $(HCS_OBJ) 

查看结果

编译完成后,可以上传内核镜像到开发板,来查看HDF驱动框架是否启动成功。

加入HDF前:

  1. # ls dev/ 
  2. __parameters__  hwrng         tty1   tty28  tty46  tty7 
  3. __trigger__     input         tty10  tty29  tty47  tty8 
  4. autofs          kmsg          tty11  tty3   tty48  tty9 
  5. binder          linux,cma     tty12  tty30  tty49  ttyAMA0 
  6. block           loop-control  tty13  tty31  tty5   ttyS0 
  7. bus             mem           tty14  tty32  tty50  ttyprintk 
  8. cachefiles      memcg         tty15  tty33  tty51  unix 
  9. char            null          tty16  tty34  tty52  urandom 
  10. console         port          tty17  tty35  tty53  vchiq 
  11. cpuctl          ptmx          tty18  tty36  tty54  vcs 
  12. cpuset          pts           tty19  tty37  tty55  vcs1 
  13. dri             random        tty2   tty38  tty56  vcsa 
  14. fd              rawctl        tty20  tty39  tty57  vcsa1 
  15. freezer         snd           tty21  tty4   tty58  vcsu 
  16. fscklogs        stderr        tty22  tty40  tty59  vcsu1 
  17. full            stdin         tty23  tty41  tty6   vga_arbiter 
  18. gpiochip0       stdout        tty24  tty42  tty60  vndbinder 
  19. gpiochip1       system        tty25  tty43  tty61  watchdog 
  20. graphics        tty           tty26  tty44  tty62  watchdog0 
  21. hwbinder        tty0          tty27  tty45  tty63  zero 

 加入HDF后:

  1. # ls dev/ 
  2. HDF_PLATFORM_I2C_MANAGER  loop-control    tty24  tty54 
  3. HDF_PLATFORM_UART_1       mem             tty25  tty55 
  4. HDF_TEST                  memcg           tty26  tty56 
  5. I2C_TEST                  null            tty27  tty57 
  6. __parameters__            port            tty28  tty58 
  7. __trigger__               ptmx            tty29  tty59 
  8. autofs                    pts             tty3   tty6 
  9. binder                    random          tty30  tty60 
  10. block                     rawctl          tty31  tty61 
  11. bus                       sample_service  tty32  tty62 
  12. cachefiles                snd             tty33  tty63 
  13. char                      stderr          tty34  tty7 
  14. console                   stdin           tty35  tty8 
  15. cpuctl                    stdout          tty36  tty9 
  16. cpuset                    system          tty37  ttyAMA0 
  17. dev_mgr                   tty             tty38  ttyS0 
  18. dri                       tty0            tty39  ttyprintk 
  19. fd                        tty1            tty4   unix 
  20. freezer                   tty10           tty40  urandom 
  21. fscklogs                  tty11           tty41  vchiq 
  22. full                      tty12           tty42  vcs 
  23. gpiochip0                 tty13           tty43  vcs1 
  24. gpiochip1                 tty14           tty44  vcsa 
  25. graphics                  tty15           tty45  vcsa1 
  26. hdf_bl                    tty16           tty46  vcsu 
  27. hdf_input_host            tty17           tty47  vcsu1 
  28. hdf_misc_vibrator         tty18           tty48  vga_arbiter 
  29. hdf_sensor_manager_ap     tty19           tty49  vndbinder 
  30. hwbinder                  tty2            tty5   watchdog 
  31. hwrng                     tty20           tty50  watchdog0 
  32. input                     tty21           tty51  zero 
  33. kmsg                      tty22           tty52 
  34. linux,cma                 tty23           tty53 

 基本算是启动成功了,接下来考虑打算用HDF的方式添加一下设备。来验证HDF驱动框架是否运转正常。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2015-10-19 17:36:19

MOST内核Linux

2016-07-22 10:50:56

Linux内核无线子系统

2021-08-31 11:53:38

Linux inputLinux 系统

2021-08-10 11:30:30

Linux代码中断控制器

2021-08-03 15:10:26

Linux代码驱动

2021-04-06 11:18:47

LinuxWWAN子系统驱动

2021-07-07 08:00:00

Linux开发虚拟机

2011-08-16 16:20:33

Linuxkconfigmakefile

2009-10-12 12:46:55

Linux内核SCSI IO

2022-01-16 07:41:46

Windows 11操作系统微软

2023-03-20 16:21:26

ADC数字转换器

2022-08-08 19:35:37

HDF驱动开发鸿蒙

2019-07-15 08:30:06

Linux 系统 数据

2023-03-21 18:06:49

ADC数字转换器

2015-08-03 10:43:58

Linux内核驱动

2022-10-08 11:57:30

Linux内核架构

2021-08-17 14:39:00

鸿蒙HarmonyOS应用

2021-11-26 15:34:27

鸿蒙HarmonyOS应用

2022-10-17 14:29:24

鸿蒙应用开发

2023-03-24 14:47:24

NAPI框架HDF框架
点赞
收藏

51CTO技术栈公众号