0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT-Thread 新一代驱动框架 DM 揭秘:从设备树到动态加载,彻底告别硬编码 | 技术集结

RT-Thread官方账号 2026-04-24 18:05 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在传统的 RTOS 驱动开发中,硬件资源往往靠硬编码、设备与驱动强耦合,导致移植难、复用低、维护成本高。

如今,RT-Thread 推出了新一代DM(Device Manager)驱动框架,引入设备树(Device Tree)、自动匹配与动态 probe 机制,让驱动开发更加现代化、可扩展。

本文以qemu-virt64-aarch64 平台为例,带你从零上手DM 框架

设备树的三种使用方式

最小系统与多核启动实战

与传统驱动框架的对比

如果你是嵌入式开发RT-Thread 爱好者,这篇文章将帮你快速掌握下一代 RT-Thread 驱动开发范式。

目录


简介


核心特点


两种驱动框架对比


DM使用方式(以qemu-virt64-aarch64为例)

1 简介

RT-Thread 新一代 DM(Device Manager)驱动框架,是近年来引入的一套现代化设备驱动管理模型。

该框架主要面向高性能平台(MPU / SoC),通过引入类似 Linux 驱动模型的设计理念,实现:

设备与驱动解耦

基于设备树(Device Tree)的硬件描述

自动匹配与动态加载(probe 机制)

其目标是逐步替代或并行于传统静态设备注册方式,构建更加统一、灵活、可扩展的驱动体系。

2 核心特点

基于设备树描述硬件资源

Driver / Device 解耦

自动匹配(compatible)

动态 probe / remove 机制

更适合复杂 SoC 平台

3 两种驱动框架对比

2728cd18-3fc5-11f1-ab55-92fbcf53809c.png

4 DM使用方式(以qemu-virt64-aarch64为例)

4.1 准备工作

获取最新RT-Thread源码 本文档使用commit: 2b58dec87b584aa7ded6e8c736498716f8d29cd0

进入BSP 目录:bsp/qemu-virt64-aarch64

打开menuconfig,开启 SMART 选项

下载 SMART 专用工具链,并设置RTT_EXEC_PATH与RTT_CC_PREFIX环境变量

4.2 设备树使用方式

在 DM 框架中,设备树(Device Tree)是核心输入,用于描述硬件资源(UART、GIC、VirtIO 等)。

当前支持三种方式:

方式一:使用 QEMU 自动生成 DTB

QEMU 的 virt 平台可以自动生成设备树,并通过寄存器传递给内核。

启动命令:

qemu-system-aarch64\ -M virt,gic-version=2\ -cpu cortex-a53\ -m128M\ -smp4\ -kernel rtthread.bin\ -nographic

原理:

QEMU 在启动时动态构建 DTB

将 DTB 地址通过寄存器传递

RT-Thread 在 early boot 阶段解析该 DTB

方式二:使用外部 DTB 文件

可以自定义 .dts 并编译为 .dtb,然后传给 QEMU:

qemu-system-aarch64\ -M virt\ -cpu cortex-a53\ -m128M\ -kernel rtthread.bin\ -dtb virt.dtb\ -nographic

设备树编译方法:

dtc -Idts -O dtb -o virt.dtbvirt.dts

方式三:内嵌设备树(RT-Thread 内置 DTB)

可以在 menuconfig 中配置:

RT_BUILTIN_FDT_PATH="path/to/your.dtb"

系统会通过 .incbin 将 DTB 嵌入到最终镜像中。

实现原理:

编译阶段将 DTB 二进制嵌入 .rodata

启动时直接使用内置 DTB,而不依赖 QEMU 传参

4.3 自定义设备树使用(最小系统示例)

本节基于一个最小可运行设备树(DTS),讲解如何在 RT-Thread DM 框架中使用自定义设备树。

4.3.1 最小设备树示例

/dts-v1/;/ { compatible ="linux,dummy-virt"; #address-cells =<2>; #size-cells =<2>; interrupt-parent = <0x8002>; memory@40000000{ reg = <0x000x400000000x000x8000000>; device_type ="memory"; }; chosen { stdout-path ="/pl011@9000000"; }; cpus { #size-cells =<0x00>; #address-cells =<0x01>; cpu@0{ reg = <0x00>; compatible ="arm,cortex-a53"; device_type ="cpu"; }; }; intc@8000000{ phandle = <0x8002>; reg = <0x000x80000000x000x100000x000x80100000x000x10000>; compatible ="arm,cortex-a15-gic"; ranges; #size-cells =<0x02>; #address-cells =<0x02>; interrupt-controller; #interrupt-cells =<0x03>; }; timer { interrupts = <0x010x0d0x1040x010x0e0x1040x010x0b0x1040x010x0a0x104>; always-on; compatible ="arm,armv8-timer\0arm,armv7-timer"; }; apb-pclk { phandle = <0x8000>; clock-output-names ="clk24mhz"; clock-frequency = <0x16e3600>; #clock-cells =<0x00>; compatible ="fixed-clock"; }; pl011@9000000{ clock-names ="uartclk\0apb_pclk"; clocks = <0x80000x8000>; interrupts = <0x000x010x04>; reg = <0x000x90000000x000x1000>; compatible ="arm,pl011\0arm,primecell"; };};

在上述设备树中只包含以下内容:

273d422a-3fc5-11f1-ab55-92fbcf53809c.png

使用下述命令将dts编译为dtb,交由rt-thread去解析处理

dtc -Idts -O dtb -o qemu-virt.dtb qemu-virt.dts

使用如下命令启动QEMU:

qemu-system-aarch64\ -machine virt,gic-version=2\ -cpu cortex-a53\ -smp1\ -m128M\ -kernel rtthread.elf\ -dtb qemu-virt.dtb\ -nographic

可以看到系统启动成功LOG:

[I/rtdm.ofw] Booting RT-Thread on physical CPU 0x0[I/rtdm.ofw] Machine model: linux,dummy-virt[I/rtdm.ofw] Memory node(0) ranges: 0x0000000040000000 - 0x0000000048000000[I/mm.memblock] System memory:[I/mm.memblock] [0x0000000040000000, 0x0000000048000000][I/mm.memblock] Reserved memory:[I/mm.memblock] [0x0000000040080000, 0x00000000401ef000][I/mm.memblock] [0x00000000401ef000, 0x00000000441ef000][I/mm.memblock] [0x00000000441ef000, 0x00000000443ef000][I/mm.memblock] [0x00000000443ef000, 0x00000000443f5000][I/mm.memblock] physical memory region [0x0000000040000000-0x0000000040080000] installed to system page[I/mm.memblock] physical memory region [0x00000000443f5000-0x0000000048000000] installed to system page[I/mm.memblock] 63 MB memory installed to system page[I/osi.psci] Using PSCI v1.1 Function IDs[I/rtdm.ofw] Console: uart0()\ | /- RT - Thread Smart Operating System/ | \ 5.3.0 build Mar 19 2026 08102006 - 2024 Copyright by RT-Thread team[I/drivers.serial] Using /dev/ttyS0 as default console[E/DFS.fs] mount point(/proc) already mounted![I/rtdm.mnt] File system initializationdonehello rt-threadmsh />msh />msh /

4.3.2 设备树多核启动示例

在之前menuconfig中可以看到,当前系统是支持 SMP的,并且qemu-virt64-aarch64默认配置#define RT_CPUS_NR 4,这里启动两个CPU作为演示

那么我们需要额外配置一下设备树,首先配置CPUS节点

cpus { #address-cells = <1>; #size-cells = <0>; cpu@0{ reg = <0>; enable-method= "psci"; compatible ="arm,cortex-a53"; device_type ="cpu"; }; cpu@1{ reg = <1>; enable-method= "psci"; compatible ="arm,cortex-a53"; device_type ="cpu"; };};

在这个CPU配置中,CPU多核启动需要通过调用 PSCI来完成,所以设备树中需要加入PSCI的节点,如下:

psci { migrate = <0xc4000005>; cpu_on = <0xc4000003>; cpu_off = <0x84000002>; cpu_suspend = <0xc4000001>; method= "hvc"; compatible ="arm,psci-1.0\0arm,psci-0.2\0arm,psci";};

使用下述命令将dts编译为dtb,交由rt-thread去解析处理

dtc -Idts -O dtb -o qemu-virt.dtb qemu-virt.dts

使用如下命令启动QEMU:

qemu-system-aarch64\ -machine virt,gic-version=2\ -cpu cortex-a53\ -smp1\ -m128M\ -kernel rtthread.elf\ -dtb qemu-virt.dtb\ -nographic

可以看到系统启动成功LOG:

[I/rtdm.ofw] Booting RT-Thread on physical CPU 0x0[I/rtdm.ofw] Machine model: linux,dummy-virt[I/rtdm.ofw] Memory node(0) ranges: 0x0000000040000000 - 0x0000000048000000[I/mm.memblock] System memory:[I/mm.memblock] [0x0000000040000000, 0x0000000048000000][I/mm.memblock] Reserved memory:[I/mm.memblock] [0x0000000040080000, 0x00000000401ef000][I/mm.memblock] [0x00000000401ef000, 0x00000000441ef000][I/mm.memblock] [0x00000000441ef000, 0x00000000443ef000][I/mm.memblock] [0x00000000443ef000, 0x00000000443f5000][I/mm.memblock] physical memory region [0x0000000040000000-0x0000000040080000] installed to system page[I/mm.memblock] physical memory region [0x00000000443f5000-0x0000000048000000] installed to system page[I/mm.memblock] 63 MB memory installed to system page[I/osi.psci] Using PSCI v1.1 Function IDs[I/rtdm.ofw] Console: uart0()\ | /- RT - Thread Smart Operating System/ | \ 5.3.0 build Mar 20 2026 03142006 - 2024 Copyright by RT-Thread team[I/drivers.serial] Using /dev/ttyS0 as default console[E/DFS.fs] mount point(/proc) already mounted![I/rtdm.mnt] File system initializationdonehello rt-threadmsh />[I/cpu.aa64] Call cpu 1 on successmsh />msh />msh />

注:在之前所提到的,系统启动时是根据设备树来决定系统配置的,所以,即使我们定义了 #define RT_CPUS_NR 4 也还是启动了2个CPU

如果将QEMU启动时的参数 -smp 修改的比设备树中定义的多,或将 RT_CPUS_NR 修改的比设备树中定义的少,或将系统的SMP关掉会发生什么,这里建议上手验证一下


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RTOS
    +关注

    关注

    25

    文章

    870

    浏览量

    123213
  • 驱动开发
    +关注

    关注

    0

    文章

    142

    浏览量

    12718
  • RT-Thread
    +关注

    关注

    32

    文章

    1639

    浏览量

    45207
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    01教你写RT-Thread之新建工程

    仿真,然后我们再开始步地教大家把 RT-Thread 内核 0 1 写出来,让大家彻底
    发表于 11-18 14:17 2455次阅读

    基于RT-Thread的RoboMaster电控框架设计

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择
    发表于 09-06 15:21 1658次阅读

    基于RT-Thread的简单物联网温控箱 | 技术集结

    接入网络,配套了功能完善的Web可视化监控和调参Dashboard,实现了完整的物联网闭环。整个项目充分利用了RT-Thread多线程、设备驱动框架和网络组件的能力
    的头像 发表于 12-26 18:18 7434次阅读
    基于<b class='flag-5'>RT-Thread</b>的简单物联网温控箱 | <b class='flag-5'>技术</b><b class='flag-5'>集结</b>

    RT-Thread Vector软件包:嵌入式开发的动态数组容器 | 技术集结

    RT-Thread Vector软件包:嵌入式开发的动态数组容器 | 技术集结
    的头像 发表于 01-25 09:33 5642次阅读
    <b class='flag-5'>RT-Thread</b> Vector软件包:嵌入式开发的<b class='flag-5'>动态</b>数组容器 | <b class='flag-5'>技术</b><b class='flag-5'>集结</b>

    01,教你彻底学透RT-Thread

    BSP 中使用的资源,并且可以让开发者对资源的使用情况目了然。RT-Thread应用笔记(设备驱动类)配套资料含源码:资料为RT-Thread
    发表于 04-16 16:18

    RT-Thread全球技术大会:RT-Thread上的单元测试框架与运行测试用例

    RT-Thread全球技术大会:RT-Thread上的单元测试框架与运行测试用例                 审核编辑:彭静
    的头像 发表于 05-27 16:21 2433次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:<b class='flag-5'>RT-Thread</b>上的单元测试<b class='flag-5'>框架</b>与运行测试用例

    RT-Thread设备模型框架及创建注册设备的实现

    RT-Thread设备模型框架及创建注册设备的实现方式介绍如下:
    的头像 发表于 05-28 10:38 3369次阅读
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>设备</b>模型<b class='flag-5'>框架</b>及创建注册<b class='flag-5'>设备</b>的实现

    RT-Thread全球技术大会:RNDIS设备介绍及应用

    RT-Thread全球技术大会上,以RNDIS设备驱动框架为主题,首先介绍了RNDIS设备介绍及
    的头像 发表于 05-28 14:36 2994次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:RNDIS<b class='flag-5'>设备</b>介绍及应用

    RT-Thread全球技术大会:RNDIS通信协议原理及主机驱动框架

    RT-Thread全球技术大会直播上,开发者详细介绍了RNDIS通信协议的原理及主机驱动框架,具体资料如下图:
    的头像 发表于 05-28 14:43 3630次阅读
    <b class='flag-5'>RT-Thread</b>全球<b class='flag-5'>技术</b>大会:RNDIS通信协议原理及主机<b class='flag-5'>驱动</b><b class='flag-5'>框架</b>

    RT-Thread文档_utest 测试框架

    RT-Thread文档_utest 测试框架
    发表于 02-22 18:43 2次下载
    <b class='flag-5'>RT-Thread</b>文档_utest 测试<b class='flag-5'>框架</b>

    浅析RT-Thread设备驱动框架

    RT-Thread 设备框架属于组件和服务层,是基于 RT-Thread 内核之上的上层软件。设备框架
    的头像 发表于 08-07 15:39 4258次阅读

    基于 RT-Thread 的 RoboMaster 电控框架

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择
    的头像 发表于 09-19 19:55 2665次阅读

    基于RT-Thread的RoboMaster电控框架(二)

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包
    的头像 发表于 09-20 15:16 2008次阅读

    RT-Thread设备驱动开发指南》基础篇--以先楫bsp的hwtimer设备为例

    、概述(RT-Thread设备驱动RT-Thread
    的头像 发表于 02-24 08:16 3631次阅读
    《<b class='flag-5'>RT-Thread</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b>开发指南》基础篇--以先楫bsp的hwtimer<b class='flag-5'>设备</b>为例

    RT-Thread设备的适配方法 | 技术集结

    本文基于RT-Thread现有的DM设备模型)框架,以Rock2F开发板为例,系统梳理了RK3528SoC的快速移植流程,涵盖了CLK、Pinctrl、ADC、NVMEM、Therm
    的头像 发表于 04-04 18:05 3135次阅读
    <b class='flag-5'>RT-Thread</b> 中<b class='flag-5'>设备</b><b class='flag-5'>树</b>的适配方法 | <b class='flag-5'>技术</b><b class='flag-5'>集结</b>