20分钟无硬件跑通 Zephyr:QEMU 上编译并运行你的第一个 RTOS 程序
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
上周我把同一份main.c从 x86 模拟机切到 Cortex-M3 模拟机,只改了west build里的一个参数。这就是 Zephyr RTOS 的核心卖点:一个内核对应 20 多个模拟目标,全程不需要一块真硬件。
项目定位:先说清楚它是什么
- 是什么:Zephyr 是面向资源受限设备的新一代开源 RTOS,提供线程调度、内存管理、设备驱动框架和协议栈,内核源码 本体只有几百个文件。
- 解决什么问题:传统嵌入式里,换一块芯片往往要重写驱动甚至重写调度层;Zephyr 用统一的内核接口 + 板卡描述文件,让一份应用代码直接编译到不同架构的目标上。
- 硬指标:官方口径内核最小可跑在约 10KB RAM 量级的目标上;boards/ 目录下有 185 个板卡厂商、200 多块板卡目标,其中仅 QEMU 模拟器板卡 就有 x86、Cortex-M0/M3、RISC-V、OR1K、Xtensa 等 20 多个。
- 适合谁:想系统学 RTOS 但手上没有开发板的人,以及需要在多平台维护同一份固件的工程师。它不承诺替代你已有的 FreeRTOS 经验,只是多一个选择。
一条命令装齐依赖,五步进入 Zephyr
这一步的目标是"能敲出第一条构建命令",安装、配置、首次编译合成一条动线,不单独拆环境章节。
安装构建工具链和设备树编译器(QEMU 后面才需要,这里一并装):
sudo apt update && sudo apt install -y git cmake ninja-build gperf ccache dfu-util device-tree-compiler wget python3-dev python3-pip python3-setuptools python3-wheel xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev qemu-system-x86获取源码。仓库本身只读,后面所有实验都不改动其中任何文件:
git clone https://gitcode.com/GitHub_Trending/ze/zephyr && cd zephyr激活环境(导出ZEPHYR_BASE,west 命令依赖它定位仓库根)和安装 Python 依赖(west 的自定义命令由 Python 实现,实现代码 就在这个目录):
source zephyr-env.sh pip3 install -r scripts/requirements.txt首次编译官方 Hello World 到 qemu_x86(构建产物落在build/):
west build -b qemu_x86 samples/hello_world日志滚动结束后,build/zephyr/zephyr.elf生成即编译成功。更完整的依赖说明见 scripts/requirements.txt。
CONFIG_ 宏从哪来:两条链路看懂构建
Zephyr 的代码不长,长的是"配置怎么变成代码"。两条链路看懂,整个构建系统就不神秘了。
Kconfig 链路:输入→处理→输出。你在prj.conf里写一行CONFIG_SHELL=y,Kconfig 系统把它和几百个.conf选项求值后,生成头文件autoconf.h;预处理阶段#define CONFIG_SHELL 1进入编译,源码里的#if defined(CONFIG_SHELL)决定哪些函数被编进固件。Hello World 打印的CONFIG_BOARD_TARGET就是这么来的——它不是变量,是编译期字符串。官方 hello_world 示例 的prj.conf只有一行注释# nothing here,用的全是默认值。
west 链路:仓库→清单→工具链。west.yml 是仓库清单,声明 zephyr 本体之外还要拉取哪些模块仓库(HAL、文件系统、加密库等);west build则把 CMake、Kconfig 和设备树(DTS)描述拼起来:arch/ 提供架构相关代码,soc/ 和 boards/ 描述硬件,drivers/ 按设备类型挂驱动,最后链接出 ELF 交给 QEMU。为什么这么分——内核不认识具体芯片,芯片只是数据,这是它能覆盖 200 多块板卡的原因。
跑通第一个示例:qemu_x86 上的 Hello World
目标:让模拟器跑起来,确认串口输出。
操作:复用刚才的构建目录直接启动 QEMU:
west build -t run验证:终端应出现(版本串随你的代码版本变化,当前仓库为 4.5.0-rc1):
*** Booting Zephyr OS build zephyr-v4.5.0-rc1 *** Hello World! qemu_x86原理:Hello World!后面跟的正是CONFIG_BOARD_TARGET的取值,证明"同一份源码、不同板卡、不同宏"的机制真实生效。源码本体就 12 行,值得看一眼 samples/hello_world/src/main.c。
切换架构只改一个参数:同一份代码上 Cortex-M3
目标:验证跨平台能力——代码一个字不动,只换目标。
操作:清空旧构建(换板卡必须清缓存,原因见后文速查表)并切到 Cortex-M3 模拟目标:
rm -rf build && west build -b qemu_cortex_m3 samples/hello_world && west build -t run验证:输出变为:
*** Booting Zephyr OS build zephyr-v4.5.0-rc1 *** Hello World! qemu_cortex_m3原理:-b参数只是换了一块"虚拟板卡"的描述文件,链接脚本、启动汇编、串口驱动全部由 boards/qemu/ 下的定义自动切换。真实板卡也是同一套逻辑,比如 Adafruit QT Py:
以后有真硬件时,-b换成adafruit_qt_py_rp2040/rp2040之类即可,应用代码不变。
写自己的应用:往 main 里加一个 k_sleep
目标:不碰仓库文件,在仓库外建一个最小应用,体验内核 API。
操作:在 zephyr 目录外建my_app/,放一个main.c(CMakeLists.txt照抄 官方示例 的三行模式:find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})、project、target_sources;prj.conf留空即可):
#include <stdio.h> #include <zephyr/kernel.h> int main(void) { /* 打印板卡宏,每 500ms 唤醒一次,共 3 次 */ for (int i = 0; i < 3; i++) { printf("tick %d [%s]\n", i, CONFIG_BOARD_TARGET); k_sleep(K_MSEC(500)); } return 0; }验证:
west build -b qemu_x86 ../my_app && west build -t run输出为:
*** Booting Zephyr OS build zephyr-v4.5.0-rc1 *** tick 0 [qemu_x86] tick 1 [qemu_x86] tick 2 [qemu_x86]原理:k_sleep把当前线程挂起、交还给调度器,定时器到期后再次唤醒——这是 内核源码 里线程调度最直观的一次体现。
踩坑速查:五条高频报错
| 现象 | 根因 | 解决 |
|---|---|---|
west: command not found | 环境未激活 | source zephyr-env.sh |
| 报错提示找不到 Zephyr SDK / 交叉编译器 | SDK 未安装 | west zephyr-sdk install |
run阶段报 QEMU 未找到 | QEMU 未装全 | sudo apt install qemu-system-x86 |
换-b后构建报错或行为异常 | 旧缓存残留 | rm -rf build后重新构建 |
| Python 侧报缺模块 | 依赖未装 | pip3 install -r scripts/requirements.txt |
延伸方向:从示例到源码
下一步做什么(操作型):
- 换更小的目标再跑一遍:
west build -b qemu_cortex_m0 samples/hello_world - 编译多线程示例,观察哲学家互斥:samples/philosophers/
- 给当前应用加命令行 Shell:构建时追加
-- -DCONFIG_SHELL=y,QEMU 里即可敲help - 跑内核测试套件:
west twister -T tests/kernel
深入学什么(概念型):
- 调度器与线程实现:kernel/sched.c、kernel/thread.c
- Kconfig 语法与
prj.conf机制:doc/develop/kconfig/ - 设备树(DTS)怎么写板卡:doc/hardware/
- 全部驱动分类与 Kconfig:drivers/Kconfig
现在就开始
Zephyr 的价值在于把"换硬件"降级成"换参数",而 QEMU 让你今天就能验证这一点。打开终端,进入仓库目录,执行west build -b qemu_x86 samples/hello_world && west build -t run——两分钟后你就该看到Hello World! qemu_x86。
【免费下载链接】zephyrPrimary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.项目地址: https://gitcode.com/GitHub_Trending/ze/zephyr
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考