
背景
嵌入式系统开发中,常常为了软件架构绞尽脑汁,有没有一种“万能”的架构,不挑平台,适配简单,快速迭代、落地项目?最近了解和学习了Zephyr,大受启发,于是有了本篇描述的构想。想借鉴Zephyr的配置系统精髓(如Kconfig),同时保持对RTOS-V2的兼容,这是一个灵活性、可配置性很强的架构。下面我将为你详细解析Zephyr的配置、编译和构建步骤与原理,并重点分析如何将其Kconfig等机制剥离并适配到你的系统中。
⚙️ Zephyr构建系统核心原理
理解Zephyr的构建系统,关键在于把握其如何将CMake、Kconfig和Device Tree (DTS) 三者协同工作。
-
配置阶段 (Configuration Phase):
- Device Tree (DTS) 处理硬件描述:Zephyr使用设备树以声明式语言(DTS)描述硬件,如SoC资源、外设、引脚配置等。构建时,所有
.dts、.dtsi及应用的.overlay文件会被C预处理器合并成一个临时的.dts.pre.temp文件。此临时文件经Python脚本解析(参考dts/bindings/下的YAML绑定文件定义设备属性及约束),最终生成供C代码使用的头文件devicetree_unfixed.h(包含设备树节点信息的宏定义)和供Kconfig使用的devicetree.conf(将设备树信息转化为Kconfig可引用的配置项)。devicetree.h则汇总并提供API访问这些信息。 - Kconfig 处理功能配置:Kconfig管理软件层面的系统功能、驱动、协议栈等可裁剪配置。它读取以下配置源:由DTS生成的
devicetree.conf、板级默认配置<board>_defconfig、应用工程的prj.conf及其他可能的CMake缓存变量。通过menuconfig或guiconfig界面或直接修改配置文件,最终合并生成统一的.config文件和autoconf.h头文件。Kconfig与DTS通过devicetree.conf传递的配置项建立关联(例如,DTS中某个UART节点状态为"okay",可能对应生成CONFIG_UART_<index>=y)。 - CMake 驱动构建并管理源码:CMake是构建过程的核心驱动者。它首先调用处理DTS和Kconfig的Python脚本。然后,根据Kconfig输出(
.config)和DTS输出,CMake通过各目录的CMakeLists.txt决定哪些源文件被编译(例如,使用target_sources_ifdef(CONFIG_FEATURE ...)条件添加),并生成最终的构建脚本(Ninja或Makefile)。你的应用代码通常编译成libapp.a,最后与Zephyr内核、驱动等库链接。
- Device Tree (DTS) 处理硬件描述:Zephyr使用设备树以声明式语言(DTS)描述硬件,如SoC资源、外设、引脚配置等。构建时,所有
-
编译阶段 (Build Phase):
- 预编译:此阶段生成系统运行必需的文件,如通过
scripts/gen_offset_header.py解析offsets_aarch32.c生成offsets.h(用于内核上下文切换时获取结构体偏移量),以及scripts/gen_syscalls.py生成系统调用相关头文件。 - 首次编译链接:编译所有选中的源文件为目标文件(
.o)并打包为静态库(.a)。链接器使用链接脚本(如linker.ld,其内容可能由CMake根据DTS信息如内存区域动态生成或指向固定脚本)将所有这些库和zephyr_prebuild.elf链接成初始的ELF文件zephyr_prebuild.elf。 - 二次编译链接:从
zephyr_prebuild.elf中提取信息(如中断向量表生成isr_table.c,内核对象地址生成Hash表),再次编译并链接,最终生成优化的zephyr.elf。 - 镜像生成:使用
objcopy等工具将zephyr.elf转换为所需的二进制(.bin)、十六进制(.hex)等格式。
- 预编译:此阶段生成系统运行必需的文件,如通过
-
工具链:
west是Zephyr的元工具和项目管理器。它封装了CMake的调用、模块管理(通过west update拉取依赖)、构建(west build)、烧录(west flash)和调试(west debug)等命令,提供了统一的开发入口。
下面的表格总结了Zephyr构建系统的核心组件及其在你的可移植架构中的可借鉴性:
| 组件 | 在Zephyr中的角色 | 对你的系统的可借鉴性 |
|---|---|---|
| Kconfig | 功能配置管理中心:管理所有软件功能选项,决定代码编译与否。 | 高:核心目标,可直接复用其语法、解析器和UI (如 menuconfig)。 |
| Device Tree (DTS) | 硬件描述与抽象:声明式描述硬件资源,作为硬件信息的唯一事实来源。 | 中高:强烈推荐采纳其**“硬件信息与驱动代码分离”的思想**。你可直接使用DTS语法和工具链,或借鉴思想自定义硬件描述格式。 |
| CMake | 构建流程驱动与源码管理:根据Kconfig和DTS的输出,组织源码、调用工具链、控制编译链接。 | 中:Zephyr的CMake脚本与其架构紧密耦合。你可使用CMake,但脚本需根据你的OS和代码结构重写。 |
west |
项目元工具与命令封装:管理多仓库依赖,提供统一开发命令集。 | 低:若你的系统代码结构简单,可不用west,用CMake或其他脚本直接驱动。 |
🧱 剥离与适配:构建你的跨OS配置系统
要在你的系统中使用Kconfig并适配RTOS-V2,关键在于解耦Kconfig、硬件描述层与操作系统,并定义清晰的接口。
-
核心组件选型与剥离:
- Kconfig系统:直接从Zephyr源码中提取Kconfig相关的前端(
menuconfig/guiconfig界面)和后端(解析Kconfig文件、生成.config和autoconf.h的代码/脚本)。这部分相对独立,修改小。 - 硬件描述层(你的"DTS"):这是解耦硬件与驱动/OS的关键。
- 你可以选择直接使用Zephyr的DTS语法和工具链(
.dts文件,YAML绑定,Python解析脚本)。 - 或者,你也可以自定义一种硬件描述格式(如JSON、XML或特定的C头文件),只要它能清晰描述你的MCU外设、GPIO、时钟、中断等,并提供生成对应头文件和Kconfig配置项(你的
devicetree.conf)的工具。
- 你可以选择直接使用Zephyr的DTS语法和工具链(
- 构建系统:选择CMake或你熟悉的其他构建工具(如Make)。你需要编写新的构建脚本,其核心逻辑是:首先运行硬件描述处理工具和Kconfig配置,然后根据配置结果决定编译哪些源码。
- Kconfig系统:直接从Zephyr源码中提取Kconfig相关的前端(
-
系统架构设计:
下图清晰地展示了推荐的解耦后的系统架构,以及信息(配置、硬件描述)的流动过程:

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



