当前位置: 首页 > news >正文

【Linux驱动-快速回顾】简单了解一下PinCtrl子系统:设备树如何被接解析与匹配

下面用 “一段真实板级 .dts 代码”
“i2c1 节点 + pinctrl-0 从设备树 → 内核 → 寄存器” 的 全流程 逐行拆开讲清。

&i2c1 {clock-frequency = <100000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_i2c1>;status = "okay";
};&iomuxc {pinctrl_i2c1: i2c1grp {fsl,pins = <MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0>;};
};

Step-0 先记住 3 个文件角色

文件作用
imx6ull.dtsiSoC 通用:声明“芯片里有 I²C1 控制器”,默认 status = "disabled"
imx6ull-evk.dts板级:把 I²C1 的时钟、引脚、状态补全
imx6ull-pinfunc.h芯片头文件:把宏 MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 翻译成寄存器偏移

Step-1 编译阶段(dtc)

dtc -I dts -O dtb imx6ull-evk.dts -o imx6ull-evk.dtb
  • &i2c1 展开后变成 节点路径 /soc/i2c@021a0000
  • pinctrl-0 = <&pinctrl_i2c1> 变成 phandle 指向 i2c1grp
  • 宏展开(以 SCL 为例)
MX6UL_PAD_UART4_TX_DATA__I2C1_SCL└─展开为 _MX6_PIN(0x01B0, 0x0460, 0x0000, ALT2, 0x4001b8b0)

得到 4 组数字:

  • MUX 偏移 0x01B0
  • PAD 偏移 0x0460
  • ALT 功能号 ALT2
  • 电气值 0x4001b8b0

Step-2 U-Boot 把 .dtb 塞进内存,启动内核

bootz zImage - dtb_addr

内核把整块 DTB 解析成 device_node 树

struct device_node *dn = of_find_node_by_path("/soc/i2c@021a0000");

此时 dn->properties 里已经有:

clock-frequency = 100000
pinctrl-names   = "default"
pinctrl-0       = <phandle_to_i2c1grp>
status          = "okay"

Step-3 内核 probe 链

① pinctrl 子系统先行

imx_pinctrl_probe()├─ 解析 phandle → 找到 i2c1grp├─ 对每条 fsl,pins 调用imx_pinctrl_set_mux()   /* 写 MUX 寄存器 0x020E0000+0x01B0 = ALT2 */imx_pinctrl_set_pad()   /* 写 PAD 寄存器 0x020E0000+0x0460 = 0x4001b8b0 */

结果:

  • UART4_TX_DATA 物理球I²C1_SCL 功能
  • 上拉 50 Ω、100 MHz、开漏 等电气特性生效

② I²C 驱动匹配

static const struct of_device_id imx_i2c_dt_ids[] = {{ .compatible = "fsl,imx6ul-i2c", },{ .compatible = "fsl,imx21-i2c", },{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_i2c_dt_ids);
  • i2c_imx_probe() 通过 of_match_table 匹配到 i2c@021a0000
  • clock-frequency = 100000 读出来 → 设置 I²C 波特率
  • platform_get_resource_byname() 拿到中断号、寄存器基址
  • 注册 i2c-1 总线到内核

Step-4 用户空间验证

# 板子上电后
ls /sys/bus/i2c/devices/0-0050    # 设备节点出现
i2cdetect -y 1                    # 扫描到 EEPROM 0x50

至此,I²C1 控制器 + 两根引脚 + 外设 打通。


一句话回顾

  1. 板厂.dts 里用宏“连线”。
  2. dtc 把宏翻译成寄存器偏移 + 电气值。
  3. 内核 probe 时把寄存器写到位,I²C1 就活了。
http://www.lryc.cn/news/593178.html

相关文章:

  • 大模型 Function Call 的实现步骤及示例详解
  • SpringBoot 3.0 挥别 spring.factories,拥抱云原生新纪元
  • Java机考题:815. 公交路线 图论BFS
  • 猎板:在 5G 与 AI 时代,印制线路板如何满足高性能需求
  • SQL Server和PostgreSQL填充因子
  • 数据结构与算法之美:拓扑排序
  • 小谈相机的学习过程
  • ROS2 通过相机确定物品坐标位置
  • MySQL数据丢失救援办法
  • 异步解决一切问题 |消息队列 |减少嵌套 |hadoop |rabbitmq |postsql
  • 智能体之变:深度解析OpenAI ChatGPT Agent如何重塑人机协作的未来
  • 【Qt开发】Qt的背景介绍(三)-> 认识Qt Creator
  • 论文略读:Are Large Language Models In-Context Graph Learners?
  • 高可用架构设计与实践综述
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 基于wordcloud库实现词云图
  • 暑假训练七
  • 进阶向:基于Python的智能客服系统设计与实现
  • 安装单机版本Redis
  • 13.4 Meta LLaMA开源模型家族全面解析:从Alpaca到Vicuna的技术内幕
  • Ubuntu 22.04.3 LTS 安装 MySQL
  • Gitee 提交信息的规范
  • docker构建springboot镜像
  • LLM大模型微调技术与最佳实践
  • 小木的机器学习日记——线性回归算法-1
  • 【Linux】AKHQ实现kafka可视化
  • 3516cv610 npu 开发典型功能点的介绍
  • Helm常用命令大全(2025最新版)
  • 教育科技内容平台的破局之路:从组织困境到 UGC 生态的构建
  • ARINC818协议综述
  • 《全栈博客系统的技术肌理:从接口构建到体验升维的实践路径》