Zephyr 总体架构与目录导读

Zephyr 总体架构与目录导读

1. 软件分层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
应用层
├─ application main()
├─ 应用线程、业务状态机
└─ prj.conf / overlay

系统服务层
├─ logging / shell / settings
├─ networking / fs / storage
├─ DFU / mcumgr / USB / IPC
└─ tracing / debug / PM

驱动与设备模型层
├─ struct device + driver API
├─ GPIO/I2C/SPI/UART/flash/clock/pinctrl/DMA
└─ Devicetree instance + Kconfig implementation selection

内核层
├─ thread / scheduler / timeout
├─ semaphore / mutex / queue / poll / work
├─ heap / slab / memory domain / userspace
└─ SMP / idle / fatal / object core

架构与 SoC 层
├─ arch/: 上下文切换、中断、原子操作、MMU/MPU
├─ soc/: 芯片启动、时钟、中断控制器
└─ boards/: 板级 DTS、defconfig、连接关系

构建描述层
├─ CMake / west / sysbuild
├─ Kconfig
├─ Devicetree + bindings
└─ linker scripts + generators

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.cpriority_queues.ctimeslicing.c:调度;
  • thread.cinit_static.cdynamic.c:线程生命周期;
  • timeout.ctimer.c:时间管理;
  • work.csystem_work_q.c:workqueue;
  • sem.cmutex.ccondvar.cevents.c:同步;
  • queue.cmsg_q.cmailbox.cpipes.cpoll.c:通信;
  • kheap.cmem_slab.cmempool.c:内存;
  • userspace.cmem_domain.cuserspace_handler.c:用户态;
  • smp.cipi.ccpu_mask.c:多核;
  • idle.cfatal.cdevice.c:系统基础设施。

include/zephyr/

公共 API 和大量编译期宏。常用入口:

  • kernel.h:内核 API 总入口;
  • device.h:设备模型;
  • devicetree.h:DTS 查询宏;
  • init.hSYS_INIT()
  • drivers/:驱动 class API;
  • sys/:链表、原子操作、byteorder、util、iterable section;
  • logging/net/fs/pm/:子系统 API;
  • internal/:内部生成和 syscall 支撑。

drivers/

按设备类别组织实现,例如:

1
2
3
4
5
adc/ audio/ cache/ can/ charger/ clock_control/
console/ counter/ crypto/ dac/ disk/ dma/ eeprom/ entropy/
ethernet/ flash/ gpio/ hwinfo/ i2c/ i3c/ input/ interrupt_controller/
led/ mbox/ mdio/ modem/ pinctrl/ pwm/ regulator/ reset/
rtc/ sensor/ serial/ spi/ timer/ watchdog/

当前裁剪树没有 Bluetooth 和 USB 的驱动实现目录,尽管部分公共头文件、binding 或 CMake 条件仍有残留。

公共 API 定义在 include/zephyr/drivers/<class>.h,具体实现通常以 compatible、Kconfig 和 CMake 三者共同选择。

subsys/

跨驱动的系统服务,主要包括:

  • loggingshellsettings
  • netfsstoragedisk
  • dfumgmt
  • pmrandomretention
  • ipcmodem
  • debugtracingtimingstats
  • zbusrtioinput
  • testsuite

当前树不包含 subsys/usbsubsys/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/zephyrunsysbuild-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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
z_cstart
├─ EARLY init
├─ arch_kernel_init
├─ 初始化日志核心和 dummy thread
├─ z_device_state_init
├─ PRE_KERNEL_1 init
├─ arch_smp_init
├─ PRE_KERNEL_2 init
├─ prepare_multithreading
│ ├─ 创建 idle threads
│ └─ 创建 main thread
└─ switch_to_main_thread
└─ bg_thread_main
├─ POST_KERNEL init
├─ boot banner
├─ z_init_static
├─ APPLICATION init
├─ 启动静态线程
├─ SMP init
└─ main()

6. 源码阅读建议

按以下顺序建立全局认识:

  1. kernel/init.c
  2. include/zephyr/init.hdevice.h
  3. kernel/thread.csched.ctimeout.c
  4. include/zephyr/kernel.h
  5. cmake/modules/zephyr_default.cmake
  6. cmake/modules/dts.cmakescripts/dts/
  7. 一个简单驱动,如 GPIO/UART,再看其 bindings
  8. subsys/loggingshellsettings
  9. 当前目标板 DTS、defconfig 和应用 overlay

文章互动

阅读 --

留言

0 条留言

正在加载留言…