news 2026/10/10 1:32:12

20分钟无硬件跑通 Zephyr:QEMU 上编译并运行你的第一个 RTOS 程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
20分钟无硬件跑通 Zephyr:QEMU 上编译并运行你的第一个 RTOS 程序

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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 1:29:45

d32 单片机 出现hardfault时,定位崩溃的地址

出现崩溃 当 ARM Cortex-M 系列芯片进入 HardFault 异常&#xff0c;可以查看寄存器去排查问题。 如下&#xff0c;PC寄存器指向的是当前执行的代码的位置。定位堆栈指针 在进入hardfault之后&#xff0c;我们可以通过查看堆栈的内容去排查问题。 堆栈分为两种堆栈&#xff0c;…

作者头像 李华
网站建设 2026/10/10 1:28:04

如何在macOS桌面应用集成Highcharts

Highcharts 是一个基于 JavaScript 的 Web 图表库&#xff0c;没有原生 macOS 桌面库。 在 macOS 应用中&#xff0c;常见方式是通过 WKWebView 加载本地网页&#xff1b;如果应用基于 Electron&#xff0c;也可以按普通 Web 应用的方式集成。 SwiftUI WKWebView 将 Highch…

作者头像 李华
网站建设 2026/10/10 1:25:07

深度解析微信小程序及公众号获取code的方法与技巧

在微信小程序和公众号的开发过程中&#xff0c;获取code是进行用户身份验证的关键步骤。本文将详细介绍如何获取code&#xff0c;包括微信小程序和公众号两种场景下的获取方法&#xff0c;以及相关技巧。 一、微信小程序获取code 获取微信提供的用户身份标识&#xff0c;从而使…

作者头像 李华