NRF52832集成OpenHarmony轻量系统适配
集成介绍
本次集成采用zephyr(RTOS)内核 + LiteOS部件静态库的方式,集成LiteOS部件后,完成ActsBootstrapTest 、ActsSamgrTest、ActsDfxFuncTest、ActsHieventLiteTest四项测试套的测试。
LiteOS的代码为OpenHarmony-v6.1-Release分支代码,NRF52832集成SDK和编译工具链为v3.3.0版本。
环境准备
开发、编译环境分为oh的编译环境和nrfk52832开发环境。
oh的编译环境主要是编译出需要集成的LiteOS部件静态库,nrfk52832开发环境则包含了nrfk52832的开发、编译、烧录等功能。
oh的编译环境
参考官方文档:https://gitcode.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/Readme-CN.md
nrfk52832开发环境
nrfk52832开发环境只需要下载vscode,并安装"nRF Connect Visual Studio Code Extension Pack"插件即可,它是一套nRF芯片开发的集合插件。
安装插件后,可以使用插件自动下载安装sdk和编译工具链,注意这里建议在linux环境也下载一份编译工具链,后续编译编译oh静态库需要用到。

编译oh静态库
下载OpenHarmony-v6.1-Release代码和预编译工具链后,参考vendor/ohemu/qemu_mini_system_demo产品,创建一个nrf52832的产品,另外其对应的device仓为device/qemu/arm_mps2_an386,可以直接复制然后修改相关产品名称。
其中有两个重要文件需要进行修改
- vendor/ohemu/nrf52832/config.json
{
"product_name": "nrf52832",
"device_company": "qemu",
"board": "nrf52832",
"version": "3.0",
"ohos_version": "OpenHarmony-v6.1-Release",
"type":"mini",
"kernel_type": "liteos_m",
"kernel_version": "3.1.0",
"target_cpu": "arm",
"force_link_libs": [],
"subsystems": [
{
"subsystem": "startup",
"components": [
{ "component": "bootstrap_lite" },
{ "component": "init",
"features": [
"init_feature_begetctl_liteos = true",
"init_lite_use_posix_file_api = true",
"init_lite_memory_size=5120"
]
}
]
},
{
"subsystem": "hiviewdfx",
"components": [
{
"component": "hilog_lite",
"features": [
"hilog_lite_log_static_cache_size = 512",
"hilog_lite_hiview_hilog_file_buf_size = 256",
"hilog_lite_disable_hilog_static = true"
]
},
{ "component": "hievent_lite" },
{
"component": "hiview_lite",
"features": [
"hiview_lite_stack_size = 2048"
]
}
]
},
{
"subsystem": "systemabilitymgr",
"components": [
{ "component": "samgr_lite" }
]
},
{
"subsystem": "commonlibrary",
"components": [
{
"component": "utils_lite",
"features":[ "utils_lite_feature_file = true" ]
}
]
},
{
"subsystem": "xts",
"components": [
{ "component": "device_attest_lite" },
{ "component": "tools" },
{ "component": "acts" }
]
}
],
"third_party_dir": "//third_party",
"vendor_adapter_dir": "",
"product_adapter_dir": "//vendor/ohemu/nrf52832/hals"
}
- device/qemu/nrf52832/liteos_m/config.gni
kernel_type = "liteos_m"
kernel_version = "3.1.0"
board_cpu = "cortex-m4"
board_arch = ""
board_toolchain = "arm-zephyr-eabi-gcc"
use_board_toolchain = true
board_toolchain_path = "/xxx/ncs/toolchains/911f4c5c26/opt/zephyr-sdk/arm-zephyr-eabi/bin"
board_toolchain_prefix = "arm-zephyr-eabi-"
board_toolchain_type = "gcc"
if (product_path != "") {
product_conf = read_file("${product_path}/config.json", "json")
force_link_libs = product_conf.force_link_libs
}
board_opt_flags = []
board_cflags = [
"-mthumb",
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-fno-builtin",
"-fno-strict-aliasing",
"-fsigned-char",
"-std=c99",
"-Os",
# "-flto",
# "-fno-stack-protector",
"-DUSE_HAL_DRIVER",
"-D__LITEOS_M__",
]
board_cflags += board_opt_flags
board_asmflags = [
"-mcpu=cortex-m4",
"-mthumb",
"-static",
"-Os",
]
board_asmflags += board_opt_flags
board_cxx_flags = board_cflags
board_ld_flags = []
board_ld_flags += [
"-Wl,-gc-sections",
"-Wl,--wrap=_free_r",
"-Wl,--wrap,_malloc_usable_size_r",
"-Wl,--wrap,_malloc_r",
"-Wl,--wrap,_memalign_r",
"-Wl,--wrap,_realloc_r",
"-Wl,--wrap,_calloc_r",
]
board_include_dirs = [ "//commonlibrary/utils_lite/include" ]
board_adapter_dir = ""
board_configed_sysroot = ""
storage_type = ""
这里需要注意board_toolchain、board_toolchain_path、board_toolchain_prefix等配置需要自行修改,需要使用到nrfk52832开发环境下载的编译工具链,其中board_toolchain_path为nrf52832编译工具链地址。
集成oh静态库
编译成功后,在out/nrf52832/nrf52832/libs中即可找到LiteOS部件的编译产物,需要将这些静态库集成到nrfk52832的sdk中。
解压附件 openharmony.rar,将解压后的openharmony复制到nrfk52832的sdk目录xxx\ncs\v3.3.0。
修改xxx\ncs\v3.3.0\nrf\west.yml文件,在最后的 self: 之前添加:
...
- name: hostap
repo-path: sdk-hostap
path: modules/lib/hostap
revision: 957e9578648b7da0e35f20dbf9a0c35fce9dc4af
***添加oh集成部分***************************
- name: ohos_lite
repo-path: ohos_lite_adaptor
path: openharmony
revision: v6.1-Release
******************************************
# West-related configuration for the nrf repository.
self:
...
静态库集成
out/nrf52832/nrf52832/libs中LiteOS部件的编译产物放在xxx\ncs\v3.3.0\openharmony\kits\libs目录下,编写CMakeList.txt文件使静态库参与项目编译。

在xxx\ncs\v3.3.0\openharmony\kits\includes文件夹中是参与编译的部件的头文件,如果在编译时出现未定义的报错,需要在oh对应的部件中找到对应的头文件并复制到对应的文件节中:

LiteOS_M内核集成
在集成oh部件静态库时,oh部件中存在直接调用LiteOS_M的内核接口,这些接口在内核中定义和实现,需要手动适配,使用zephyr内核接口实现一遍:

以中断中断控制为例,通过调用 Zephyr 的底层中断控制 API (irq_lock / irq_unlock),来实现符合 LiteOS-M 规范的中断加锁、解锁和恢复功能:

Hilog集成
在openharmony中,大部分的日志打印主要是hilog部件提供相关接口,因此很多部件都依赖hilog部件,而zephyr中也提供了自己的日志模块,集成静态库后需要对接hilog与zephyr的日志模块,而hilog部件也提供了集成方法,通过注册日志打印接口,hilog在打印时可以走注册的接口传输日志信息,在注册的方法中则可以接收信息后通过zephyr的日志模块进行打印:

启动集成
liteos的启动主要是在bootstrap部件中,通过OHOS_SystemInit();启动各个服务,在启动之前需要先完成hilog的日志输出注册:

开发nrf52832应用
解压附件 liteos_app.rar,将其导入到项目中,参考:

链接器配置
上面集成静态库完成后,虽然oh的代码及适配层都可参与项目编译,但需要在链接文/xxx/ncs/liteos_app/linker/linker.ld中手动新增如下段:
__zinitcall_bsp_start = .;
KEEP (*(.zinitcall.bsp0.init))
KEEP (*(.zinitcall.bsp1.init))
KEEP (*(.zinitcall.bsp2.init))
KEEP (*(.zinitcall.bsp3.init))
KEEP (*(.zinitcall.bsp4.init))
__zinitcall_bsp_end = .;
__zinitcall_device_start = .;
KEEP (*(.zinitcall.device0.init))
KEEP (*(.zinitcall.device1.init))
KEEP (*(.zinitcall.device2.init))
KEEP (*(.zinitcall.device3.init))
KEEP (*(.zinitcall.device4.init))
__zinitcall_device_end = .;
__zinitcall_core_start = .;
KEEP (*(.zinitcall.core0.init))
KEEP (*(.zinitcall.core1.init))
KEEP (*(.zinitcall.core2.init))
KEEP (*(.zinitcall.core3.init))
KEEP (*(.zinitcall.core4.init))
__zinitcall_core_end = .;
__zinitcall_sys_service_start = .;
KEEP (*(.zinitcall.sys.service0.init))
KEEP (*(.zinitcall.sys.service1.init))
KEEP (*(.zinitcall.sys.service2.init))
KEEP (*(.zinitcall.sys.service3.init))
KEEP (*(.zinitcall.sys.service4.init))
__zinitcall_sys_service_end = .;
__zinitcall_sys_feature_start = .;
KEEP (*(.zinitcall.sys.feature0.init))
KEEP (*(.zinitcall.sys.feature1.init))
KEEP (*(.zinitcall.sys.feature2.init))
KEEP (*(.zinitcall.sys.feature3.init))
KEEP (*(.zinitcall.sys.feature4.init))
__zinitcall_sys_feature_end = .;
__zinitcall_run_start = .;
KEEP (*(.zinitcall.run0.init))
KEEP (*(.zinitcall.run1.init))
KEEP (*(.zinitcall.run2.init))
KEEP (*(.zinitcall.run3.init))
KEEP (*(.zinitcall.run4.init))
__zinitcall_run_end = .;
__zinitcall_app_service_start = .;
KEEP (*(.zinitcall.app.service0.init))
KEEP (*(.zinitcall.app.service1.init))
KEEP (*(.zinitcall.app.service2.init))
KEEP (*(.zinitcall.app.service3.init))
KEEP (*(.zinitcall.app.service4.init))
__zinitcall_app_service_end = .;
__zinitcall_app_feature_start = .;
KEEP (*(.zinitcall.app.feature0.init))
KEEP (*(.zinitcall.app.feature1.init))
KEEP (*(.zinitcall.app.feature2.init))
KEEP (*(.zinitcall.app.feature3.init))
KEEP (*(.zinitcall.app.feature4.init))
__zinitcall_app_feature_end = .;
__zinitcall_test_start = .;
KEEP (*(.zinitcall.test0.init))
KEEP (*(.zinitcall.test1.init))
KEEP (*(.zinitcall.test2.init))
KEEP (*(.zinitcall.test3.init))
KEEP (*(.zinitcall.test4.init))
__zinitcall_test_end = .;
__zinitcall_exit_start = .;
KEEP (*(.zinitcall.exit0.init))
KEEP (*(.zinitcall.exit1.init))
KEEP (*(.zinitcall.exit2.init))
KEEP (*(.zinitcall.exit3.init))
KEEP (*(.zinitcall.exit4.init))
__zinitcall_exit_end = .;
需要新增上述段是因为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文件需要手动加入强制链接。
/xxx/ncs/liteos_app/linker/linker.ld是项目的链接器文件,它的基础内容是/xxx/ncs/v3.3.0/zephyr/include/zephyr/arch/arm/cortex_m/scripts/linker.ld的内容,这是由于nrf52832芯片是Arm Cortex-M4芯片,使用默认的链接器文件,当需要自定义链接器时,可以通过设置liteos_app/prj.conf,在其中添加:
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="linker/linker.ld"


串口输出日志配置
系统uart口输出日志,通过查看设备原理图,USB串口RX、TX对应的引脚是P0.06,P0.07:

打开设备树,查看引脚配置,如果不是这两个引脚,修改后保存即可:


修改后保存即可自动保存到/xxx/ncs/liteos_app/nrf52dk_nrf52832.overlay文件中。
启动入口
在liteos_app/src/main.c文件中导入 oh_lite_init.h 头文件,然后在main方法中调用ohos_lite_init();接口, 即可完成LiteOS的集成启动。

应用打包和烧录
应用开发后,可以直接使用vscode的nrf插件进行打包、烧录等操作:

XTS测试
XTS测试用例可以单独运行也可以一起运行,查看/xxx/ncs/v3.3.0/openharmony/kits/CMakeLists.txt文件:

在进行测试时,需要查看测试日志,使用串口调试助手工具即可,在windows商店直接搜索 "串口调试助" 安装。
链接设备后,端口名选择 USB-SERIAL CH340 , 波特率选择 115200,数据位选择 8, 校验位选择 None,停止位选择 1,最下面的自动重连勾选上,然后点击打开即可,点击打开后正常情况下会变成绿色的关闭按钮,此时就可以记录并查看日志。

更多推荐


所有评论(0)