Zephyr 总体架构与目录导读
1. 软件分层
1 | 应用层 |
Zephyr 的硬件描述、功能选择和源码编译高度耦合于编译期。很多看似“运行时注册”的对象,实际是由宏放进 iterable linker section,再由内核按 section 边界遍历。
2. 顶层目录
arch/
CPU 架构实现。完整上游 Zephyr 支持多种架构,但当前裁剪树实际只包含 ARM 和 POSIX 实现(另有 arch/common 公共代码);不能依据残留公共头文件假定 RISC-V、x86、Xtensa 等架构可直接构建。架构层主要职责:
- reset 后进入 C 环境;
- interrupt lock/unlock 和异常入口;
- thread context 构造和切换;
- syscall trap;
- cache、MPU/MMU、userspace;
- SMP CPU 启动和 IPI;
- 架构专用 linker snippets。
通用内核通过 arch_*() API 调用架构层,例如 arch_kernel_init()、arch_switch()、arch_irq_lock()。
kernel/
与硬件架构无关的内核主体:
init.c:系统启动和 init level;sched.c、priority_queues.c、timeslicing.c:调度;thread.c、init_static.c、dynamic.c:线程生命周期;timeout.c、timer.c:时间管理;work.c、system_work_q.c:workqueue;sem.c、mutex.c、condvar.c、events.c:同步;queue.c、msg_q.c、mailbox.c、pipes.c、poll.c:通信;kheap.c、mem_slab.c、mempool.c:内存;userspace.c、mem_domain.c、userspace_handler.c:用户态;smp.c、ipi.c、cpu_mask.c:多核;idle.c、fatal.c、device.c:系统基础设施。
include/zephyr/
公共 API 和大量编译期宏。常用入口:
kernel.h:内核 API 总入口;device.h:设备模型;devicetree.h:DTS 查询宏;init.h:SYS_INIT();drivers/:驱动 class API;sys/:链表、原子操作、byteorder、util、iterable section;logging/、net/、fs/、pm/:子系统 API;internal/:内部生成和 syscall 支撑。
drivers/
按设备类别组织实现,例如:
1 | adc/ audio/ cache/ can/ charger/ clock_control/ |
当前裁剪树没有 Bluetooth 和 USB 的驱动实现目录,尽管部分公共头文件、binding 或 CMake 条件仍有残留。
公共 API 定义在 include/zephyr/drivers/<class>.h,具体实现通常以 compatible、Kconfig 和 CMake 三者共同选择。
subsys/
跨驱动的系统服务,主要包括:
logging、shell、settings;net、fs、storage、disk;dfu、mgmt;pm、random、retention;ipc、modem;debug、tracing、timing、stats;zbus、rtio、input;testsuite。
当前树不包含 subsys/usb 和 subsys/bluetooth 实现,相关功能需恢复上游源码或通过外部模块提供。
lib/
可复用库和 C 运行时适配:
- libc 与 POSIX;
- C++ 支持;
- heap、hash、CRC、ring buffer、JSON、CBOR;
- compression、crypto glue、DSP;
- OS abstraction 和 utilities。
内核机制一般位于 kernel/,不拥有系统线程或复杂策略的算法库通常位于 lib/,提供完整服务/协议的功能通常位于 subsys/。
boards/、soc/、dts/
boards/:板级硬件组合、DTS、默认配置、runner;soc/:SoC 系列启动、时钟、中断、pinmux 和内存布局;dts/:架构/厂商.dtsi、bindings schema、公共 include。
当前 3.7 树同时支持新的 hardware model v2。板描述通过 board.yml 指定 vendor、SoC 和 qualifiers。
cmake/、scripts/
cmake/:Zephyr package、工具链、board/SoC 查找、Kconfig/DTS、linker、生成规则;scripts/:Kconfiglib、DTS parser、gen_isr_tables、syscall generator、Twister、west commands、签名与 runner。
tests/、samples/
samples/侧重可运行用法和文档示例;tests/侧重自动断言、边界、负向和覆盖率;testcase.yaml描述 Twister 测试场景、平台约束和 tags;subsys/testsuite/ztest提供测试框架。
modules/、share/
modules/中的 Kconfig/CMake glue 用于接入 workspace 外部模块;share/zephyr-package支持find_package(Zephyr);share/sysbuild支持多 image 联合构建;share/zephyrun、sysbuild-package等提供工具集成。
3. 核心对象关系
Thread
struct k_thread 保存线程架构上下文、调度状态、优先级、stack、timeout、资源池、userspace 权限等。调度器主要操作其内嵌的 struct _thread_base。
Kernel
kernel/init.c 定义唯一全局实例:
1 | struct z_kernel _kernel |
其中包含 CPU 数组、ready queue、timeout queue、当前线程和调度状态。
Device
struct device 保存:
name;- 只读
config; - 可变
data; - class-specific
api; - device state;
- PM 对象和依赖 handle。
设备对象由 DEVICE_DT_DEFINE() 等宏静态生成。
Init entry
struct init_entry 同时承载 SYS_INIT 和 device init。宏把 entry 放到 .z_init_<level><prio>_<subprio>_ section,链接脚本排序后,z_sys_init_run_level() 顺序调用。
4. 编译期与运行时边界
编译期完成:
- board/SoC/arch 选择;
- DTS 合并和 binding 校验;
- Kconfig 依赖求解;
- 驱动实例生成;
- syscall 和 userspace object 元数据生成;
- init entry 排序;
- ISR table 和 device dependency 生成;
- section 和内存地址布局。
运行时完成:
- 初始化硬件和设备;
- 启动线程和调度;
- 执行驱动 API;
- 协议栈、文件系统和服务状态机;
- runtime PM、动态线程、动态内存。
理解 Zephyr 问题时,应先判断问题发生在“生成期/链接期”还是“运行期”。例如:
undefined reference to __device_dts_ord_N:通常是 DTS 有节点但驱动未编译;- Kconfig symbol 未生效:配置求解问题;
device_is_ready()为 false:设备 init 运行后失败;- API 返回
-ENOSYS:class 或功能路径未实现。
5. 启动总览
体系结构 reset 代码完成最小 CPU/内存准备后调用 z_cstart():
1 | z_cstart |
6. 源码阅读建议
按以下顺序建立全局认识:
kernel/init.cinclude/zephyr/init.h、device.hkernel/thread.c、sched.c、timeout.cinclude/zephyr/kernel.hcmake/modules/zephyr_default.cmakecmake/modules/dts.cmake和scripts/dts/- 一个简单驱动,如 GPIO/UART,再看其 bindings
subsys/logging、shell、settings- 当前目标板 DTS、defconfig 和应用 overlay
正在加载留言…