OpenHarmony南向设备开发建构编译分析
一、OpenHarmony编译相关基础
OpenHarmony采用分层设计、组件化开发模式。
一个产品由多个子系统(subsystem)组成,每个子系统包含一个或多个组件(component),每个组件包含一个或多个功能项(feature)。
子系统是一个逻辑概念,不同的子系统可能位于内核层,如驱动子系统;或位于系统服务层,如wifi服务子系统。
组件是系统最小的可复用、可配置、可裁剪的功能单元。组件目录独立可并行开发、可独立编译、可独立测试。
组件是gn定义的编译目标,可以为静态库、动态库、可执行文件或group。
KAL 内核抽象层
屏蔽不同类型芯片采用的内核差异,对上层提供基础内核的多种管理能力。
HDF 硬件驱动框架
提供统一的外设访问和驱动开发框架,方便不同硬件接入。
芯片解决方案
- 芯片解决方案是一个特殊的组件
- 芯片解决方案组件一般就是编程实现的用户功能
产品解决方案
- 产品解决方案为基于开发板的完整产品,是最终提供给用户的功能组合
- 该目录下的config.json文件配置产品的子系统和组件依赖
二、基于qihang开发板编译分析
代码目录结构如下:
/home/openharmony
├──applications
├──base #核心子系统目录
├──build
├──device #芯片解决方案目录
├──domains
├──drivers
├──foundation
├──kernel
├──out
├──prebuilts
├──productdefine
├──third_party
├──utils #公共基础子系统目录
├──vendor #产品解决方案目录
├──.gn
├──build.py
├──build.sh
├──ohos_config.json #hb build读取的配置文件
├──quemu-run
运行hb set,选择"isoftstone-qihang"产品选项后,ohos_config.json文件被设定为:
{
"root_path": "/home/openharmony",
"board": "qihang", #开发板定义
"kernel": "liteos_m", #使用的内核
"product": "qihang", #产品定义
"product_path": "/home/openharmony/vendor/isoftstone/qihang",
"device_path": "/home/openharmony/device/board/isoftstone/qihang/liteos_m",
"device_company": "isoftstone",
"os_level": "small",
"version": "3.0",
"patch_cache": null,
"product_json": "/home/openharmony/vendor/isoftstone/qihang/config.json", #编译构建主入口
"target_cpu": null,
"target_os": null,
"out_path": "/home/openharmony/out/qihang/qihang" #输出文件的位置
}
编译构建主入口:vendor/device_company/product/config.json,即产品解决方案的配置文件,描述本产品包括哪些子系统。个人认为这些组件可理解为应用程序需要链接的库(静态库/动态库),这些库是与产品设计的功能相关、由OpenHarmony提供的能力库。
本示例实际为:
vendor/isoftstone/qihang/config.json
{
"product_name": "qihang", #产品名称
"type": "small", #系统类型
"version": "3.0", #config.json版本号
"ohos_version": "OpenHarmony 1.1.0",
"device_company": "isoftstone",
"board": "qihang",
"kernel_type": "liteos_m", #内核类型
"kernel_is_prebuilt": true, #内核预编译
"kernel_version": "",
"subsystems": [ #使用的子系统
{
"subsystem": "iot_hardware", #iot硬件设备操作接口,提供I2C,GPIO,FLASH,PWM,UART控制
"components": [
{ "component": "iot_controller", "features":[] }
]
},
{
"subsystem": "hiviewdfx", #日志子系统
"components": [
{ "component": "hilog_lite", "features":[] }, #流水日志
{ "component": "hievent_lite", "features":[] }, #故障、用户行为、功耗统计事件接口
{ "component": "blackbox", "features":[] },
{ "component": "hidumper_mini", "features":[] }
]
},
{
"subsystem": "distributedschedule", #分布式任务调度子系统
"components": [
{ "component": "samgr_lite", "features":[] }
]
},
{
"subsystem": "security", #安全子系统
"components": [
{ "component": "hichainsdk", "features":[] },
{ "component": "deviceauth_lite", "features":[] }, #设备认证
{ "component": "huks", "features": #Harmony通用密钥库管理
[
"disable_huks_binary = false",
"disable_authenticate = false",
"huks_use_lite_storage = true",
"huks_use_hardware_root_key = true",
"huks_config_file = \"hks_config_lite.h\"",
"huks_mbedtls_path = \"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/\""
]
}
]
},
{
"subsystem": "startup",
"components": [
{ "component": "bootstrap_lite", "features":[] }, #bootstrap启动引导
{ "component": "syspara_lite", "features": #提供系统属性读写接口
[
"enable_ohos_startup_syspara_lite_use_thirdparty_mbedtls = false"
]
}
]
},
{
"subsystem": "communication", #分布式通讯子系统
"components": [
{ "component": "wifi_lite", "features":[] },
{ "component": "dsoftbus", "features":[] },
{ "component": "wifi_aware", "features":[]}
]
},
{
"subsystem": "updater", #OTA升级
"components": [
{ "component": "ota_lite", "features":[] }
]
},
{
"subsystem": "iot", #华为云IoTDA平台SDK,集成了MQTT、LwIP、CoAP、LwM2M、mbedtls并提供API接口
"components": [
{ "component": "iot_link", "features":[] }
]
},
{
"subsystem": "utils", #公共基础子系统
"components": [
{ "component": "file", "features":[] }, #文件操作
{ "component": "kv_store", #KV存储
"features": [
"enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = false"
]
},
{ "component": "os_dump", "features":[] } #Dump系统属性
]
},
{
"subsystem": "vendor", #芯片厂商SDK
"components": [ # 3861子系统
{ "component": "hi3861_sdk", "target": "//device/soc/hisilicon/hi3861v100/sdk_liteos:wifiiot_sdk", "features":[] }
]
}
],
"third_party_dir": "//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party",
"product_adapter_dir": "//vendor/isoftstone/qihang/hals"
}
编译主入口:vendor/device_company/product/BUILD.gn,本示例实际为:
vendor/isoftstone/qihang/BUILD.gn
group("qihang") { #指定最终创建的目标qihang包含的依赖项
deps = [
"//device/board/isoftstone/qihang:run_qihang_scons", #设定用户自定义的hi3861编译配置
"//device/board/isoftstone/qihang/qihang_app", #用户应用程序,指向下文"芯片解决方案目录"中的内容
"//device/board/isoftstone/qihang/iot_hardware_hals", #硬件操作API
]
}
device/board/isoftstone/qihang/BUILD.gn的内容如下:
import("//build/lite/config/component/lite_component.gni")
build_ext_component("run_qihang_scons") {
exec_path = rebase_path(".", root_build_dir)
outdir = rebase_path(root_out_dir)
if (host_os == "win") {
command = "sh qihang_build.sh $outdir win"
} else {
command = "sh qihang_build.sh $outdir linux"
}
}
device/board/isoftstone/qihang/qihang_build.sh的内容如下:
即将用户定义的两个makefile配置文件拷贝到Hi3861 SDK目录下,保证3861 SDK编译后符合应用程序的规格要求。
#!/bin/bash
cp config/usr_config.mk ../../../soc/hisilicon/hi3861v100/sdk_liteos/build/config
cp config/sdk.mk ../../../soc/hisilicon/hi3861v100/sdk_liteos/build/config
芯片解决方案目录结构:
├──device/board/isoftstone/qihang_app
├──BUILD.gn
├──02OLED
├──BUILD.gn
├──oled_module.c
├──…
├──temp_humi_demo
├──BUILD.gn
├──temp_humi_test.c
├──…
qihang_app\BUILD.gn(qihang_app组件的编译配置文件)文件内容如下:
import("//build/lite/config/component/lite_component.gni") # 导入编译组件
lite_component("qihang_app") { #qihang_app组件(componet)包括2个功能(feature)
features = [
"02OLED:oled",
"temp_humi_demo",
]
}
02OLED\BUILD.gn(oled功能的编译配置)文件内容如下:
static_library("oled") { #【oled功能】构建成静态库
sources = [ #sources指定静态库.a所依赖的.c文件及其路径
"oled_module.c",
"oled.c",
"spi_screen.c",
"led_screen_main.c",
"test.c",
"gui.c",
]
cflags = [ "-Wno-unused-variable" ]
cflags += [ "-Wno-unused-but-set-variable" ]
include_dirs = [ #include_dirs指定source所需要依赖的.h文件路径
"//utils/native/lite/include", #路径中包含"//"表示绝对路径
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/board/isoftstone/qihang/iot_hardware_hals/include",
"include"
]
}
temp_humi_demo\BUILD.gn(温湿度采集功能的编译配置)文件内容如下:
static_library("temp_humi_demo") { #【温湿度采集功能】构建成静态库
sources = [
"temp_humi_test.c",
"wifi_sta_connect.c",
"mqtt.c",
]
include_dirs = [
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/board/isoftstone/qihang/iot_hardware_hals/include",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//third_party/cJSON",
"include",
"//device/board/isoftstone/qihang/third_party/paho_mqtt/MQTTPacket/src",
"//device/board/isoftstone/qihang/third_party/paho_mqtt/MQTTClient-C/src"
]
deps = [ #deps指示本功能模块依赖的其它软件模块
"//device/board/isoftstone/qihang/third_party/paho_mqtt:pahomqtt_static"
]
}
构建编译小结:
- 从上文描述的编译主入口BUILD.gn文件开始,递归处理产品所有依赖的子系统和组件,以及用户应用程序组件
- 执行构建配置,最终生成out\qihang\qihang\build.ninja文件(类似makefile)
- ninja编译,生成南向设备应用程序烧录文件:out\qihang\qihang\Hi3861_wifiiot_app_allinone.bin文件
参考:
- 轻量和小型系统编译构建指导
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-build-mini-lite.md - hb工具分析
https://ost.51cto.com/posts/5651 - OpenHarmony编译运行基础及简单实践
https://ost.51cto.com/posts/15383
很不错的总结,收藏了
硬核科普,三连了