新闻详情

新闻详情

首页 / 资讯中心 / 详情

Zephyr BSP: 06-SoC设备树实战

发布时间:2026/9/29 8:15:50来源:尧图网络
Zephyr BSP: 06-SoC设备树实战
摘要:本文是 Zephyr SoC Porting 系列的第 06 篇,从实战角度讲解如何为假想 SoC 编写 Devicetree。文章以一个虚构芯片的寄存器地址为起点,逐步演示了 SoC DTSI 与 Board DTS 的区别、UART/GPIO 等外设的 DTS 描述方法、compatible与 Driver 的匹配机制、reg/interrupts/clocks/resets等关键属性的含义,并梳理了从硬件 Memory Map → DTS → Binding → Driver 的完整链路。最后给出 SoC BSP 开发时 DTS 的落地步骤与学习建议,帮助读者建立从"会看 DTS"到"能为自家 SoC 建立 Devicetree 硬件描述体系"的完整思维模型。SoC Devicetree 实战这一篇建议正式进入Zephyr SoC Porting 的第二个核心环节:Devicetree。前面几篇的逻辑已经形成了:01 Hardware Model ↓ 02 Architecture → SoC → Board ↓ 03 BSP / Board 组织 ↓ 04 SoC Porting ↓ 05 SoC Devicetree ↓ 06 SoC Devicetree 实战 ← 现在这一篇不要再停留在"Devicetree 是什么",而是要真正做一次:从一个假想 SoC 的寄存器地址开始,逐步把它描述成 Zephyr 可以使用的 Devicetree。1. 这一篇要解决什么问题?假设公司有一颗 SoC:Company SoC │ ├── CPU │ └── Cortex-M4 │ ├── SYS │ ├── Clock │ └── Reset │ ├── UART0 │ └── 0x4000_0000 │ ├── GPIO │ └── 0x4001_0000 │ ├── TIMER0 │ └── 0x4002_0000 │ └── SPI0 └── 0x4003_0000硬件手册可能告诉你:UART0 Base Address=0x40000000 GPIO Base Address=0x40010000 TIMER Base Address=0x40020000 SPI0 Base Address=0x40030000但是 Zephyr 并不知道这些东西。你需要把:Hardware Memory Map ↓ Devicetree ↓ Zephyr Device Model ↓ Driver连接起来。2. 最重要的理解:Devicetree 不是"配置文件"很多刚开始做 Zephyr BSP 的人会把 DTS 理解成:“一个配置硬件参数的文件。”这个理解不够准确。对于 SoC BSP 开发来说,更准确的是:Devicetree 是 Zephyr 对硬件结构的描述。例如:UART0 ├── address ├── size ├── interrupt ├── clock ├── status └── compatible这些信息最终告诉 Zephyr:这里有一个 UART 设备 ↓ 它位于 0x40000000 ↓ 它使用 IRQ5↓ 它属于某种 UART compatible ↓ 应该匹配某个 driver3. SoC Devicetree 与 Board Devicetree 的区别这是做公司 SoC BSP 时必须掌握的。假设:Company SoC │ ├── UART0 ├── UART1 ├── GPIO ├── SPI0 └── TIMER0这些属于SoC 固有硬件。而:开发板 │ ├── LED → GPIO0 Pin5├── Button → GPIO0 Pin10├── UART connector → UART0 └── SPI Flash → SPI0这些属于Board。因此:为了更直观地建立两者的边界认知,下面从五个维度对比 SoC DTSI 与 Board DTS:对比维度SoC DTSI(mychip.dtsi)Board DTS(myboard.dts)描述对象SoC 固有硬件:CPU、UART、GPIO、SPI、TIMER 等芯片内部外设开发板上的资源:LED、Button、UART connector、SPI Flash 等板级外设文件位置dts/arm/mycompany/mychip/mychip.dtsiboards/arm/myboard/myboard.dts典型内容compatible、reg、interrupts、clocks、resets、gpio-controller等外设属性model、aliases、leds、uart0 { status = "okay"; }等板级配置status 默认值通常为"disabled",SoC 层默认关闭所有外设通过uart0 { status = "okay"; }按需打开修改频率低,芯片定型后基本不变高,随开发板设计、外设增减而频繁调整一句话总结:SoC DTSI 回答「这颗芯片有什么」,Board DTS 回答「这块板子怎么用」。前者是芯片的「户口本」,后者是板子的「使用说明书」。核心原则:SoC DTSI 描述 SoC 有什么。Board DTS 描述这块板子怎么使用这些硬件。4. 一个最小 SoC Devicetree我们先假设公司 SoC 名叫:mycompany,mychip创建:dts/ └── arm/ └── mycompany/ └── mychip/ └── mychip.dtsi最简单可以从:/{compatible="mycompany,mychip";cpus{cpu0:cpu@0{compatible="arm,cortex-m4";device_type="cpu";reg=0;};};};开始。这里最重要的是:compatible="mycompany,mychip";它表示:这是我们的 SoC。5. 添加 UART假设硬件手册:UART0 Base=0x40000000 Size=0x1000 IRQ=5那么:uart0: uart@40000000{compatible="mycompany,my-uart";reg=0x40000000 0x1000;interrupts=5;status="disabled";};于是:Hardware │ │ UART0 │ ├── Base=0x40000000 ├── Size=0x1000 └── IRQ=5│ ↓ Devicetree到这里,我们已经把 UART0 描述进了 Devicetree。把前面第 4 节的 CPU 节点和第 5 节的 UART0 节点组合起来,就得到一份包含 CPU 和 UART0 的 mychip.dtsi:/{compatible="mycompany,mychip";/* 整个 SoC 的 compatible,标识这是 mycompany 的 mychip */cpus{#address-cells=1;#size-cells=0;cpu0:cpu@0{compatible="arm,cortex-m4";/* CPU 内核类型,Zephyr 据此匹配内核支持 */device_type="cpu";/* 固定写法,表示这是一个 CPU 节点 */reg=0;/* CPU 编号,单核 SoC 通常为 0 */};};soc{compatible="simple-bus";/* 表示该节点下的子节点都是内存映射外设 */ranges;/* 子节点 reg 地址直接映射到父地址空间 */uart0:uart@40000000{compatible="mycompany,my-uart";/* 外设类型,Driver 靠它匹配 */reg=0x400000000x1000;/* 基地址 0x40000000,寄存器空间 0x1000 */interrupts=5;/* UART0 使用 IRQ 5 */status="disabled";/* SoC 层默认关闭,由 Board 层打开 */};};};这段代码把「CPU 是什么、UART0 在哪里、用哪个中断」都描述清楚了,是后续添加 GPIO、TIMER 等外设的基础骨架。对应:uart0: uart@40000000{compatible="mycompany,my-uart";reg=0x40000000 0x1000;interrupts=5;status="disabled";};6. 为什么默认是 disabled?这里非常重要。SoC 可能有:UART0 UART1 UART2但某个具体 Board 可能只使用:UART0因此 SoC 层通常可以定义:status="disabled";然后 Board 打开:uart0{status="okay";};于是:SoC DTSI UART0 disabled │ ↓ Board DTS │ └── status="okay"这就是SoC → Board override。7. 添加 GPIO假设:GPIO Base=0x40010000 IRQ=6可以:gpio0: gpio@40010000{compatible="mycompany,my-gpio";reg=0x40010000 0x1000;interrupts=6;gpio-controller;# gpio-cells = 2;status="disabled";};这里第一次出现:gpio-controller;它表示:这个 node 是一个 GPIO controller。而:# gpio-cells = 2;表示其他设备引用 GPIO 时,需要提供两个参数。例如:led0{gpios=gpio05GPIO_ACTIVE_HIGH;};现在把 GPIO0 和 TIMER0 也加进来,就得到一份包含 CPU、UART0、GPIO0、TIMER0 四个节点的完整 mychip.dtsi:/{compatible="mycompany,mychip";/* 整个 SoC 的 compatible,标识这是 mycompany 的 m
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

AI工程化从零实践:从大模型接口到稳定系统的完整搭建指南 2026/9/29 9:17:24

AI工程化从零实践:从大模型接口到稳定系统的完整搭建指南

看到“ai-engineering”这个热搜词的时候,我第一反应不是去看哪个新框架又火了,而是想起自己从零折腾“AI工程化”的那几个月。说实话,当时我也以为AI工程就是调通大模型接口、写几句提示词、把输出拼成JSON返回给前端。真把一个项目推到能稳…

阅读更多 →
MCP 协议使用核心讲解:TaoToken 统一 Key 接入 Cline 的 config.toml 配置骨架 2026/9/29 9:17:17

MCP 协议使用核心讲解:TaoToken 统一 Key 接入 Cline 的 config.toml 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
超高PSRR线性稳压器LT3045应用电路设计与调试实战 2026/9/29 9:17:17

超高PSRR线性稳压器LT3045应用电路设计与调试实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
内存芯片结构与对齐原理:从封装到存储单元的硬核解析 2026/9/29 9:17:10

内存芯片结构与对齐原理:从封装到存储单元的硬核解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
10分钟上手Robin:AI暗网情报工具的安装与基础配置教程 2026/9/29 9:17:10

10分钟上手Robin:AI暗网情报工具的安装与基础配置教程

10分钟上手Robin:AI暗网情报工具的安装与基础配置教程 Robin是一款强大的AI驱动暗网情报工具,专为网络安全研究人员和情报分析师设计。本教程将帮助你在10分钟内完成Robin的安装与基础配置,快速开启暗网情报收集之旅。 准备工作&#xff1a…

阅读更多 →
园区网三层架构落地实战:从VLAN配置到跨VLAN通信验证 2026/9/29 9:17:03

园区网三层架构落地实战:从VLAN配置到跨VLAN通信验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉