1. 版本背景
- 发布时间:2011年7月21日
- 总线支持状态:基础总线框架稳定,I2C/SPI核心支持,PCI枚举完成
- 关键里程碑 :
- I2C子系统完全重构
- SPI核心框架稳定化
- PCI枚举机制标准化
- 设备树总线绑定初步支持
- 本地总线(Local Bus)基础框架
2. 子系统架构
核心架构
bash
+---------------------+
| 用户空间 |
| 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核心实现
bash
// 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枚举机制
bash
// 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设备树示例
bash
&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传输流程
bash
SPI Master → Transfer Setup → CS Assert → Clock/Data → CS Deassert → Complete
- 关键约束 :
- 时钟极性/相位配置
- 片选信号管理
- 全双工通信特性
6. 错误处理机制
I2C错误码
bash
// 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调试命令
bash
# 扫描I2C总线设备
i2cdetect -l
i2cdetect -y 1
# 读取设备寄存器
i2cget -y 1 0x50 0x00
# 写入设备寄存器
i2cset -y 1 0x50 0x00 0xAA
-
输出示例 :
bash0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- 48 -- -- -- 50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
9. 版本差异对比
| 特性 | Linux 2.6.39 | Linux 3.0 |
|---|---|---|
| I2C框架 | 基础实现 | 完全重构 |
| SPI核心 | 实验性 | 稳定化 |
| PCI枚举 | 简单扫描 | 递归处理 |
| 设备树 | 无 | ARM平台初步 |
10. 故障排查场景
1. 设备无法识别
-
现象 :
i2cdetect无响应 -
原因 :
- 线路连接错误
- 设备地址配置错误
- 上拉电阻缺失
-
解决方案 :
bash# 检查物理连接 i2cdetect -y 1 # 验证设备地址 dmesg | grep i2c
2. 通信超时
-
现象 :
read系统调用阻塞 -
原因 :
- 时钟频率不匹配
- 从设备未响应
-
解决方案 :
bash# 调整I2C时钟 echo 100000 > /sys/class/i2c-adapter/i2c-1/bus_speed
11. 参考资料
- 内核源码:
drivers/i2c/,drivers/spi/,drivers/pci/ - I2C规范:I2C Bus
- SPI规范:Serial Peripheral Interface (SPI) --- The Linux Kernel documentation
- PCI规范:Specifications | PCI-SIG