1. 版本背景
- 发布时间:2011年7月21日
- 总线支持状态:基础总线框架稳定,I2C/SPI核心支持,PCI枚举完成
- 关键里程碑:
- I2C子系统完全重构
- SPI核心框架稳定化
- PCI枚举机制标准化
- 设备树总线绑定初步支持
- 本地总线(Local Bus)基础框架
2. 子系统架构
核心架构
+---------------------+
| 用户空间 |
| sysfs接口 |
| busctl工具集 |
+----------+----------+
|
+----------v----------+
| 内核空间 |
| 总线核心子系统 |
| + I2C/SPI框架 |
| + PCI枚举 |
+----------+----------+
|
+----------v----------+
| 设备驱动层 |
| (platform-specific)|
+----------+----------+
|
+----------v----------+
| 总线物理层 |
+---------------------+
架构特点
- 总线核心:
drivers/base/bus.c 统一管理
- I2C框架:
drivers/i2c/ 下的完整实现
- SPI框架:
drivers/spi/ 标准化接口
- PCI支持:
drivers/pci/ 枚举与配置
3. 源码深度解析
I2C核心实现
// drivers/i2c/i2c-core.c
int i2c_add_adapter(struct i2c_adapter *adap)
{
/* 注册I2C适配器 */
adap->nr = i2c_register_adapter_nr();
/* 创建sysfs节点 */
adap->dev.parent = &i2c_bus_type;
adap->dev.release = i2c_adapter_dev_release;
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
return device_register(&adap->dev);
}
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver = to_i2c_driver(drv);
/* 匹配设备与驱动 */
if (client && driver->id_table)
return i2c_match_id(driver->id_table, client) != NULL;
return 0;
}
- 关键函数:
i2c_add_adapter():注册I2C适配器
i2c_device_match():设备-驱动匹配
i2c_transfer():核心传输函数
PCI枚举机制
// drivers/pci/probe.c
static void pci_scan_child_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
int max = bus->busn_res.end;
/* 扫描总线上的设备 */
for (devfn = 0; devfn < 0x100; devfn++) {
dev = pci_scan_single_device(bus, devfn);
if (dev) {
pci_device_add(dev, bus);
if (dev->subordinate)
pci_scan_child_bus(dev->subordinate);
}
}
}
4. 设备树配置详解
I2C设备树示例
&i2c1 {
status = "okay";
eeprom@50 {
compatible = "atmel,24c32";
reg = <0x50>;
pagesize = <32>;
};
sensor@48 {
compatible = "ti,tmp102";
reg = <0x48>;
};
};
- 关键属性:
reg:设备I2C地址
compatible:驱动匹配标识
pagesize:EEPROM分页大小
5. 总线协议实现
I2C协议栈
| 层级 |
组件 |
功能 |
| 用户空间 |
i2c-tools |
i2cdetect/i2cget等工具 |
| 内核接口 |
i2c-dev |
/dev/i2c-*设备节点 |
| 核心层 |
i2c-core |
适配器/设备管理 |
| 控制器 |
i2c- |
硬件特定实现 |
SPI传输流程
SPI Master → Transfer Setup → CS Assert → Clock/Data → CS Deassert → Complete
6. 错误处理机制
I2C错误码
// include/uapi/linux/i2c.h
#define EREMOTEIO 121 /* Remote I/O error */
#define ECOMM 122 /* Communication error */
#define ENOTDIR 123 /* Not a directory */
- 典型错误:
-EREMOTEIO:从设备无响应
-ECOMM:通信协议错误
-ENXIO:设备地址不存在
7. 性能特性
总线性能指标
| 总线类型 |
最大速率 |
传输单位 |
典型延迟 |
| I2C |
400kHz |
字节 |
100μs |
| SPI |
50MHz |
字 |
10μs |
| PCI |
133MHz |
事务 |
1μs |
8. 调试工具详解
I2C调试命令
# 扫描I2C总线设备
i2cdetect -l
i2cdetect -y 1
# 读取设备寄存器
i2cget -y 1 0x50 0x00
# 写入设备寄存器
i2cset -y 1 0x50 0x00 0xAA
9. 版本差异对比
| 特性 |
Linux 2.6.39 |
Linux 3.0 |
| I2C框架 |
基础实现 |
完全重构 |
| SPI核心 |
实验性 |
稳定化 |
| PCI枚举 |
简单扫描 |
递归处理 |
| 设备树 |
无 |
ARM平台初步 |
10. 故障排查场景
1. 设备无法识别
2. 通信超时
11. 参考资料