OpenHarmony 平头哥玄铁架构 轻量系统移植—润和W800移植分享 原创 精华
本方案基于OpenHarmony LiteOS-M内核,使用联盛德W800芯片的润和软件海王星系列Neptune100开发板,进行开发移植。移植架构采用Board
与SoC
分离方案,支持通过Kconfig图形化配置编译选项,增加玄铁ck804ef
架构移植,实现了HDF
、XTS
等子系统及组件的适配。
适配准备
准备ubuntu20.04系统环境,安装csky-abiv2-elf-gcc交叉编译工具链。
编译构建
目录规划
本方案的目录结构使用Board和Soc解耦的思路:
芯片适配目录规划为:
产品样例目录规划为:
产品定义
vendor/hihope/neptune_iotlink_demo/config.json
文件下,描述了产品使用的内核、单板、子系统等信息。其中,内核、单板型号、单板厂商需提前规划好,是预编译指令hb set
关注的。例如:
填入的信息与规划的目录相对应,其中device_company
和board
用于关联出device/board/<device_company>/
目录。
单板配置
关联到的<board>目录下,在device/board/hihope/neptune100/liteos_m
目录下放置config.gni
文件,该配置文件用于描述该单板信息,包括CPU型号、交叉编译工具链及全局编译、链接参数等重要信息:
预编译
在工程根目录下输入预编译指令hb set
可显示相关产品信息,如下:
执行hb set
后,会在根目录下自动生成ohos_config.json
文件,文件中会列出待编译的产品信息。
通过hb env
可以查看选择出来的预编译环境变量。
至此,预编译适配完成,但工程还不能执行hb build进行编译,还需要准备好后续的LiteOS-M内核移植。
内核移植
Kconfig适配
在kernel/liteos_m
的编译中,需要在相应的单板以及SoC目录下使用Kconfig
文件进行索引。
-
在
vendor/hihope/neptune_iotlink_demo
目录下创建kernel_configs目录,并创建debug.config
空文件。 -
打开
kernel/liteos_m/Kconfig
文件,可以看到在该文件通过orsource命令导入了device/board
和device/soc
下多个Kconfig
文件,后续需要创建并修改这些文件: -
在
device/board/hihope
下创建相应的的Kconfig
文件: -
修改
Board
目录下Kconfig
文件内容:
在 neptune100/Kconfig.liteos_m.board
中添加,
配置只有SOC_WM800被选后,BOARD_NEPTUNE100才可被选。
在 neptune100/Kconfig.liteos_m.defconfig.board
中添加,
用于添加 BOARD_NEPTUNE100默认配置
-
在
device/soc/winnermicro
下创建相应的的Kconfig
文件: -
修改
Soc
目录下Kconfig
文件内容:
在wm800/Kconfig.liteos_m.defconfig.wm800
中添加:
在wm800/Kconfig.liteos_m.defconfig.series
中添加:
在 wm800/Kconfig.liteos_m.series
中添加:
在选择了 SOC_SERIES_WM800之后,才可选 wm800/Kconfig.liteos_m.soc
文件中的 SOC_WM800:
综上所述,要编译单板BOARD_NEPTUNE100,则要分别选中:SOC_COMPANY_WINNERMICRO、SOC_SERIES_WM800、SOC_WM800
7. 在kernel/liteos_m
中执行make menuconfig
进行选择配置,能够对SoC Series进行选择:
配置后的文件会默认保存在vendor/hihope/neptune_iotlink_demo/kernel_configs/debug.config
,也可以直接填写debug.config
:
模块化编译
Board
和SoC
的编译采用模块化的编译方法,从kernel/liteos_m/BUILD.gn
开始逐级向下递增。本方案的适配过程如下:
-
在
device/board/hihope
中新建文件BUILD.gn
,新增内容如下:在上述
BUILD.gn
中,neptune100以及shields即是按目录层级组织的模块名。 -
在
device/soc/winnermicro
中,新建文件BUILD.gn
,按目录层级组织,新增内容如下: -
在
device/soc/winnermicro
各个层级模块下,同样新增文件BUILD.gn
,将该层级模块加入编译。以device/soc/winnermicro/wm800/board/platform/sys/BUILD.gn
为例: -
为了组织链接以及一些编译选项,在
device/soc/winnermicro/wm800/board/BUILD.gn
下的config("board_config")
填入了相应的参数: -
为了组织一些产品侧的应用,需要强制链接到产品工程中来,本方案在vendor相应的
config.json
加入了相应的list来组织,在vendor/hihope/neptune_iotlink_demo/config.json
增加对应的list:将demo应用作为模块库来管理,开启/关闭某个demo,在bin_list中增减相应库文件即可。bin_list在gn中可以直接被读取,在
device/board/hihope/neptune100/liteos_m/config.gni
新增内容:读取list后即可在相应的链接选项上加入相关的组件库,在
//device/soc/winnermicro/wm800/BUILD.gn
添加内容:
内核子系统适配
在vendor/hihope/neptune_iotlink_demo/config.json
添加内核子系统及相关配置,如下:
内核启动适配
由于Neptune100开发板的芯片架构为Openharmony不支持的ck804ef架构,需要进行ck804ef架构移植。适配 kernel\liteos_m\arch\include
中定义的通用的文件以及函数列表,并放在了 kernel\liteos_m\arch\csky\v2\ck804\gcc
文件夹下。
内核初始化示例如下:
board_main在启动OHOS_SystemInit之前,需要初始化必要的动作,如下:
UserMain函数在device/soc/winnermicro/wm800/board/app/main.c
文件中,如下:
HDF驱动框架适配
HDF驱动框架提供了一套应用访问硬件的统一接口,可以简化应用开发,添加HDF组件需要在//vendor/hihope/neptune_iotlink_demo/kernel_configs
添加:
驱动适配相关文件放置在drivers/adapter/platform
中,对应有gpio,i2c,pwm,spi,uart,watchdog,都是通过HDF机制加载,本章节以GPIO和UART为例进行详细说明。
GPIO适配
-
芯片驱动适配文件位于
drivers/adapter/platform
目录,在gpio目录增加gpio_wm.c
文件,在BUILD.gn
文件中,描述了W800驱动的编译适配。如下: -
gpio_wm.c
中驱动描述文件如下: -
在
device/board/hihope/shields/neptune100/neptune100.hcs
添加gpio硬件描述信息, 添加内容如下: -
在GpioDriverInit获取hcs参数进行初始化,如下:
UART适配
-
芯片驱动适配文件位于
drivers/adapter/platform
目录,在uart目录增加uart_wm.c
文件,在BUILD.gn
文件中,描述了W800驱动的编译适配。如下: -
uart_wm.c
中驱动描述文件如下: -
在
device/board/hihope/shields/neptune100/neptune100.hcs
添加uart硬件描述信息, 添加内容如下: -
在UartDriverInit获取hcs参数进行初始化,如下:
Openharmony子系统适配
子系统的编译选项入口在相应产品config.json
下,如:vendor/hihope/neptune_iotlink_demo/config.json
。
wifi_lite组件
首先,在config.json
文件中,增加communication
子系统的wifi_lite
部件,如下:
wifi_lite
部件在 build/lite/components/communication.json
文件中,描述如下:
在本案例中,wifi
适配源码可见device/soc/winnermicro/wm800/board/src/wifi/wm_wifi.c
,如下:
系统服务管理子系统适配
系统服务管理子系统适配添加samgr_lite
部件,直接在config.json
配置,如下:
公共基础库子系统适配
公共基础库子系统适配添加了kv_store、file
部件,直接在config.json
配置,如下:
适配kv_store
部件时,键值对会写到文件中。在轻量系统中,文件操作相关接口有POSIX
接口与HalFiles
接口这两套实现。
因为对接内核的文件系统,采用POSIX
相关的接口,所以features
需要增加enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true
。
启动恢复子系统适配
启动恢复子系统适配添加了bootstrap_lite、syspara_lite
部件,直接在config.json
配置,如下:
适配bootstrap_lite部件时,需要在链接脚本文件device/soc/winnermicro/wm800/board/ld/w800/gcc_csky.ld
中手动新增如下段:
需要新增上述段是因为bootstrap_init
提供的对外接口,见utils/native/lite/include/ohos_init.h
文件,采用的是灌段的形式,最终会保存到上述链接段中。主要的服务自动初始化宏如下表格所示:
接口名 | 描述 |
---|---|
SYS_SERVICE_INIT(func) | 标识核心系统服务的初始化启动入口 |
SYS_FEATURE_INIT(func) | 标识核心系统功能的初始化启动入口 |
APP_SERVICE_INIT(func) | 标识应用层服务的初始化启动入口 |
APP_FEATURE_INIT(func) | 标识应用层功能的初始化启动入口 |
通过上面加载的组件编译出来的lib文件需要手动加入强制链接。
如在 vendor/hihope/neptune_iotlink_demo/config.json
中配置了bootstrap_lite
部件
bootstrap_lite
部件会编译base/startup/bootstrap_lite/services/source/bootstrap_service.c
,该文件中,通过SYS_SERVICE_INIT
将Init
函数符号灌段到__zinitcall_sys_service_start
和__zinitcall_sys_service_end
中,由于Init
函数是没有显式调用它,所以需要将它强制链接到最终的镜像。如下:
在base/startup/bootstrap_lite/services/source/BUILD.gn
文件中,描述了在out/neptune100/neptune_iotlink_demo/libs
生成 libbootstrap.a
,如下:
适配syspara_lite
部件时,系统参数会最终写到文件中进行持久化保存。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。
因为对接内核的文件系统,采用POSIX相关的接口,所以features字段中需要增加enable_ohos_startup_syspara_lite_use_posix_file_api = true
。
XTS子系统适配
XTS子系统的适配,直接在config.json
中加入组件选项:
另外,XTS功能也使用了list来组织,在config.json
文件中增减相应模块:
其它组件的适配过程与官方以及其它厂商的过程类似,不再赘述。
Openharmony的生态真是越来越壮大了