Zephyr RTOS 移植实战:在 Luckfox Pico Ultra W(Rockchip RV1106)上运行 hello_world
【免费下载链接】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
导读
本文介绍如何在 Zephyr RTOS 官方仓库中为 Luckfox Pico Ultra W 开发板构建并运行应用。该开发板基于 Rockchip RV1106(Cortex-A7 单核)芯片,板载 256MB DDR3L 内存,是一块低成本微 Linux 开发板。读完本文,你将掌握:RV1106 在 Zephyr 中的板级支持现状、U-Boot 引导链的必备改造(缓存命令与 Thumb 模式修正)、Zephyr 应用的构建命令,以及通过 TFTP 加载 Zephyr 二进制并启动的完整 U-Boot 操作流程。
Luckfox Pico Ultra 开发板实物图
板卡概览:RV1106 与 Luckfox Pico Ultra W
Luckfox Pico Ultra W 是一款低成本的微 Linux 开发板,核心芯片为瑞芯微 Rockchip RV1106。该芯片在 Zephyr 仓库中的 SoC 定义为SOC_RV1106,属于 Rockchip 家族(SOC_FAMILY_ROCKCHIP),其层级关系记录在 soc/rockchip/rv1106/Kconfig.soc:
SOC_RV1106选中SOC_SERIES_RV1106SOC_SERIES_RV1106选中SOC_FAMILY_ROCKCHIPSOC默认值为"rv1106"
板级元数据中,board.yml 声明了板名pico_ultra、全名Pico Ultra、厂商luckfox以及对应 SoCrv1106;pico_ultra.yaml 则声明了标识符、架构(arch: arm)与工具链(zephyr)。
从 dts/arm/rockchip/rv1106.dtsi 可以看出该 SoC 的关键硬件特征:
- CPU:单核 ARM Cortex-A7(
compatible = "arm,cortex-a7") - 定时器:ARMv8 架构定时器(
arm,armv8-timer),时钟频率 24MHz - 中断控制器:GIC-400(
arm,gic-400,兼容 gic-v2/gic),寄存器基址0xff1f1000 - 串口:6 路 ns16550 兼容 UART(DW APB 总线,寄存器偏移
reg-shift = <2>),其中 UART2 位于0xff4c0000 - 内存:板载 256MB DDR3L DRAM
板级设备树解析
boards/luckfox/pico_ultra/pico_ultra.dts 定义了板级设备树,它包含 SoC 级设备树rockchip/rv1106.dtsi,并做了以下关键配置:
/dts-v1/; #include <rockchip/rv1106.dtsi> / { model = "Luckfox Pico Ultra W"; compatible = "luckfox,pico-ultra-w"; chosen { zephyr,sram = &ddr; zephyr,console = &uart2; zephyr,shell-uart = &uart2; }; ddr: ddr@0 { /* DDR is initialized by the FSBL before the kernel starts */ compatible = "mmio-sram"; reg = <0x0 DT_SIZE_M(256)>; }; }; &cpu0 { clock-frequency = <DT_FREQ_M(816)>; }; &uart2 { status = "okay"; current-speed = <115200>; };要点说明:
chosen节点:zephyr,sram指向ddr节点——Zephyr 将 256MB DDR 当作 SRAM 使用(由 FSBL/U-Boot 先行初始化);zephyr,console与zephyr,shell-uart均指向uart2,即 Zephyr 控制台与 shell 都走 UART2。ddr节点:reg = <0x0 DT_SIZE_M(256)>声明从地址 0x0 开始的 256MB 内存区域,注释明确指出 DDR 由引导流程(FSBL)在内核启动前完成初始化。cpu0时钟:clock-frequency = <DT_FREQ_M(816)>将 CPU 主频声明为 816MHz。uart2:波特率 115200,状态为okay。
SoC 级 Kconfig(soc/rockchip/rv1106/Kconfig.defconfig)还补充了运行所需的底层配置:
NUM_IRQS默认 160SOC_RESET_HOOK默认开启(用于复位钩子)SYS_CLOCK_HW_CYCLES_PER_SEC从设备树/timer节点的clock-frequency派生(即 24MHz)- 默认启用
UART_NS16550_DW8250_DW_APB(DW8250/DW APB 串口变体)与UART_NS16550_ACCESS_WORD_ONLY(仅 32 位字访问,配合reg-shift = <2>使用)
板级默认 defconfig(boards/luckfox/pico_ultra/pico_ultra_defconfig)保持极简,仅开启串口与控制台:
CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y启动前提:为什么需要 U-Boot 引导
RV1106 是一颗运行 Linux 的应用处理器(Cortex-A7),其 DDR 控制器、时钟等外设必须由引导程序初始化。Zephyr 的板级文档明确要求:运行 Zephyr 之前,必须先用 Luckfox SDK 的 U-Boot 完成 RV1106 的初始化。
这意味着典型启动链为:片上 ROM → FSBL(初始化 DDR)→ U-Boot(加载并跳转)→ Zephyr 二进制。
从 soc/rockchip/rv1106/soc.c 可以看到 Zephyr 侧对这一引导链的适配——soc_reset_hook会在启动早期把 VBAR(向量基址寄存器)重新指回 Zephyr 自己的向量表:
void soc_reset_hook(void) { /* * U-Boot modifies VBAR to point to its own vectors - set it to the Zephyr's vector table. */ uint32_t vbar = 0; __set_VBAR(vbar); }此外,soc/rockchip/rv1106/mmu_regions.c 定义了 MMU 映射区域,将向量表、GIC(0xff1f1000)及所有 ns16550 串口映射为设备内存:
static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_FLAT_ENTRY("vectors", 0, 0x1000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_X), MMU_REGION_FLAT_ENTRY("gic", 0xff1f1000, 0x3000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(ns16550, MT_DEVICE | MPERM_R | MPERM_W)};修改 U-Boot:两个必备补丁
默认 U-Boot 无法直接跳转运行 Zephyr,需要打两个补丁(针对 Luckfox SDK 中的 U-Boot 源码):
补丁一:取消强制 Thumb 模式
Luckfox SDK 的 U-Boot 在cmd/boot.c的do_go_exec()中,当CONFIG_CPU_V7定义时会把入口地址强制置位 Thumb 位(entry | 1),这会导致 Zephyr 的 ARM 代码以错误的指令集执行。补丁将其移除,直接以原始入口地址跳转:
--- a/sysdrv/source/uboot/u-boot/cmd/boot.c +++ b/sysdrv/source/uboot/u-boot/cmd/boot.c @@ -21,10 +21,6 @@ unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, char * const argv[]) { -#ifdef CONFIG_CPU_V7 - ulong addr = (ulong)entry | 1; - entry = (void *)addr; -#endif return entry (argc, argv); }补丁二:启用 cache 命令
Zephyr 跳转前需要关闭并冲刷 D-Cache/I-Cache(见下文启动命令),因此 U-Boot 必须启用CONFIG_CMD_CACHE提供dcache/icache命令:
--- a/sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_defconfig +++ b/sysdrv/source/uboot/u-boot/configs/luckfox_rv1106_uboot_defconfig @@ -141,3 +141,4 @@ CONFIG_SPL_GZIP=y CONFIG_ERRNO_STR=y # CONFIG_EFI_LOADER is not set +CONFIG_CMD_CACHE=y补丁应用后,按 Luckfox Pico SDK 的官方流程重新编译并烧写 U-Boot 即可。
构建 Zephyr 应用
以官方示例samples/hello_world为例,使用 west 构建:
west build -b pico_ultra samples/hello_world-b pico_ultra指定目标板(对应 boards/luckfox/pico_ultra 目录)samples/hello_world为应用源码路径(参见 samples/hello_world)
构建产物中包含zephyr.bin(位于 build 目录的zephyr/子目录下),后续将通过 TFTP 加载到板端。
通过 TFTP 加载并启动 Zephyr
板卡上电进入 U-Boot 命令行后,依次执行以下操作:
=> dcache off && icache off => dcache flush && icache flush => setenv ipaddr 192.168.1.2 => setenv serverip 192.168.1.1 => tftp 0x0 zephyr.bin => go 0x0逐步说明:
dcache off && icache off:关闭数据缓存与指令缓存。U-Boot 与 Zephyr 对缓存的维护策略不同,跳转前必须关闭,避免缓存脏数据干扰 Zephyr 运行。dcache flush && icache flush:冲刷缓存,确保内存中数据的一致性。setenv ipaddr 192.168.1.2:设置板端 IP(按实际网络环境调整)。setenv serverip 192.168.1.1:设置 TFTP 服务器(宿主机)IP。tftp 0x0 zephyr.bin:从 TFTP 服务器下载zephyr.bin到内存地址0x0(即 DDR 起始地址,对应设备树中ddr节点的reg = <0x0 DT_SIZE_M(256)>)。go 0x0:跳转到0x0执行 Zephyr。
启动成功后,串口控制台(UART2,115200 波特率)应输出:
*** Booting Zephyr OS build v4.3.0-4280-g2f3d729d951a *** Hello World! pico_ultra/rv1106其中pico_ultra/rv1106为板名/SoC 名的组合,来自 hello_world 示例对CONFIG_BOARD与CONFIG_SOC的引用。
常见问题与排查要点
go命令跳转后无输出:确认两个 U-Boot 补丁均已应用并重新烧写;检查是否已执行dcache/icache off。- 串口无打印:确认使用的是 UART2(默认调试串口,115200-8-N-1),并核对设备树中
current-speed = <115200>的配置。 - 指令集异常(Undefined Instruction):多半是
CONFIG_CPU_V7的 Thumb 位强制未被移除,请核对补丁一是否生效。 - TFTP 传输失败:确认宿主机 TFTP 服务与
serverip配置正确,且zephyr.bin位于 TFTP 根目录。 - 内存地址对齐:加载地址使用
0x0需与ddr节点起始地址一致;若跳转其他地址,需同步修改设备树reg定义与 MMU 向量表映射(参考 soc/rockchip/rv1106/mmu_regions.c 中MMU_REGION_FLAT_ENTRY("vectors", 0, ...)的映射)。
小结
本文完整还原了 Zephyr 官方文档(boards/luckfox/pico_ultra/doc/index.rst)中 Luckfox Pico Ultra W 的移植与运行流程:从板级/SoC 设备树与 Kconfig 的硬件抽象,到 U-Boot 的两处关键改造,再到 west 构建与 TFTP 加载启动。这套"U-Boot 初始化硬件 + Zephyr 接管"的双引导方案,是 Zephyr 在 Cortex-A 应用处理器(如 RV1106)上运行的典型模式,可作为后续在该板卡上开发串口、网络等外设应用的起点。
【免费下载链接】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),仅供参考