OpenHarmony实战:轻量带屏解决方案之恒玄芯片移植案例

本文章基于恒玄科技 BES2600W 芯片的欧智通 Multi-modal V200Z-R 开发板,进行轻量带屏开发板的标准移植,开发了智能开关面板样例,同时实现了 ace_engine_litearkui_ui_liteaafwk_liteappexecfwk_liteHDF 等部件基于 OpenHarmony LiteOS-M 内核的适配。移植架构上采用 Board 与 SoC 分离的方案,工具链 Newlib C 库与 Musl C 库可选,LiteOS-M 内核编译采用 gn 结合 Kconfig 图形化配置等需求。

编译构建

目录规划

本案例在芯片移植架构方面进行了一些改进,以前的芯片适配目录规划为:

device
└── <device_company>
    └── <device_name>

这样会导致,小熊派 BearPi-HM Nano 开发板与润和的 HiSpark Pegasus 开发板使用小海思的 hi3861 的 SoC 时,需要在这两款开发板里面都放置一份重复的代码。为了解决该问题,本案例将单板厂商与 SoC 厂商进行分离,可以参考 Board 和 SoC 解耦的设计思路,并把芯片适配目录规划为:

device
├── board                                --- 单板厂商目录
│   └── fnlink                           --- 单板厂商名字:欧智通
│       └── v200zr                       --- 单板名:v200zr
└── soc									 --- SoC厂商目录
    └── bestechnic                       --- SoC厂商名字:恒玄
        └── bes2600						 --- SoC Series名:bes2600是一个系列,里面包含bes2600w等SoC名

产品样例目录规划为:

vendor
└── bestechnic							 --- 开发产品样例厂商目录,恒玄开发的带屏样例,因此以bestechnic命名
    └── display_demo         			 --- 产品名字:以智能开关面板的带屏显示样例

预编译适配

在进行移植之前,需要进行预编译适配。
预编译适配主要使用 hb set 命令,设置整个项目的根目录、单板目录、产品目录、单板公司名等环境变量,为编译做准备。
具体的预编译适配步骤如下:

  1. 在 vendor/bestechnic/display_demo 目录下新增 config.json 文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容:
{
  "product_name": "display_demo",       --- 用于hb set进行选择时,显示的产品名称
  "type": "mini",                       --- 构建系统的类型,mini/small/standard
  "version": "3.0",                     --- 构建系统的版本,1.0/2.0/3.0
  "device_company": "fnlink",           --- 单板厂商名,用于编译时找到/device/board/fnlink目录
  "board": "v200zr",                    --- 单板名,用于编译时找到/device/board/fnlink/v200zr目录
  "kernel_type": "liteos_m",            --- 内核类型,因为OpenHarmony支持多内核,一块单板可能适配了多个内核,所以需要指定某个内核进行编译
  "kernel_version": "3.0.0",            --- 内核版本,一块单板可能适配了多个linux内核版本,所以需要指定某个具体的内核版本进行编译
  "subsystems": [ ]                     --- 选择所需要编译构建的子系统
}
  1. 在 device/board/fnlink/v200zr/liteos_m 目录下新增 config.gni 文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容:
# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
kernel_type = "liteos_m"                --- 内核类型,跟config.json中kernel_type对应
# Kernel version.
kernel_version = "3.0.0"                --- 内核版本,跟config.json中kernel_version对应
  1. 验证 hb set 配置是否正确,输入 hb set 能够显示如下图片表示配置正确。
    执行 hb set 输入项目根目录,并且回车,hb 命令会遍历所有 //vendor/<product_company>/<product_name> 目录下的 config.json,给出可选产品编译选项,config.json 的 product_name 用于显示产品名,device_company 和 board 用于关联出 //device/board/<device_company>/<board> 目录,并且匹配 <any_dir_name>/config.gni 文件,如果能够匹配多个文件,表示该单板适配了多个内核,那么可以根据 config.json 的 kernel_type 和 kernel_version 来唯一匹配 config.gni 的 kernel_type 和 kernel_version,即可确定了需要编译适配了哪个内核的单板。

    通过 hb env 可以查看选择出来的预编译环境变量。

    在执行 hb build 之前,需要准备好 LiteOS-M 内核适配,具体适配步骤请参内核移植

内核移植

内核移植需要完成 LiteOS-M Kconfig 适配、gn 的编译构建和内核启动最小适配。

LiteOS-M Kconfig 适配

在 //kernel/liteos_m 目录下执行 make menuconfig 命令,完成编译配置选项的选择。在 Makefile 文件中,会将 hb env 的结果转换成环境变量,即 PRODUCT_PATHDEVICE_PATH 和 BOARD_COMPANY。如下代码块所示:

$(foreach line,$(shell hb env | sed 's/\[OHOS INFO\]/ohos/g;s/ /_/g;s/:_/=/g' || true),$(eval $(line)))
ifneq ($(ohos_kernel),liteos_m)
$(error The selected product ($(ohos_product)) is not a liteos_m kernel type product)
endif
--- 将hb env的每一行输出转化为变量形式,例如将[OHOS INFO] device company: fnlink转换为ohos_device_company=fnlink
……
ifeq ($(BOARD_COMPANY),)
BOARD_COMPANY:=$(ohos_device_company)
endif
……
export BOARD_COMPANY
--- 将ohos_device_company转化为BOARD_COMPANY环境变量

在 //kernel/liteos_m/Kconfig 文件中使用这些导出的环境变量,Kconfiglib 采用 ulfalizer 开发基于 python 的版本,源码地址功能介绍连接参考,里面用到了 orsource 关键字,其中 o 表示 optional,表示这个文件是否存在可选,r 表示 relative,表示这个文件相对当前文件的相对路径。

config SOC_COMPANY
    string "SoC company name to locate soc build path"
    help
      This option specifies the SoC company name, used to locate the build path for soc. This option is set by the
      SoC's Kconfig file, and should be exactly the same with SoC company path, and the user should generally avoid
       modifying it via the menu configuration.
orsource "../../device/board/*/Kconfig.liteos_m.shields"                                 --- 将所有扩展板配置信息加载进来,因为单板厂商A提供扩展板可以给单板厂商B使用,所以这里使用*匹配所有的扩展板,而非BOARD_COMPANY。另外由于OpenHarmony支持多内核设计,Kconfig文件采用liteos_m作为后缀,在进行单板适配过程中,其他内核在适配过程中,可以使用对应的内核名作为后缀名进行扩展。
orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.defconfig.boards"         --- 加载BOARD_COMPANY的所有单板预定义配置
choice
    prompt "Board Selection"
orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.boards"                   --- 提供Board选择列表
endchoice
orsource "../../device/soc/*/Kconfig.liteos_m.defconfig"                                 --- 加载所有SoC的默认配置定义
choice
    prompt "SoC Series Selection"
orsource "../../device/soc/*/Kconfig.liteos_m.series"                                    --- 提供所有SoC Series选择列表
endchoice
orsource "../../device/soc/*/Kconfig.liteos_m.soc"                                       --- 加载所有SoC配置

从 //kernel/liteos_m/Kconfig 文件可以看出需要在 //device/board/fnlink 目录下新增如下 Kconfig 文件进行适配:

.
├── v200zr                                       --- v200zr单板配置目录
│   ├── Kconfig.liteos_m.board                   --- 提供v200zr单板的配置选项
│   ├── Kconfig.liteos_m.defconfig.board         --- 提供v200zr单板的默认配置项
│   └── liteos_m
│       └── config.gni
├── Kconfig.liteos_m.boards                      --- 提供fnlink单板厂商下Boards配置信息
├── Kconfig.liteos_m.defconfig.boards			 --- 提供fnlink单板厂商下Boards默认配置信息
├── Kconfig.liteos_m.shields					 --- 提供fnlink单板厂商下扩展板配置信息
└── shields										 --- fnlink单板厂商的扩展板目录
    ├── v200zr-t0								 --- fnlink单板厂商的扩展板v200zr-t0
    │   ├── Kconfig.liteos_m.defconfig.shield	 --- 扩展板v200zr-t0默认配置
    │   └── Kconfig.liteos_m.shield				 --- 扩展板v200zr-t0配置信息
    ├── v200zr-t1
    │   ├── Kconfig.liteos_m.defconfig.shield
    │   └── Kconfig.liteos_m.shield
    └── Kconfig.liteos_m.shields

在 v200zr/Kconfig.liteos_m.board 需要配置选择该单板的选项,以及它依赖的 SoC,如下:

config BOARD_v200zr
    bool "select board v200zr"
    depends on SOC_BES2600W		 --- v200zr单板用的bes2600w的SoC,只有 bes2600w的SoC被选择后,v200zr单板配置选项才可见,可以被选择。

在 v200zr/Kconfig.liteos_m.defconfig.board 需要配置选择该单板后,默认定义 BOARD 的名字为 "v200zr" ,如下:

if BOARD_v200zr
config BOARD
    string		 --- string后没有带提示,因此用户不可见
    default "v200zr"
endif # BOARD_v200zr

从 //kernel/liteos_m/Kconfig 文件可以看出需要在 //device/soc/bestechnic 目录下新增如下 Kconfig 文件进行适配:

.
├── bes2600									 --- bes2600 SoC系列
│   ├── Kconfig.liteos_m.defconfig.bes2600w	 --- bestechnic芯片厂商bes2600w SoC Series配置
│   ├── Kconfig.liteos_m.defconfig.series	 --- bestechnic芯片厂商bes2600默认配置
│   ├── Kconfig.liteos_m.series				 --- bestechnic芯片厂商bes2600 SoC Series配置
│   └── Kconfig.liteos_m.soc				 --- bestechnic芯片厂商bes2600 SoC配置
├── Kconfig.liteos_m.defconfig				 --- bestechnic芯片厂商SoC默认配置
├── Kconfig.liteos_m.series					 --- bestechnic芯片厂商SoC Series配置
└── Kconfig.liteos_m.soc					 --- bestechnic芯片厂商 SoC配置

在 bes2600/Kconfig.liteos_m.series 需要配置 bes2600 SoC series,以及它的芯片架构等信息,如下:

config SOC_SERIES_BES2600			 --- 提供bes2600 SoC Series选项
    bool "Bestechnic 2600 Series"
    select ARM						 --- 选择bes2600后,默认选择ARM架构
    select SOC_COMPANY_BESTECHNIC    --- 选择bes2600后,默认选择bestechnic芯片公司,驱动会依赖这个宏配置,选择配置编译对应厂商的驱动
    select CPU_CORTEX_M33			 --- 选择bes2600后,默认选择cortex-m33 CPU
    help
        Enable support for Bestechnic 2600 series

在 bes2600/Kconfig.liteos_m.soc 需要提供 bes2600 SoC series 下有多少个具体的 SoC 可供选择,如下:

choice
    prompt "Bestechnic 2600 series SoC"
    depends on SOC_SERIES_BES2600	 --- 只有选择了bes2600 Series后,才会出现如下配置选项
config SOC_BES2600W					 --- 增加bes2600w SoC配置选择项
    bool "SoC BES2600w"
endchoice

在 bes2600/Kconfig.liteos_m.defconfig.series 需要提供 bes2600 SoC series 选择后的默认配置,如下:

if SOC_SERIES_BES2600							 --- 选择了bes2600 Series后,才会增加如下默认配置选项
rsource "Kconfig.liteos_m.defconfig.bes2600w"	 --- 增加bes2600w SoC的默认配置
config SOC_SERIES								 --- 增加SOC_SERIES的默认配置
    string
    default "bes2600"
endif

配置完成后,还需要根据 kernel/liteos_m/Makefile 文件配置 make menuconfig 的 defconfig 保存路径:

ifeq ($(TEE:1=y),y)
tee = _tee
endif
ifeq ($(RELEASE:1=y),y)
CONFIG ?= $(PRODUCT_PATH)/kernel_configs/release$(tee).config
else
CONFIG ?= $(PRODUCT_PATH)/kernel_configs/debug$(tee).config		 --- 配置文件保存在$(CONFIG)中,由产品最终定义
endif
……
update_config menuconfig:
	$(HIDE)test -f "$(CONFIG)" && cp -v "$(CONFIG)" .config && menuconfig $(args) && savedefconfig --out "$(CONFIG)"

在这个例子中,defconfig 配置路径为 $(PRODUCT_PATH)/kernel_configs/debug.config,创建该文件后,内容为空,产品的目录文件结构如下:

.
└── display_demo
    ├── config.json
    └── kernel_configs
        └── debug.config

配置完成后,在 kernel/liteos_m 目录下执行 make menuconfig 能够对 SoC Series/SoC/Board 进行选择,如下࿱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值