遍历设备树规则:device_node 转换成 platform_device的规则

1.linux系统的驱动中,在arm设备树中,device_node 转换成 platform_device的规则中,如下规则的目的是什么呢 遍历包含 compatible 属性为 "simple-bus"、"simple-mfd" 或 "isa" 的节点以 及它们的子节点。如果子节点包含 compatible 属性值则会创建一个对应的 platform_device

在Linux内核的设备树(Device Tree)机制中,将device_node转换为platform_device的规则中,针对包含compatible属性为"simple-bus""simple-mfd""isa"的节点及其子节点的处理,其核心目的可以归纳为以下三点:

1. 实现硬件总线的动态抽象与设备发现

  • 总线控制器的描述
    "simple-bus""simple-mfd""isa"等属性通常用于描述总线控制器(如PCI、AMBA总线)。这些节点本身代表总线硬件,其子节点则表示挂载在该总线上的设备(如PCI设备、I2C设备)。
    • 示例:若设备树中存在一个simple-bus节点描述PCI总线控制器,其子节点可能对应具体的PCI设备(如网卡、显卡)。
  • 自动创建子设备
    当内核检测到某个节点的compatible属性为上述值时,会将其子节点(需同样包含compatible属性)自动转换为platform_device。这一过程模拟了硬件总线的自动探测机制,使得总线控制器驱动能动态发现并管理挂载的设备。

2. 支持复杂硬件拓扑的模块化描述

  • 分层硬件结构
    现代SoC(系统级芯片)通常包含多层总线结构(如CPU总线、外设总线)。通过simple-bus等属性,设备树可以分层描述这些总线及其挂载的设备,形成树状拓扑。
    • 示例

      / {
          soc {
              compatible = "simple-bus";
              cpu@0 { ... };          // 直接挂载在SoC总线上的CPU
              i2c@44e0b000 {         // I2C控制器(总线)
                  compatible = "ti,omap4-i2c";
                  tps@24 {            // I2C设备(如电源管理芯片)
                      compatible = "ti,tps65217";
                  };
              };
          };
      };
      在此例中,soc节点(simple-bus)的子节点i2c@44e0b000会被转换为platform_device,而tps@24则由I2C总线驱动进一步处理。
  • 避免代码冗余
    传统内核代码中,总线控制器及其设备的描述需硬编码在驱动中。设备树通过属性标记,将这部分描述外移,减少内核代码冗余,提升可维护性。

3. 兼容旧硬件与驱动模型

  • 历史驱动支持
    "isa"属性用于兼容传统的ISA(Industry Standard Architecture)总线设备。虽然现代系统已较少使用ISA总线,但内核仍需支持旧硬件。
    • 示例:某些嵌入式系统可能通过桥接芯片模拟ISA总线,设备树通过isa属性标记此类节点,触发内核生成对应的platform_device以兼容旧驱动。
  • 驱动模型统一性
    即使总线类型不同(如PCI、I2C、SPI),通过simple-bus等属性,内核可将总线控制器统一抽象为platform_device,简化驱动模型。总线控制器驱动(如PCI主机控制器驱动)通过解析子节点的compatible属性,进一步初始化具体设备驱动。

规则的深层逻辑

  • 为什么需要遍历子节点?
    总线控制器的子节点代表实际挂载的设备。若不自动创建这些子设备的platform_device,则需手动为每个设备编写内核代码,违背设备树的设计初衷(硬件描述与驱动分离)。

  • 为什么排除I2C/SPI总线子节点?
    I2C、SPI等总线节点下的子节点(如传感器、存储器)通常由对应的总线驱动(如i2c_clientspi_device)管理。若将这些节点转换为platform_device,会导致设备模型混乱(同一设备被多个驱动管理)。

总结

该规则通过属性标记和层级遍历,实现了:

  1. 硬件总线的自动抽象:将总线控制器及其子设备动态注册为platform_device,模拟硬件探测过程。
  2. 复杂拓扑的模块化描述:以树状结构分层描述SoC内部总线及外设,减少内核代码冗余。
  3. 历史驱动兼容性:支持ISA等旧总线设备,统一驱动模型。

这一机制是Linux内核设备模型与设备树集成的重要体现,显著提升了硬件描述的灵活性和驱动开发的效率。

2."simple-bus"、"simple-mfd"、"isa"分别代表什么总线

在Linux设备树中,"simple-bus""simple-mfd""isa"是用于描述特定类型硬件节点的兼容性属性(compatible属性值)。它们的含义和用途如下:

1. simple-bus

  • 定义
    "simple-bus"表示该节点描述的是一个总线控制器(如PCI、AMBA、I2C等总线),其子节点代表挂载在该总线上的设备。

  • 用途

    • 总线抽象:将总线控制器及其挂载的设备抽象为设备树中的节点,便于内核统一管理。
    • 自动设备发现:内核在解析设备树时,若检测到"simple-bus"属性,会自动将其子节点(需包含compatible属性)转换为platform_device。这一过程模拟了硬件总线的自动探测机制,使得总线控制器驱动能动态发现并管理挂载的设备。
  • 应用场景

    • 描述SoC(系统级芯片)内部的系统总线(如ARM的AMBA总线)。
    • 例如,在设备树中定义一个simple-bus节点描述PCI总线控制器,其子节点可能对应具体的PCI设备(如网卡、显卡)。

2. simple-mfd

  • 定义
    "simple-mfd"(Multi-Function Device)表示该节点描述的是一个多合一功能设备,如电源管理芯片(PMIC)或传感器集线器。这些设备通常集成多个功能模块,每个模块可独立控制。

  • 用途

    • 模块化设备管理:将多合一设备拆分为多个逻辑设备,每个逻辑设备对应一个功能模块(如PMIC中的ADC、DAC、GPIO控制器)。
    • 驱动隔离:为每个功能模块创建独立的platform_device,便于驱动开发和调试。
  • 应用场景

    • 描述集成多个外设控制器的芯片,如某些型号的PMIC可能集成ADC、DAC、GPIO控制器等。
    • 例如,在设备树中定义一个simple-mfd节点描述PMIC,其子节点可能对应ADC、DAC等独立模块。

3. isa

  • 定义
    "isa"代表工业标准体系结构(Industry Standard Architecture)总线,是早期PC中广泛使用的16位总线标准。虽然现代系统已较少使用ISA总线,但内核仍需支持旧硬件。

  • 用途

    • 遗留硬件兼容:在设备树中标记兼容ISA总线的设备节点,以便内核生成对应的platform_device,兼容旧驱动。
    • 模拟接口支持:某些嵌入式系统可能通过桥接芯片模拟ISA总线接口,设备树通过"isa"属性标记此类节点。
  • 应用场景

    • 支持传统的ISA总线设备(如ISA接口的网卡、声卡)。
    • 例如,在设备树中定义一个isa节点描述ISA总线控制器,其子节点可能对应具体的ISA设备。

总结

属性描述对象核心用途典型应用场景
simple-bus总线控制器总线抽象与自动设备发现SoC内部总线(如AMBA)、PCI总线
simple-mfd多合一功能设备模块化设备管理与驱动隔离PMIC、传感器集线器
isaISA总线控制器/设备遗留硬件兼容与模拟接口支持传统ISA设备、嵌入式模拟ISA接口

这些属性通过设备树机制,将硬件描述与驱动管理解耦,显著提升了Linux内核对复杂硬件系统的支持能力和可维护性。

3.检查节点的 compatible 属性是否包含 "arm" 或 "primecell"。如果是,则不 将该节点转换为 platform_device,而是将其识别为 AMBA 设备。 这个规则的目的是什么呢 

3.为什么排除I2C/SPI总线子节点 

在Linux设备树的处理逻辑中,排除I2C/SPI总线子节点的核心目的是维护总线驱动模型的隔离性,确保不同总线类型的设备由对应的子系统统一管理。以下是这一规则的详细解释:

1. 总线驱动模型的隔离性

  • I2C/SPI总线的独立性
    I2C和SPI是独立的片上总线协议,各自拥有专用的驱动模型(如i2c_clientspi_device)。这些总线子系统负责:
    • 设备发现与绑定:通过扫描总线上的设备地址,自动发现并绑定驱动。
    • 资源管理:处理总线的时钟、中断、电源状态等底层细节。
    • 协议适配:封装总线特定的通信协议(如I2C的起始/停止条件、SPI的时钟极性)。
  • 与Platform设备的冲突
    若将I2C/SPI子节点强制转换为platform_device,会导致:
    • 驱动不兼容:通用平台驱动无法理解I2C/SPI设备的地址空间、通信协议等细节。
    • 资源冲突:同一设备可能被多个总线子系统重复注册(如同时作为platform_devicei2c_client)。

2. 设备树的结构化描述

  • 总线控制器的层级关系
    在设备树中,I2C/SPI控制器通常作为独立节点描述,其子节点代表挂载在总线上的设备。例如:

    i2c@44e0b000 {
        compatible = "ti,omap4-i2c";
        reg = <0x44e0b000 0x100>;
        interrupts = <72>;
        status = "okay";
    
        tps@24 {
            compatible = "ti,tps65217";
            reg = <0x24>;
        };
    };
    此处:
    • i2c@44e0b000是I2C控制器节点,会被转换为platform_device
    • tps@24是I2C设备节点,需由I2C子系统处理,而非作为platform_device
  • 排除规则的作用
    当内核遍历simple-bus等节点时,会跳过I2C/SPI控制器的子节点,确保:
    1. I2C控制器本身通过platform_device初始化。
    2. 挂载的I2C设备通过i2c_client管理,形成清晰的层级关系。

3. 驱动开发的最佳实践

  • 单一职责原则
    每个总线子系统(如I2C、SPI、PCI)应独立管理其设备,避免跨子系统操作。例如:
    • I2C设备的驱动应通过i2c_driver注册,而非platform_driver
    • SPI设备的驱动应通过spi_driver注册,而非直接操作硬件寄存器。
  • 代码复用与维护性
    通过总线子系统隔离,驱动代码可复用通用逻辑(如I2C消息传递、SPI传输队列),减少冗余。例如:

    // I2C设备驱动示例
    static const struct i2c_device_id tps65217_id[] = {
        { "ti,tps65217", 0 },
        { }
    };
    
    static struct i2c_driver tps65217_driver = {
        .driver = {
            .name = "tps65217-pmic",
        },
        .probe = tps65217_probe,
        .id_table = tps65217_id,
    };
    
    module_i2c_driver(tps65217_driver);  // 注册为I2C驱动

4. 历史兼容性与生态统一

  • ARM PrimeCell的扩展
    某些I2C/SPI控制器可能集成ARM PrimeCell外设(如PL022 SPI控制器)。这些设备通过"arm,primecell"标识,并由AMBA子系统管理,进一步强化了总线隔离的必要性。

  • 内核抽象层的完整性
    Linux内核通过bus_type机制(如i2c_bus_typespi_bus_type)维护总线驱动的独立性。排除I2C/SPI子节点确保:

    • 设备按总线类型自动分类(如i2c_client归入i2c_bus_type)。
    • 驱动通过标准接口(如i2c_driver)注册,而非依赖平台特定代码。

总结

排除I2C/SPI总线子节点的规则通过以下机制实现:

  1. 总线隔离:确保I2C/SPI设备由专用子系统管理,避免驱动冲突。
  2. 结构化描述:维护设备树中总线控制器的层级关系,清晰表达硬件拓扑。
  3. 生态兼容:统一支持跨SoC的I2C/SPI设备,简化驱动开发与维护。

这一规则是Linux内核对片上总线协议深度优化的体现,确保了多总线环境下设备的可靠管理与驱动的高效复用。

4.自动转换为platform_device

在Linux内核中,设备树(Device Tree)节点自动转换为platform_device的机制是硬件抽象与驱动模型统一的核心设计。以下是这一过程的详细解释:

1. platform_device的作用与适用场景

  • 定义
    platform_device表示直接连接到处理器系统总线(如AMBA、x86的PCI总线)或集成在SoC内部的外设。这些设备通常没有独立的总线控制器(如I2C、SPI),而是通过内存映射I/O(MMIO)或专用寄存器与CPU通信。

  • 典型设备

    • 集成在SoC中的GPIO控制器、定时器、看门狗。
    • 直接连接CPU总线的外部设备(如某些型号的以太网控制器)。

2. 自动转换的条件与过程

触发条件

内核在解析设备树时,若检测到以下条件,会触发节点到platform_device的转换:

  1. 父节点类型
    节点位于simple-bussimple-mfdisa等总线控制器节点下。这些父节点本身会被转换为platform_device,表示总线控制器。
  2. compatible属性
    子节点包含compatible属性,明确标识设备类型(如"acme,foo-device")。
  3. 排除规则
    节点不属于I2C、SPI等独立总线子系统(这些设备由i2c_clientspi_device管理)。
转换流程
  1. 设备树遍历
    内核从根节点开始递归遍历设备树,识别所有符合条件的节点。
  2. 资源提取
    从节点中提取硬件资源(如寄存器地址范围reg、中断号interrupts、时钟源clocks)。
  3. 设备创建
    调用of_platform_device_create_pdata()等函数,将节点信息封装为platform_device结构体。
  4. 驱动绑定
    通过compatible属性匹配对应的platform_driver,完成驱动与设备的绑定。

3. 示例:从设备树到platform_device

设备树描述

soc {
    compatible = "simple-bus";  // 总线控制器节点
    #address-cells = <1>;
    #size-cells = <1>;

    foo-device@1000 {
        compatible = "acme,foo-v1";  // 子节点,触发platform_device创建
        reg = <0x1000 0x100>;        // 寄存器地址范围
        interrupts = <1 34>;         // 中断号
    };
};
内核处理过程
  1. 解析父节点
    soc节点因compatible = "simple-bus"被转换为platform_device,表示总线控制器。
  2. 解析子节点
    foo-device@1000因包含compatible属性,被识别为需创建platform_device的设备。
  3. 资源填充
    提取reginterrupts属性,填充到platform_device.resource字段。
  4. 驱动匹配
    内核搜索所有platform_driver,找到compatible"acme,foo-v1"的驱动(如foo_driver),并调用其probe()函数。

4. 排除I2C/SPI子节点的原因

  • 总线隔离性
    I2C和SPI设备由独立的子系统(i2c_corespi_core)管理,这些子系统:
    • 自动扫描总线:通过i2c_new_device()spi_new_device()动态发现设备。
    • 协议适配:封装总线特定的通信逻辑(如I2C的起始/停止条件)。
    • 资源冲突避免:确保同一设备不会同时被platform_devicei2c_client注册。
  • 驱动模型一致性
    若将I2C/SPI设备强制转换为platform_device,会导致:
    • 驱动不兼容:通用平台驱动无法处理I2C/SPI的地址空间或通信协议。
    • 功能冗余:I2C/SPI子系统已提供设备发现、资源管理等功能,重复实现会浪费资源。

5. 特殊处理:AMBA设备与PrimeCell外设

  • AMBA总线
    若节点包含"arm""primecell"兼容性字符串,内核会将其识别为AMBA设备,而非platform_device。例如:

    amba_bus {
        compatible = "arm,amba-bus";
        #address-cells = <1>;
        #size-cells = <1>;
    
        pl011_uart@90000000 {
            compatible = "arm,pl011";  // PrimeCell UART
            reg = <0x90000000 0x1000>;
            interrupts = <1 34>;
        };
    };

    此处pl011_uart@90000000会被转换为amba_device,由AMBA子系统管理。

  • 驱动绑定
    AMBA设备通过amba_driver接口注册驱动(如amba_pl011_driver),而非platform_driver。这确保了:

    • 总线协议适配:AMBA子系统处理地址解码、中断路由等底层细节。
    • 生态兼容性:ARM PrimeCell外设的驱动可在不同厂商的SoC上复用。

6. 自动转换机制的优势

  • 硬件抽象
    将设备树中的硬件描述转换为内核统一的数据结构(platform_device),隐藏底层细节(如寄存器地址、中断号)。
  • 驱动复用
    驱动通过compatible属性匹配设备,无需关心具体硬件平台,实现“编写一次,处处运行”。
  • 动态配置
    设备树可在运行时修改(如通过固件更新),无需重新编译内核即可调整硬件配置。

总结

设备树节点自动转换为platform_device的机制通过以下步骤实现:

  1. 条件匹配:基于父节点类型、compatible属性和排除规则。
  2. 资源提取:从设备树中提取硬件配置。
  3. 设备创建:封装为platform_device结构体。
  4. 驱动绑定:通过compatible属性匹配驱动。

这一机制是Linux内核对复杂硬件系统高效管理的基石,确保了驱动开发的简洁性、跨平台兼容性和生态统一性。

5.为什么排除I2C/SPI总线子节点? I2C、SPI等总线节点下的子节点(如传感器、存储器)通常由对应的总线驱动(如i2c_client、spi_device)管理。若将这些节点转换为platform_device,会导致设备模型混乱(同一设备被多个驱动管理)

在Linux内核的设备树处理逻辑中,排除I2C/SPI总线子节点(如传感器、存储器)并阻止其自动转换为platform_device的核心目的是维护设备模型的完整性和驱动管理的隔离性。以下是这一规则的详细技术解释:

1. 总线驱动模型的专属职责

  • I2C/SPI子系统的设计目标
    I2C和SPI是独立的片上总线协议,各自拥有专用的驱动子系统(如i2c_corespi_core)。这些子系统负责:
    • 设备发现与枚举:通过扫描总线上的设备地址,自动发现并注册设备(如i2c_clientspi_device)。
    • 协议适配:封装总线特定的通信逻辑(如I2C的起始/停止条件、SPI的时钟极性和相位)。
    • 资源管理:分配中断号、配置时钟源,并处理总线仲裁(如I2C的多主设备竞争)。
  • 与Platform设备的职责冲突
    platform_device模型的设计目标是管理直接连接到系统总线(如AMBA、x86的PCI总线)或集成在SoC内部的外设。若将I2C/SPI设备强制转换为platform_device,会导致:
    • 功能冗余:I2C/SPI子系统已提供设备发现、资源管理等功能,重复实现会浪费资源。
    • 协议不兼容platform_driver无法理解I2C/SPI设备的地址空间或通信协议,导致驱动无法正确操作硬件。

2. 设备模型混乱的风险

  • 驱动冲突
    若一个I2C设备同时被注册为platform_devicei2c_client,内核可能尝试多次绑定驱动,导致:
    • 内存泄漏:重复分配设备结构体(如struct device)。
    • 功能异常:驱动可能因竞争条件(Race Condition)同时访问硬件寄存器,导致数据损坏或系统崩溃。
  • 资源重复分配
    I2C/SPI子系统会为设备分配中断号、DMA通道等资源。若platform_device也尝试分配相同资源,会导致:
    • 资源冲突:同一中断号被多个设备使用,引发不可预测的行为。
    • 内核崩溃:资源分配失败时,可能触发Oops或Panic。
  • 调试困难
    设备模型混乱会使得内核日志(如dmesg)中出现重复的设备注册/注销记录,增加调试难度。例如:

    [ 1234.567890] platform_device_register: duplicate device 'foo-sensor'
    [ 1234.567901] i2c_new_device: already registered as platform_device

3. 内核设计原则:隔离性与单一职责

  • 模块化设计
    Linux内核通过bus_type机制(如i2c_bus_typespi_bus_type)隔离不同总线类型的设备管理。这种设计:
    • 提高可维护性:每个总线子系统独立演化,修复漏洞或添加功能时无需修改其他代码。
    • 增强安全性:限制驱动的权限(如仅允许I2C驱动访问I2C控制器寄存器)。
  • 避免隐式依赖
    若I2C/SPI设备被强制转换为platform_device,驱动可能隐式依赖平台总线的特定行为(如地址映射方式),导致:
    • 跨平台兼容性问题:同一驱动在不同SoC上表现不一致。
    • 功能回归:内核升级后,平台总线行为变化可能破坏原有驱动逻辑。

4. 实际案例:I2C温度传感器的驱动管理

  • 正确配置
    设备树中定义I2C温度传感器节点:

    i2c@44e0b000 {
        compatible = "ti,omap4-i2c";
        reg = <0x44e0b000 0x100>;
        interrupts = <72>;
    
        tmp102@48 {
            compatible = "ti,tmp102";
            reg = <0x48>;
        };
    };
    内核处理流程:
    1. i2c@44e0b000节点被转换为platform_device,初始化I2C控制器。
    2. tmp102@48节点由I2C子系统处理,创建i2c_client并绑定tmp102_driver
    3. 驱动通过I2C协议读取温度数据,无需关心底层总线细节。
  • 错误配置
    若强制将tmp102@48转换为platform_device
    
    

    soc {
        compatible = "simple-bus";
    
        tmp102@48 {
            compatible = "ti,tmp102";
            reg = <0x48>;  // 错误!I2C地址无法直接映射为平台总线地址
        };
    };
    导致的问题:
    • platform_driver尝试通过内存映射I/O(MMIO)访问I2C地址0x48,但该地址在平台总线上无效。
    • 驱动读取到随机数据,导致温度值错误或系统崩溃。

5. 调试与验证方法

  • 内核日志分析
    使用dmesg命令检查设备注册日志,确认设备是否由正确的子系统管理:

    [ 1234.567890] i2c i2c-0: new_device: Instantiated device tmp102 at 0x48
    [ 1234.567901] tmp102 1-0048: device identified as ti,tmp102

    若出现platform_device_register日志,则表明设备被错误转换。

  • 符号检查
    使用/sys/bus/目录验证设备归属:

    ls /sys/bus/i2c/devices/ # 应包含tmp102@48
    ls /sys/bus/platform/devices/ # 不应包含tmp102@48

总结

排除I2C/SPI总线子节点的规则通过以下机制确保系统稳定性:

  1. 职责隔离:I2C/SPI设备由专用子系统管理,避免驱动冲突和资源重复分配。
  2. 协议适配:总线子系统封装通信细节,使驱动开发更简单。
  3. 设计原则:遵循模块化、单一职责原则,提高内核可维护性和安全性。

这一规则是Linux内核对复杂硬件系统高效管理的关键设计,确保了驱动开发的简洁性、跨平台兼容性和生态统一性。

6.PCI、I2C、SPI和simple-bus的关系 

PCI、I2C、SPI和simple-bus是计算机系统中不同层次和场景下使用的总线协议,它们在硬件连接、通信机制和应用场景上存在显著差异。以下是它们的关系解析:

1. 硬件层次与角色

PCI(Peripheral Component Interconnect)
  • 定位
    PCI是一种高速外部总线标准,主要用于连接计算机主板上的高速外设(如显卡、网卡、SATA控制器)。它通常作为系统总线,直接与CPU或芯片组(如北桥)相连。
  • 特点
    • 高速传输:支持高达数十GB/s的带宽(如PCIe 4.0)。
    • 热插拔:部分变种(如PCIe)支持热插拔。
    • 地址空间:使用内存映射I/O(MMIO)或端口映射I/O(PMIO)。
I2C(Inter-Integrated Circuit)
  • 定位
    I2C是一种低速串行总线,主要用于连接嵌入式系统中的低速外设(如传感器、EEPROM、实时时钟)。它通常作为片上总线或板级总线。
  • 特点
    • 双线接口:仅需SDA(数据线)和SCL(时钟线)。
    • 多主设备支持:允许多个主设备(如MCU、传感器)共存。
    • 地址分配:通过7位或10位地址唯一标识设备。
SPI(Serial Peripheral Interface)
  • 定位
    SPI是一种高速同步串行总线,常用于连接需要较高数据传输速率的外设(如闪存、触摸屏控制器、ADC/DAC)。它通常作为片上总线或短距离板级总线。
  • 特点
    • 四线接口:包括MOSI(主出从入)、MISO(主入从出)、SCK(时钟)、CS(片选)。
    • 全双工通信:支持同时读写操作。
    • 灵活拓扑:支持单主多从或菊花链拓扑。
simple-bus
  • 定位
    simple-bus是Linux设备树中的一个兼容性属性,用于描述总线控制器节点(如PCI、I2C、SPI控制器本身)。它表示该节点是一个总线控制器,其子节点代表挂载在该总线上的设备。
  • 特点
    • 抽象层:将总线控制器抽象为platform_device,便于内核统一管理。
    • 自动设备发现:内核通过解析子节点的compatible属性,自动发现并绑定驱动。

2. 层次结构关系


系统总线(如PCI)
  │
  ├─ CPU/内存控制器
  │
  ├─ PCI设备(如显卡、网卡)
  │
  └─ 桥接芯片(如PCH)
        │
        ├─ I2C控制器(simple-bus节点)
        │   ├─ I2C设备(如传感器、EEPROM)
        │
        └─ SPI控制器(simple-bus节点)
              ├─ SPI设备(如闪存、触摸屏控制器)

3. 通信机制对比

特性PCII2CSPI
传输速率高(GB/s级)低(100kbps~4Mbps)中(Mbps~数十Mbps)
拓扑结构点对点/多设备多主从单主多从/菊花链
地址空间内存映射/端口映射7/10位地址片选信号(CS)
典型应用显卡、网卡传感器、EEPROM闪存、触摸屏
设备树表示PCI控制器节点I2C控制器节点SPI控制器节点
子节点管理PCI子设备I2C设备(i2c_client)SPI设备(spi_device)

4. 设备树中的协同工作

  • PCI控制器节点

    
    

    pci@10000000 {
        compatible = "pci-host-ecam-generic";
        reg = <0x10000000 0x1000000>;
        bus-range = <0x0 0xff>;
        #address-cells = <3>;
        #size-cells = <2>;
    };

    此处pci@10000000节点描述PCI控制器,内核会将其转换为platform_device,并扫描PCI总线上的设备。

  • I2C控制器节点

    i2c@44e0b000 {
        compatible = "ti,omap4-i2c";
        reg = <0x44e0b000 0x100>;
        interrupts = <72>;
        status = "okay";
    };

    此处i2c@44e0b000节点描述I2C控制器,内核会将其转换为platform_device,并通过I2C子系统管理挂载的设备(如tmp102@48)。

  • SPI控制器节点

    spi@48030000 {
        compatible = "ti,omap4-spi";
        reg = <0x48030000 0x1000>;
        interrupts = <73>;
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";
    };

    此处spi@48030000节点描述SPI控制器,内核会将其转换为platform_device,并通过SPI子系统管理挂载的设备(如mcp3208@0)。

5. 实际应用场景

  • PCI
    • 连接高性能GPU(如NVIDIA RTX 4090)到CPU,实现游戏或AI计算。
    • 连接企业级SSD(如PCIe 4.0 NVMe盘)到服务器主板,提供高速存储。
  • I2C
    • 在智能手机中连接温度传感器(如TMP102)到应用处理器,实现实时温控。
    • 在工业控制器中连接EEPROM(如24C02)到MCU,存储配置参数。
  • SPI
    • 在嵌入式系统中连接NOR闪存(如S25FL256L)到处理器,存储启动代码。
    • 在汽车电子中连接触摸屏控制器(如STMPE811)到微控制器,实现触控输入。

总结

PCI、I2C、SPI和simple-bus的关系可概括为:

  1. 层次化连接:PCI作为系统总线连接高速设备,I2C/SPI作为片上总线连接低速外设,simple-bus在设备树中描述这些总线控制器。
  2. 协议互补:PCI提供高速传输,I2C/SPI满足低速/低成本需求,simple-bus实现总线控制器的抽象管理。
  3. 内核协同:内核通过simple-bus节点发现总线控制器,再通过PCI、I2C、SPI子系统管理挂载的设备,形成完整的硬件抽象层。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值