
操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载导读本文围绕 RT-Thread 的 OFWOpen Firmware基于设备树 FDT驱动模型中 platform 总线枚举实现platform_ofw.c详细剖析启动阶段设备树节点如何被遍历、过滤、实例化为struct rt_platform_device并注册到 platform 总线触发驱动probe的完整链路。读完本文你将掌握 RT-Thread 中INIT_PLATFORM_EXPORT平台的启动顺序、simple-bus等总线节点的递归规则、rt_platform_ofw_request按需请求 provider 的状态机以及时钟 provider 晚就绪等典型问题的排查方法可以直接指导 BSP 移植与设备驱动调试。一、功能定位与源码脉络platform_ofw.c是 RT-Thread DMDevice Model驱动框架中platform 总线与设备树之间的桥接层。它完成两件事被动扫描遍历 unflatten 之后的内存节点树struct rt_ofw_node为每个符合条件的节点分配struct rt_platform_device并注册到 platform 总线主动请求提供rt_platform_ofw_request()供消费者驱动在解析 phandle 后按需实例化尚未注册的 provider时钟、GPIO、pinctrl 等。相关文件路径核心实现components/drivers/core/platform_ofw.c平台驱动/设备数据结构与 API 声明components/drivers/include/drivers/platform.hplatform 总线本体匹配、probe 包装components/drivers/core/platform.cOFW 节点树核心 APIdocumentation/6.components/device-driver/ofw/ofw_base.md设备树引导unflatten 前置流程documentation/6.components/device-driver/ofw/ofw_boot.md在 ofw.md 给出的典型驱动流程中platform_ofw_device_probe处于 bootloader DTB →rt_fdt_unflatten之后、驱动probe(np)之前的关键一环是设备树节点走向设备实例的必经之路。二、Probe 顺序四个阶段的固定遍历次序platform_ofw_device_probe通过INIT_PLATFORM_EXPORT(platform_ofw_device_probe)注册到 RT-Thread 的初始化序列链接器排序键为1.2位于INIT_SUBSYS_EXPORT之后、INIT_DEVICE_EXPORT之前。其遍历顺序是刻意设计过的依赖约束源码见 platform_ofw.c顺序遍历目标目的1/clocks子树时钟 provider 必须先于消费者实例化providers before consumers2/根节点深度优先常规设备即 SoC 上的 MMIO 外设3/firmware固件代理节点如 SCMI 等4/chosen/simple-framebuffer若存在引导阶段遗留的简单帧缓冲实现细节上每个阶段都以rt_ofw_find_node_by_path()或对 chosen 使用rt_ofw_get_child_by_compatible()定位子树入口再调用内部递归函数platform_ofw_device_probe_once()扫描。若ofw_node_root为 NULL设备树尚未 unflatten函数直接返回-RT_ENOSYS。为什么/clocks优先时钟是几乎所有外设 probe 的前置依赖rt_clk_get_by_index、rt_ofw_clk_set_defaults都要用到。/clocks子树先行扫描可以确保后续普通设备的 probe 阶段时钟 provider 已经就位。若时钟 provider 因未注册驱动而 probe 失败其节点不会得到rt_ofw_data下游消费者在 phandle 解析阶段就会暴露问题——这正是第五节 pitfalls 中Clock provider late的根源。三、Child walk逐节点过滤与递归注册规则核心递归函数platform_ofw_device_probe_once(parent_np)使用宏rt_ofw_foreach_available_child_node(parent_np, np)遍历 parent 的每个availablestatus属性有效子节点见 platform_ofw.c。3.1 跳过条件对每个子节点先执行三重过滤跳过条件原因np-dev已设置该节点已被其他路径实例化为设备如被某个子设备通过rt_platform_ofw_request请求过避免重复创建RT_OFW_F_SYSTEM或RT_OFW_F_READLY标志置位系统元节点/、/cpus、/chosen等unflatten 时统一打标或已被 stub/驱动绑定的节点不作为 platform 设备既无compatible属性又无有效节点名匿名容器节点无硬件语义直接跳过其中无有效节点名的判断逻辑是name为NULL且无compatible属性。这是设备树中常见的占位/容器节点约定。3.2 命中platform_ofw_ids的分流通过rt_ofw_prop_match(compat_prop, platform_ofw_ids)将节点的compatible与静态匹配表比对。platform_ofw_ids定义见 platform_ofw.cstatic const struct rt_ofw_node_id platform_ofw_ids[] { { .compatible simple-bus, }, #ifdef RT_USING_MFD { .compatible simple-mfd, }, #endif #ifdef RT_USING_ISA { .compatible isa, }, #endif #ifdef RT_USING_AMBA_BUS { .compatible arm,amba-bus, }, #endif { /* sentinel */ } };注意simple-mfd、isa、arm,amba-bus三个条目受 Kconfig 开关RT_USING_MFD、RT_USING_ISA、RT_USING_AMBA_BUS条件编译保护simple-bus无条件启用。表中对arm,amba-bus的注释还提示ARM 未来可能用arm,primecell取代它。命中compatible动作simple-bus/simple-mfd/isa/arm,amba-bus先递归platform_ofw_device_probe_once(np)扫描其子节点总线节点自身不实例化为设备叶子节点未命中总线表alloc_ofw_platform_device(np)分配 pdev →rt_platform_device_register(pdev)注册到 platform 总线递归之后还有一个关键复查若递归过程中某个子节点被下游请求np-dev已被设置父节点会再次检查np-dev并continue防止总线节点被重复实例化。2025-12-25 的变更记录fix OFW bus conflict and prevent duplicate device creation正是对这一类竞态场景的修复。3.3 设备命名ofw_device_renamealloc_ofw_platform_device内会调用ofw_device_rename()为设备生成可读名称platform_ofw.c命名策略优先reg基址命名沿节点祖先链向上寻找第一个能通过rt_ofw_get_address(np, 0, addr, RT_NULL)解析出地址的节点生成%lx.%.*s格式如fe300000.serial若节点还带mask属性则进一步生成%lx.%x.%.*s掩码位宽参与命名无reg则退回层级路径使用rt_fdt_node_name拼接父子节点名%s:%s格式若设备已有dev_nameRT_NAME_MAX 0场景则以:%s后缀附加上。因此实际效果与 platform.md 中描述的fe300000.serial:uart0一致由reg地址 节点名 别名/设备名组合而成。四、rt_platform_ofw_request按需请求 provider 的状态机当驱动在 probe 中解析 phandle 拿到 provider 节点rt_ofw_data(provider_np)为 NULL即 provider 尚未实例化时需要调用rt_platform_ofw_request(np)主动触发 provider 注册。其原型与状态机见 platform.h 与 platform_ofw.crt_err_t rt_platform_ofw_request(struct rt_ofw_node *np);np-dev状态行为NULL无设备走alloc_ofw_platform_device(np)→ 设置dev_id ofw_alias_node_id(np)→np-dev pdev-parent→rt_platform_device_register(pdev)注册即触发匹配与probe若节点还命中platform_ofw_ids且有子节点会顺带递归扫描其子设备有dev但dev-drv为 NULL说明设备已创建但尚未绑定驱动通常是驱动注册晚于扫描。此时若设备带RT_OFW_F_PLATFORM标志调用rt_bus_reload_driver_device重新匹配驱动否则如 I2C/SPI 等原生总线的设备直接返回RT_EOK避免被错误地转交给 platform 总线 probe已 probedev-drv非 NULL直接返回RT_EOK无操作典型调用时机消费者在rt_ofw_parse_phandle_cells之后、使用子系统 API 之前见 ofw.md 的 Phandle consumer patternrt_ofw_parse_phandle_cells(np, clocks, #clock-cells, index, args)provider_np args.data若!rt_ofw_data(provider_np)→rt_platform_ofw_request(provider_np)再调用子系统 APIrt_clk_get_by_index、rt_mbox_request_channel等以时钟子系统为例clk.c 在rt_ofw_parse_phandle_cells成功后对clk_ofw_np执行了完全一致的 request 流程可视为官方参考实现。其他遵循同一模式的子系统包括resets、mboxes、io-channels、nvmem-cells等各自对应#*-cells属性详见 ofw.md。五、其他公开 API除上述两个核心函数外platform_ofw.c还导出两个 APIAPI角色rt_platform_ofw_device_probe_child(np)将单个子节点注册为 platform 设备仅适用于父节点不是/且节点带compatible、且尚未带RT_OFW_F_PLATFORM标志的场景见 platform_ofw.c否则返回-RT_EINVAL。常用于伞形驱动umbrella driver显式暴露子设备rt_platform_ofw_free(pdev)逆操作清除节点的RT_OFW_F_PLATFORM标志、rt_ofw_node_put(np)释放节点引用、rt_free(pdev)释放设备内存见 platform_ofw.c其中rt_platform_ofw_free与 platform 总线的卸载流程衔接总线调用pdrv-remove后执行 IOMMU/power domain detach最后调rt_platform_ofw_free(pdev)完成清理参见 platform.md 的 remove 流程说明。六、与 platform 总线、初始化层级的协同platform_ofw.c只是造设备的一方真正完成匹配与 probe 的是 platform 总线本体。二者通过 RT-Thread 初始化层级精确衔接详见 platform.md 的 Boot and init orderINIT_CORE → platform bus 注册rt_bus_register(platform_bus) INIT_SUBSYS → 早期驱动手动 rt_platform_driver_register可选如 pin-pl061、pinctrl-single INIT_PLATFORM → platform_ofw_device_probeDT 节点 → platform 设备入总线 → 已有驱动则立即匹配 probe INIT_DEVICE → RT_PLATFORM_DRIVER_EXPORT 注册驱动 → rt_bus_for_each_dev 重扫并 probe 全部未匹配设备由此可以得出两个重要推论设备先于驱动是常态INIT_PLATFORM阶段设备全部就位大多数驱动RT_PLATFORM_DRIVER_EXPORT在INIT_DEVICE才注册靠rt_bus_add_driver的重扫机制完成绑定——所以驱动注册晚于设备不是问题驱动必须早于扫描的例外若某驱动要在批量 DT 扫描之前就绪早期依赖必须改用INIT_SUBSYS_EXPORT 手动rt_platform_driver_register否则其节点即使被创建也无法立即 probe需等待后续重扫或rt_platform_ofw_request。从platform_ofw_ids只匹配总线类compatible可以看出不在总线表中的节点只要带compatible仍会作为叶子 platform 设备注册见下文 pitfalls 第 3 条因此总线表的裁剪只影响是否递归深入不影响节点能否成为设备。七、Pitfalls三个高频问题与规避问题规避手段时钟 provider 就绪太晚依赖/clocks节点的内建遍历顺序providers before consumers。尽量不要人为打乱INIT_PLATFORM之前的初始化层级若必须请把 provider 驱动提前到INIT_SUBSYS_EXPORT未调用rt_platform_ofw_requestprovider 永远不会被实例化——phandle 解析虽然成功拿到节点指针但rt_ofw_data始终为 NULL后续子系统 API 取不到控制器私有数据。消费者 probe 中解析 phandle 后必须检查并调用 request总线compatible不在platform_ofw_ids该总线节点自身会被当作普通叶子设备注册为 platform 设备只要带compatible其子设备不会被自动递归扫描可能因父设备未 probe 而依赖悬空另外两个易踩的坑源自 ofw_base.md 与 platform.md节点引用泄漏np的get必须与put配对alloc_ofw_platform_device内部rt_ofw_node_get(np)增加引用卸载路径由rt_platform_ofw_free归还compatible顺序设备树与驱动ids[]表中都应把最具体的字符串放最前rt_ofw_prop_match按顺序匹配。八、实战建议驱动侧完整接入流程结合本文与 platform.md一个标准 DT 驱动的接入可以归纳为三步DTS 侧节点带compatible如vendor,my-device、reg、interrupts放在simple-bus之下即可被自动扫描放在/clocks下的则是时钟 provider 场景驱动侧定义struct rt_platform_driver填充.ids my_ofw_idscompatible表末元素为 sentinel、.probe、.remove并用RT_PLATFORM_DRIVER_EXPORT(my_driver)导出probe 中通过pdev-parent调用rt_dm_dev_iomap、rt_clk_get_by_index等 DM 辅助 API依赖侧probe 内解析clocks/resets/mboxes等 phandle 属性后若rt_ofw_data(provider_np)为 NULL立即rt_platform_ofw_request(provider_np)。调试时可借助LOG_D/LOG_EDBG_TAG drv.platform观察节点是否被遍历、注册与 probe 结果设备命名形如fe300000.serial:uart0可直接在 shell 的 device 列表确认实例化是否成功。参考链接OFW 总览OFW 节点与属性base.c / ofw.cFDT 引导与 unflattenfdt.cplatform 总线与驱动注册通用 rt_bus 机制platform_ofw.c 实现源码platform.h 头文件赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread PCI 枚举与设备探测全流程解析从 Host 桥初始化到驱动 Probe 的端到端指南RT Thread PCI 枚举与设备探测全流程解析从 Host 桥初始化到驱动 Probe 的端到端指南 导读本文以 RT Thread 设备驱动框架中操作系统嵌入式物联网嵌入式OSRTOSRT-Thread PCI/PCIe 子系统指南总线枚举、BAR 分配与功能驱动开发RT Thread PCI/PCIe 子系统指南总线枚举、BAR 分配与功能驱动开发 PCI/PCIe 是 RT Thread 设备驱动框架中用于接入高性能外操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 中 Microchip SAMD51 的 USB Device Core枚举协议处理与设备类驱动管理RT Thread 中 Microchip SAMD51 的 USB Device Core枚举协议处理与设备类驱动管理 USB Device Coreus操作系统嵌入式物联网嵌入式OSRTOS上一篇为什么无需CUDA内核MaxEntScan score3 NPU 纯PyTorch算子前向传播原理详解下一篇docker-transmission性能优化调整peer-port与带宽限制提升下载速度创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考