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以兼容旧驱动。
- 示例:某些嵌入式系统可能通过桥接芯片模拟ISA总线,设备树通过
- 驱动模型统一性:
即使总线类型不同(如PCI、I2C、SPI),通过simple-bus等属性,内核可将总线控制器统一抽象为platform_device,简化驱动模型。总线控制器驱动(如PCI主机控制器驱动)通过解析子节点的compatible属性,进一步初始化具体设备驱动。
规则的深层逻辑
-
为什么需要遍历子节点?
总线控制器的子节点代表实际挂载的设备。若不自动创建这些子设备的platform_device,则需手动为每个设备编写内核代码,违背设备树的设计初衷(硬件描述与驱动分离)。 -
为什么排除I2C/SPI总线子节点?
I2C、SPI等总线节点下的子节点(如传感器、存储器)通常由对应的总线驱动(如i2c_client、spi_device)管理。若将这些节点转换为platform_device,会导致设备模型混乱(同一设备被多个驱动管理)。
总结
该规则通过属性标记和层级遍历,实现了:
- 硬件总线的自动抽象:将总线控制器及其子设备动态注册为
platform_device,模拟硬件探测过程。 - 复杂拓扑的模块化描述:以树状结构分层描述SoC内部总线及外设,减少内核代码冗余。
- 历史驱动兼容性:支持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总线控制器,其子节点可能对应具体的ISA设备。
总结
| 属性 | 描述对象 | 核心用途 | 典型应用场景 |
|---|---|---|---|
| simple-bus | 总线控制器 | 总线抽象与自动设备发现 | SoC内部总线(如AMBA)、PCI总线 |
| simple-mfd | 多合一功能设备 | 模块化设备管理与驱动隔离 | PMIC、传感器集线器 |
| isa | ISA总线控制器/设备 | 遗留硬件兼容与模拟接口支持 | 传统ISA设备、嵌入式模拟ISA接口 |
这些属性通过设备树机制,将硬件描述与驱动管理解耦,显著提升了Linux内核对复杂硬件系统的支持能力和可维护性。
3.检查节点的 compatible 属性是否包含 "arm" 或 "primecell"。如果是,则不 将该节点转换为 platform_device,而是将其识别为 AMBA 设备。 这个规则的目的是什么呢
3.为什么排除I2C/SPI总线子节点
在Linux设备树的处理逻辑中,排除I2C/SPI总线子节点的核心目的是维护总线驱动模型的隔离性,确保不同总线类型的设备由对应的子系统统一管理。以下是这一规则的详细解释:
1. 总线驱动模型的隔离性
- I2C/SPI总线的独立性:
I2C和SPI是独立的片上总线协议,各自拥有专用的驱动模型(如i2c_client、spi_device)。这些总线子系统负责:- 设备发现与绑定:通过扫描总线上的设备地址,自动发现并绑定驱动。
- 资源管理:处理总线的时钟、中断、电源状态等底层细节。
- 协议适配:封装总线特定的通信协议(如I2C的起始/停止条件、SPI的时钟极性)。
- 与Platform设备的冲突:
若将I2C/SPI子节点强制转换为platform_device,会导致:- 驱动不兼容:通用平台驱动无法理解I2C/SPI设备的地址空间、通信协议等细节。
- 资源冲突:同一设备可能被多个总线子系统重复注册(如同时作为
platform_device和i2c_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控制器的子节点,确保:- I2C控制器本身通过
platform_device初始化。 - 挂载的I2C设备通过
i2c_client管理,形成清晰的层级关系。
- I2C控制器本身通过
3. 驱动开发的最佳实践
- 单一职责原则:
每个总线子系统(如I2C、SPI、PCI)应独立管理其设备,避免跨子系统操作。例如:- I2C设备的驱动应通过
i2c_driver注册,而非platform_driver。 - SPI设备的驱动应通过
spi_driver注册,而非直接操作硬件寄存器。
- I2C设备的驱动应通过
- 代码复用与维护性:
通过总线子系统隔离,驱动代码可复用通用逻辑(如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_type、spi_bus_type)维护总线驱动的独立性。排除I2C/SPI子节点确保:- 设备按总线类型自动分类(如
i2c_client归入i2c_bus_type)。 - 驱动通过标准接口(如
i2c_driver)注册,而非依赖平台特定代码。
- 设备按总线类型自动分类(如
总结
排除I2C/SPI总线子节点的规则通过以下机制实现:
- 总线隔离:确保I2C/SPI设备由专用子系统管理,避免驱动冲突。
- 结构化描述:维护设备树中总线控制器的层级关系,清晰表达硬件拓扑。
- 生态兼容:统一支持跨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的转换:
- 父节点类型:
节点位于simple-bus、simple-mfd或isa等总线控制器节点下。这些父节点本身会被转换为platform_device,表示总线控制器。 - compatible属性:
子节点包含compatible属性,明确标识设备类型(如"acme,foo-device")。 - 排除规则:
节点不属于I2C、SPI等独立总线子系统(这些设备由i2c_client、spi_device管理)。
转换流程
- 设备树遍历:
内核从根节点开始递归遍历设备树,识别所有符合条件的节点。 - 资源提取:
从节点中提取硬件资源(如寄存器地址范围reg、中断号interrupts、时钟源clocks)。 - 设备创建:
调用of_platform_device_create_pdata()等函数,将节点信息封装为platform_device结构体。 - 驱动绑定:
通过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>; // 中断号
};
};
内核处理过程
- 解析父节点:
soc节点因compatible = "simple-bus"被转换为platform_device,表示总线控制器。 - 解析子节点:
foo-device@1000因包含compatible属性,被识别为需创建platform_device的设备。 - 资源填充:
提取reg和interrupts属性,填充到platform_device.resource字段。 - 驱动匹配:
内核搜索所有platform_driver,找到compatible为"acme,foo-v1"的驱动(如foo_driver),并调用其probe()函数。
4. 排除I2C/SPI子节点的原因
- 总线隔离性:
I2C和SPI设备由独立的子系统(i2c_core、spi_core)管理,这些子系统:- 自动扫描总线:通过
i2c_new_device()、spi_new_device()动态发现设备。 - 协议适配:封装总线特定的通信逻辑(如I2C的起始/停止条件)。
- 资源冲突避免:确保同一设备不会同时被
platform_device和i2c_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的机制通过以下步骤实现:
- 条件匹配:基于父节点类型、
compatible属性和排除规则。 - 资源提取:从设备树中提取硬件配置。
- 设备创建:封装为
platform_device结构体。 - 驱动绑定:通过
compatible属性匹配驱动。
这一机制是Linux内核对复杂硬件系统高效管理的基石,确保了驱动开发的简洁性、跨平台兼容性和生态统一性。
5.为什么排除I2C/SPI总线子节点? I2C、SPI等总线节点下的子节点(如传感器、存储器)通常由对应的总线驱动(如i2c_client、spi_device)管理。若将这些节点转换为platform_device,会导致设备模型混乱(同一设备被多个驱动管理)。
在Linux内核的设备树处理逻辑中,排除I2C/SPI总线子节点(如传感器、存储器)并阻止其自动转换为platform_device的核心目的是维护设备模型的完整性和驱动管理的隔离性。以下是这一规则的详细技术解释:
1. 总线驱动模型的专属职责
- I2C/SPI子系统的设计目标:
I2C和SPI是独立的片上总线协议,各自拥有专用的驱动子系统(如i2c_core、spi_core)。这些子系统负责:- 设备发现与枚举:通过扫描总线上的设备地址,自动发现并注册设备(如
i2c_client、spi_device)。 - 协议适配:封装总线特定的通信逻辑(如I2C的起始/停止条件、SPI的时钟极性和相位)。
- 资源管理:分配中断号、配置时钟源,并处理总线仲裁(如I2C的多主设备竞争)。
- 设备发现与枚举:通过扫描总线上的设备地址,自动发现并注册设备(如
- 与Platform设备的职责冲突:
platform_device模型的设计目标是管理直接连接到系统总线(如AMBA、x86的PCI总线)或集成在SoC内部的外设。若将I2C/SPI设备强制转换为platform_device,会导致:- 功能冗余:I2C/SPI子系统已提供设备发现、资源管理等功能,重复实现会浪费资源。
- 协议不兼容:
platform_driver无法理解I2C/SPI设备的地址空间或通信协议,导致驱动无法正确操作硬件。
2. 设备模型混乱的风险
- 驱动冲突:
若一个I2C设备同时被注册为platform_device和i2c_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_type、spi_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>; }; };i2c@44e0b000节点被转换为platform_device,初始化I2C控制器。tmp102@48节点由I2C子系统处理,创建i2c_client并绑定tmp102_driver。- 驱动通过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总线子节点的规则通过以下机制确保系统稳定性:
- 职责隔离:I2C/SPI设备由专用子系统管理,避免驱动冲突和资源重复分配。
- 协议适配:总线子系统封装通信细节,使驱动开发更简单。
- 设计原则:遵循模块化、单一职责原则,提高内核可维护性和安全性。
这一规则是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. 通信机制对比
| 特性 | PCI | I2C | SPI |
|---|---|---|---|
| 传输速率 | 高(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的关系可概括为:
- 层次化连接:PCI作为系统总线连接高速设备,I2C/SPI作为片上总线连接低速外设,
simple-bus在设备树中描述这些总线控制器。 - 协议互补:PCI提供高速传输,I2C/SPI满足低速/低成本需求,
simple-bus实现总线控制器的抽象管理。 - 内核协同:内核通过
simple-bus节点发现总线控制器,再通过PCI、I2C、SPI子系统管理挂载的设备,形成完整的硬件抽象层。
188

被折叠的 条评论
为什么被折叠?



