Linux内核与驱动:GPIO设备树与SPI设备树的区别

首先先看SPI的整体应用-内核-硬件的框架:

在硬件层我们可以看到存在SPI控制器和SPI外设,而我们一般操作的是外设,所以写的驱动也是外设的驱动,而SPI控制器连接的是SPI适配器的驱动层,这部分驱动是由芯片原厂工程师进行编写的。

我们本篇文章描述的是设备树的写法,我们知道设备树描述的是**硬件设备与CPU无法自动发现的硬件连接关系,**由图可知,对于SPI来说,或者说对于我们要编写一个SPI外设来说,具有两个硬件设备,一个是SPI控制器,一个是SPI外设,一般情况下SPI控制器的设备树是原厂工程师写好了的,所以我们一般只需要自己写SPI外设的设备树即可。

**GPIO:**GPIO也是如此,分为GPIO控制器和GPIO"外设"(即使用GPIO的设备,如led),我们需要编写的也是GPIO"外设"的设备树。、

接下里我们对比两种外设的写法:

GPIO控制器及其GPIO使用者设备树

GPIO控制器:

bash 复制代码
gpio1: gpio@0209c000 {
    compatible = "fsl,imx6ul-gpio";
    reg = <0x0209c000 0x4000>;
    interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;

    gpio-controller;
    #gpio-cells = <2>;

    interrupt-controller;
    #interrupt-cells = <2>;
};

可知,这个节点可以作为GPIO控制器,也可以作为中断控制器。

GPIO"外设":

bash 复制代码
led {
    compatible = "mycompany,myled";
    led-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};

SPI控制器及其外设设备树

SPI控制器:

spi控制器节点一般在芯片级.dtsi文件中。

SPI外设:

bash 复制代码
&spi0 {
    status = "okay"; // 启用 SPI0 控制器
    pinctrl-names = "default";
    pinctrl-0 = <&spi0m1_pins>; // 确保引脚复用配置正确

    /* 你的外设子节点 */
    my_sensor@0 {
        compatible = "vendor,my-sensor-model"; // 必须与驱动中的 of_match_table 一致
        reg = <0>;                             // 使用 CS0 (片选0)
        spi-max-frequency = <10000000>;        // 最大时钟频率 10MHz
        
        /* 可选属性 */
        spi-cpol;                              // 如果外设需要 CPOL=1
        spi-cpha;                              // 如果外设需要 CPHA=1
        
        /* 中断引脚配置(如果外设带中断) */
        interrupt-parent = <&gpio1>;
        interrupts = <RK_PA1 IRQ_TYPE_EDGE_FALLING>;
    };
};

写法分析

我们可以发现 GPIO 和 SPI 都有"控制器"和"外设",但它们在设备树里的写法不同,根本原因是:

SPI 是总线,外设是挂在 SPI 控制器下面的"子设备";GPIO 不是总线,外设只是"使用了某几根 GPIO 线"。

设备树既可以用父子节点 表示总线拓扑,也可以用 phandle 引用表示资源连接关系。Linux 设备树文档也说明,DT 本质是描述硬件的数据结构,除了树形父子关系外,还允许节点之间建立任意引用关系;常见 binding 会描述 data bus、GPIO connection、interrupt line、peripheral device 等硬件特征。

SPI 是典型总线结构:

bash 复制代码
SPI 控制器
 ├── CS0 外设
 ├── CS1 外设
 └── CS2 外设

而GPIO不是父子结构,GPIO 更像是一组"可借用的引脚资源"。

对比 SPI GPIO
本质 总线 引脚资源
外设和控制器关系 外设挂在 SPI 控制器下面 外设使用 GPIO 控制器的一根线
设备树表示 父子节点 phandle 引用
外设身份 spi_device 通常是 platform device / input device / led device 等
地址含义 reg = <CS号> <&gpiox pin flags>
内核解析 SPI core 扫描子节点 GPIO consumer API 解析 xxx-gpios
相关推荐
雯宝4 小时前
mnt_init 函数
linux
UIU1144 小时前
递归算法与汉诺塔
c++·学习·算法·c#·递归
Fruit_Caller5 小时前
static
开发语言·c++
律宏阔10 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔10 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴10 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千10 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei3710 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei3710 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei3710 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化