基于 NXP i.MX8M Plus 测试 Zephyr RTOS

简介

Zephyr 是一个开源的小型实时操作系统(RTOS),专为资源受限的嵌入式系统而设计------从简单的环境传感器、LED 可穿戴设备,到复杂的嵌入式控制器、智能手表和 IoT 无线应用,均可使用 Zephyr 进行开发。Zephyr 采用 Apache 2.0 宽松许可证,由 Linux 基金会托管,拥有活跃的社区支持。

Zephyr 内核支持多种处理器架构,包括 ARMv6-M / ARMv7-M / ARMv8-M(Cortex-M 系列)、ARMv7-A / ARMv8-A(Cortex-A 系列)、RISC-V、x86、Xtensa 等。在嵌入式 ARM 应用中,Zephyr 具备以下突出优势:

  • 小型内核、低资源占用:内核针对资源受限设备优化,可在仅数十 KB RAM 的 MCU 上运行。
  • 高度模块化:应用可按需裁剪功能模块,仅包含所需的组件,灵活控制 footprint。
  • 丰富的内核服务:提供多线程(协作式/抢占式)、信号量、消息队列、内存管理、电源管理等完整的 RTOS 服务。
  • 原生设备树(Devicetree)支持:使用设备树描述硬件,驱动模型统一,便于跨平台移植。
  • 完善的网络与通信栈:内建 TCP/IP、BLE 5.0、Bluetooth Mesh、Thread(OpenThread)、LwM2M 等协议栈。
  • 活跃的社区与厂商支持:NXP、Nordic、STMicroelectronics 等主流芯片厂商均积极参与 Zephyr 上游开发,板级支持(BSP)持续增长。

在 NXP i.MX 8M Plus 这类异构多核 SoC 上,Zephyr 运行于 Cortex-M7 实时核心,与 Linux 运行的 Cortex-A53 应用核心协同工作,是 FreeRTOS 之外的一个现代化替代方案。

本文基于 Toradex Verdin i.MX8M Plus 嵌入式平台,演示 Zephyr RTOS 的环境搭建、交叉编译以及在 Cortex-M7 核心上的部署运行流程,并进一步测试 OpenAMP 资源表(rsc_table)demo,验证异构多核间基于 RPMsg 的核间通信。

硬件平台介绍

Verdin i.MX8M Plus 是 Toradex 推出的核心板(Computer on Module),基于 NXP i.MX 8M Plus SoC,主要规格如下:

项目 规格
应用处理器 4× Arm Cortex-A53 @ 1.6 GHz
实时微控制器 1× Arm Cortex-M7F @ 800 MHz
RAM(A53) 1GB / 2GB / 4GB / 8GB(视型号)
RAM(M7) 3×32KB(TCML、TCMU、OCRAM_S)+ 128KB OCRAM + 256MB DDR
存储(A53) 最高 32GB eMMC
网络 千兆以太网(TSN)、Wi-Fi 802.11ac 2×2 MU-MIMO、蓝牙 5.0
接口 USB 3.1、CAN、I2C、SPI、UART、GPIO 等
AI 加速 NPU(神经处理单元)、ISP(图像信号处理器)

Cortex-M7 微控制器具备 800 MHz 主频和浮点运算单元(FPU),配合紧耦合存储器(TCM)可实现极低中断延迟,适用于实时控制场景。Zephyr 在该核心上运行,与 Cortex-A53 上的 Linux 系统形成异构多核协作。

准备

硬件

  • Verdin i.MX8M Plus 核心板,搭配 Dahlia 载板
  • 连接 Dahlia 载板 X18 调试串口 ------该接口同时提供 Cortex-A53 调试串口Cortex-M7 调试串口,需分别连接以便后续操作

软件

  • 参考 Toradex Easy Installer 使用说明,将当前最新版本 Toradex Yocto Linux BSP 7.x Reference Image 烧写至 Verdin i.MX8M Plus
  • 开发主机操作系统:Ubuntu 24.04 LTS(或更新版本)

测试步骤

1. 更新开发主机系统

bash 复制代码
$ sudo apt update
$ sudo apt upgrade

2. 安装依赖工具

Zephyr 对主要构建工具的最低版本要求如下:

工具 最低版本
CMake 3.20.5
Python 3.12
Devicetree compiler 1.4.6

安装所需依赖包:

bash 复制代码
$ sudo apt install --no-install-recommends git cmake ninja-build gperf \
 ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \
 xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1

验证工具版本:

bash 复制代码
$ cmake --version
cmake version 3.28.3

$ python3 --version
Python 3.12.3

$ dtc --version
Version: DTC 1.7.0

3. 创建 Zephyr 工作区

创建 Python 虚拟环境并安装 west(Zephyr 的元工具/构建前端):

bash 复制代码
$ python3 -m venv ~/zephyrproject/.venv
$ source ~/zephyrproject/.venv/bin/activate

(.venv) $ pip install west

使用 west 初始化 Zephyr 仓库并更新依赖:

bash 复制代码
(.venv) $ west init ~/zephyrproject
=== Initializing in /home/simon/zephyrproject
--- Cloning manifest repository from https://github.com/zephyrproject-rtos/zephyr
...
=== Initialized. Now run "west update" inside /home/simon/zephyrproject.

(.venv) $ cd ~/zephyrproject
(.venv) $ west update
(.venv) $ west zephyr-export
(.venv) $ west packages pip --install

说明west update 会拉取 Zephyr 及其所有子模块(HAL、第三方库等),首次执行耗时较长,请确保网络畅通。

4. 安装 Zephyr SDK

Zephyr SDK 包含交叉编译工具链。由于 Cortex-M7 是 32 位 ARM 架构,仅需安装 arm-zephyr-eabi 工具链:

bash 复制代码
(.venv) $ cd ~/zephyrproject/zephyr
(.venv) $ west sdk install -t arm-zephyr-eabi

5. 编译 Hello World 示例

Zephyr 为 Verdin i.MX8M Plus 的 M7 核心提供了两种内存配置的 board target:

Board Target 代码运行位置 说明
verdin_imx8mp/mimx8ml8/m7 ITCM(紧耦合存储器) 低延迟,适合实时性要求高的场景,但空间有限
verdin_imx8mp/mimx8ml8/m7/ddr DDR 外部存储器 空间大,适合较大的应用程序

分别编译:

bash 复制代码
# 编译 ITCM 版本
(.venv) $ west build -b verdin_imx8mp/mimx8ml8/m7 samples/hello_world

# 编译 DDR 版本
(.venv) $ west build -b verdin_imx8mp/mimx8ml8/m7/ddr samples/hello_world

6. 部署固件到目标设备

将编译生成的二进制文件通过 SCP 传输到 Verdin i.MX8M Plus(需确保 Linux 系统已启动并联网):

bash 复制代码
(.venv) $ scp build/zephyr/zephyr.bin root@<verdin_imx8mp_ip_address>:/home/root

<verdin_imx8mp_ip_address> 替换为设备的实际 IP 地址。

7. 在 M7 核心上运行固件

通过 Cortex-A53 调试串口连接 U-Boot 控制台,执行以下命令将固件加载到 M7 核心的 ITCM 并启动:

复制代码
Verdin iMX8MP # ext4load mmc 2:2 ${loadaddr} /home/root/zephyr.bin
<size> bytes read in 2 ms (7.7 MiB/s)

Verdin iMX8MP # cp.b ${loadaddr} 0x7e0000 <size>

Verdin iMX8MP # bootaux 0x7e0000
## No elf image at address 0x007e0000
## Starting auxiliary core stack = 0x20000F80, pc = 0x00000D8D...

说明

  • ext4load 从 eMMC 的 ext4 分区读取固件到内存
  • cp.b 将固件从加载地址复制到 ITCM 起始地址 0x7e0000
  • bootaux 命令启动辅助核心(M7)
  • <size>ext4load 命令输出的实际文件字节数,需替换为实际值

8. 查看运行结果

切换到 Cortex-M7 调试串口,可看到 Zephyr 启动输出:

复制代码
*** Booting Zephyr OS build v4.4.0-4978-g8cb75f4fbdde ***
Hello World! verdin_imx8mp/mimx8ml8/m7

至此,Zephyr RTOS 已成功在 i.MX8M Plus 的 Cortex-M7 核心上运行。

OpenAMP rsc_table Demo:异构核间通信测试

在完成 Hello World 基础运行验证后,进一步测试 Zephyr 的 OpenAMP 资源表(rsc_table)示例,验证 Cortex-A53(Linux)与 Cortex-M7(Zephyr)之间基于 RPMsg 的核间通信。

9. 修改 Yocto Linux 设备树 Overlay

为了使 Linux 端的 remoteproc 框架能够正确加载 Zephyr 固件并进行 RPMsg 通信,需要修改设备树 overlay 文件 verdin-imx8mp_hmp_overlay.dts

主要修改点:

  • 调整 mailbox 通道配置(mboxes 属性),使其与 Zephyr 端的 IPM 配置匹配
  • 移除 rsc_table 内存区域引用(由 Zephyr 固件自行管理资源表)
  • 为 vring buffer 添加 shared-dma-pool 兼容属性

diff 内容:

diff 复制代码
--- verdin-imx8mp_hmp_overlay.dts.bak 2026-06-18 17:05:15.280623216 +0800
+++ verdin-imx8mp_hmp_overlay.dts 2026-07-02 17:22:03.948562862 +0800
@@ -22,10 +22,10 @@
  compatible = "fsl,imx8mp-cm7";
  clocks = <&clk IMX8MP_CLK_M7_DIV>;
  mbox-names = "tx", "rx", "rxdb";
- mboxes = <&mu 0 1
- &mu 1 1
- &mu 3 1>;
- memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>, <&m7_reserved>;
+ mboxes = <&mu 0 0
+ &mu 1 0
+ &mu 3 0>;
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&m7_reserved>;
  rsc-da = <0x55000000>;
  syscon = <&src>;
  fsl,startup-delay-ms = <500>;
@@ -50,11 +50,13 @@
  };

  vdev0vring0: vdev0vring0@55000000 {
+ compatible = "shared-dma-pool";
  no-map;
  reg = <0 0x55000000 0 0x8000>;
  };

  vdev0vring1: vdev0vring1@55008000 {
+ compatible = "shared-dma-pool";
  no-map;
  reg = <0 0x55008000 0 0x8000>;
  };

修改完成后,编译新的 verdin-imx8mp_hmp_overlay.dtbo 并替换 /boot/overlays/verdin-imx8mp_hmp_overlay.dtbo,然后重启设备使配置生效。

10. 添加 Zephyr 端配置文件

在 Zephyr 源码中为 openamp_rsc_table 示例添加板级配置文件和设备树 overlay。

Kconfig 配置文件 samples/subsys/ipc/openamp_rsc_table/boards/verdin_imx8mp_mimx8ml8_m7.conf

复制代码
CONFIG_LOG_PRINTK=n
CONFIG_IPM_IMX_MAX_DATA_SIZE_16=n
CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y
CONFIG_OPENAMP_WITH_DCACHE=y
CONFIG_LOG=y
CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_DEFAULT_LEVEL=0
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_OPENAMP_RSC_TABLE_IPM_RX_ID=0
CONFIG_OPENAMP_RSC_TABLE_IPM_TX_ID=1

配置说明:

  • CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y:将 IPM 数据包大小限制为 4 字节,与 i.MX8MP 的 MU 硬件匹配
  • CONFIG_OPENAMP_WITH_DCACHE=y:启用数据缓存支持,确保共享内存一致性
  • CONFIG_OPENAMP_RSC_TABLE_IPM_RX_ID=0 / CONFIG_OPENAMP_RSC_TABLE_IPM_TX_ID=1:配置 IPM 收发通道 ID

设备树 Overlay samples/subsys/ipc/openamp_rsc_table/boards/verdin_imx8mp_mimx8ml8_m7.overlay

dts 复制代码
/ {
 chosen {
 /*
 * shared memory reserved for the inter-processor communication
 */
 zephyr,ipc_shm = &shram;
 zephyr,ipc = &mailbox0;
 };

 shram: memory@55000000 {
 compatible = "mmio-sram";
 reg = <0x55000000 0x500000>;
 };
};

&mailbox0 {
 status = "okay";
};

该 overlay 定义了:

  • 共享内存区域(shram):起始地址 0x55000000,大小 0x500000(5MB),与 Linux 设备树中的 vring buffer 区域对齐
  • IPC 通道:使用 mailbox0 作为核间通信通道

11. 编译 openamp_rsc_table 示例

bash 复制代码
(.venv) $ west build -p always -b verdin_imx8mp/mimx8ml8/m7 samples/subsys/ipc/openamp_rsc_table

-p always 选项强制重新构建,确保所有配置变更生效。

12. 配置 U-Boot 环境变量

在 Verdin i.MX8M Plus 上,Linux remoteproc 框架需要确保 M7 核心的时钟驱动已正确初始化。需要添加以下 U-Boot 环境变量,使内核参数 clk-imx8mp.mcore_booted=1 在启动时传递给 Linux,告知时钟驱动 M7 核心已由 bootloader 启动。

bash 复制代码
root@verdin-imx8mp-06849028:~# fw_setenv tdxargs "clk-imx8mp.mcore_booted=1"

说明

  • fw_setenv 用于在 Linux 用户空间修改 U-Boot 环境变量
  • tdxargs 是 Toradex 平台的内核启动附加参数变量
  • clk-imx8mp.mcore_booted=1 告知 clk-imx8mp 时钟驱动 M7 核心已启动,避免 remoteproc 加载固件时出现时钟初始化冲突

设置完成后,重启设备使 U-Boot 环境变量生效。

13. 通过 Linux remoteproc 加载运行固件

将编译生成的 ELF 文件部署到目标设备,并通过 Linux 的 remoteproc 框架加载运行:

bash 复制代码
root@verdin-imx8mp-06849028:~# cp zephyr_openamp_rsc_table.elf /lib/firmware/
root@verdin-imx8mp-06849028:~# echo stop > /sys/class/remoteproc/remoteproc0/state 2>/dev/null
root@verdin-imx8mp-06849028:~# echo zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware
root@verdin-imx8mp-06849028:~# echo start > /sys/class/remoteproc/remoteproc0/state

操作说明:

  1. 将 ELF 固件复制到 /lib/firmware/ 目录(remoteproc 默认搜索路径)
  2. 停止当前运行的 remoteproc 实例(如果已存在)
  3. 指定固件文件名
  4. 启动 remoteproc,此时 M7 核心开始运行 Zephyr

注意 :与 Hello World 示例通过 U-Boot bootaux 手动启动不同,OpenAMP demo 使用 Linux 的 remoteproc 框架管理 M7 核心的生命周期,支持固件的动态加载、启动和停止。

14. 查看 M7 核心启动输出

切换到 Cortex-M7 调试串口,可看到 Zephyr 启动输出:

复制代码
*** Booting Zephyr OS build v4.4.0-5071-gfb64460fd6e5 ***

uart:~$

启动成功后会进入 Zephyr Shell 命令行界面,可通过 UART 进行交互。

15. 测试 RPMsg 核间通信

在 Linux 端通过 RPMsg 设备与 M7 核心进行通信测试:

bash 复制代码
root@verdin-imx8mp-06849028:~# cat /dev/ttyRPMSG1 &
[2] 595
root@verdin-imx8mp-06849028:~# echo "Hello Zephyr on Toradex Verdin i.MX8MP" > /dev/ttyRPMSG1
TTY 0x0402: Hello Zephyr on Toradex Verdin i.MX8MP

测试结果说明:

  • cat /dev/ttyRPMSG1 &:在后台监听 RPMsg 通道 1 的接收数据
  • echo ... > /dev/ttyRPMSG1:通过 RPMsg 通道 1 向 M7 核心发送字符串
  • TTY 0x0402: Hello Zephyr on Toradex Verdin i.MX8MP:M7 核心通过 RPMsg 将接收到的消息回显到 Linux 终端,验证双向通信正常

以上结果表明 Linux(Cortex-A53)与 Zephyr(Cortex-M7)之间的 RPMsg 核间通信链路已成功建立并工作正常。

总结

本文基于 NXP i.MX8M Plus(Toradex Verdin 平台)完整演示了 Zephyr RTOS 的开发流程,包括:

  1. 开发环境搭建:依赖安装、Python 虚拟环境、west 元工具
  2. Zephyr 源码获取:west init/update 拉取完整工作区
  3. 交叉编译工具链 :通过 west sdk install 安装 ARM 工具链
  4. 应用编译 :使用 west build 针对不同内存配置(ITCM/DDR)构建
  5. 固件部署与运行:通过 U-Boot 将固件加载到 M7 核心并启动
  6. OpenAMP 核间通信测试:修改设备树 overlay,配置 Zephyr 端参数,通过 Linux remoteproc 框架加载 openamp_rsc_table demo,验证基于 RPMsg 的 A53-M7 双向通信

Zephyr 作为现代化的开源 RTOS,在 i.MX8M Plus 异构平台上为 Cortex-M7 实时核心提供了 FreeRTOS 之外的另一种选择,具有设备树驱动、高度模块化、丰富的协议栈支持以及成熟的 OpenAMP 核间通信框架等优势,适合工业自动化、IoT 网关、智能家居等需要 Linux + RTOS 协同工作的应用场景。

参考链接

相关推荐
Quincy_Freak9 小时前
银河麒麟 SQLite 实操:Excel 导入与 SQL 语法编辑功能详解摘要
数据库·arm·数据库管理·大数据分析·银河麒麟·aarch64·sqlitego
Quincy_Freak2 天前
信创内网数据规范实践:银河麒麟下SQLite本地数据安全管理方案
数据库·sqlite·arm·数据库管理·大数据分析·银河麒麟·aarch64
凉、介2 天前
ARMv8 架构下的刷 Cache 操作
c语言·笔记·学习·架构·嵌入式·arm
奔跑的架构师3 天前
[A-48]ARMv9/v8-电源状态管理机制(PSCI协调机制)
android·linux·arm开发·arm
凉、介3 天前
KVM + QEMU 虚拟化
笔记·学习·嵌入式·arm·qemu·虚拟化·kvm
secondyoung4 天前
Cortex-R52学习:存储系统
arm开发·单片机·学习·arm
阿米亚波21 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
ScilogyHunter21 天前
Zephyr串口驱动开发及构建完全指南
驱动开发·uart·zephyr
ScilogyHunter21 天前
Zephyr Hello World应用开发构建完全指南
zephyr·hello world