I2C 驱动框架:i2c_driver 结构填 probe/remove/id_table,设备树里 compatible 匹配;probe 里用 i2c_smbus_read_byte_data 等函数读写寄存器;用户态通过 /dev/i2c-X 或 sysfs 访问,也可以封装成字符设备。
本文概述
I2C 是 Linux 最常用外设驱动,面试常考:i2c_driver、probe、设备树、读写函数。回答要给代码骨架。
核心要点
I2C 驱动用 i2c_driver 结构,和 platform_driver 类似
设备树里 compatible 匹配,probe 里初始化
读写用 i2c_master_send/recv 或 i2c_smbus_* 函数
用户态:/dev/i2c-X + ioctl,或封装成字符设备/sysfs
I2C 地址 7 位,注意读写位和地址左移

面试官考察点
驱动开发基础题。面试官看你是否写过 I2C 驱动。重点听:i2c_driver、probe、读写。
回答思路
给最小骨架,讲 probe 里做什么,读写函数。
参考回答
驱动骨架。
#include <linux/i2c.h>
#include <linux/module.h>
static int temp_probe(struct i2c_client *c, const struct i2c_device_id *id){
/* 读芯片 ID 验证 */
u8 id = i2c_smbus_read_byte_data(c, 0x0D);
/* 注册字符设备/sysfs */
return 0;
}
static int temp_remove(struct i2c_client *c){
/* 注销设备 */
return 0;
}
static const struct i2c_device_id temp_id[] = {
{ "temp_sensor", 0 }, {}
};
static const struct of_device_id temp_of_match[] = {
{ .compatible = "fanyi,temp-sensor" }, {}
};
static struct i2c_driver temp_driver = {
.probe = temp_probe,
.remove = temp_remove,
.id_table = temp_id,
.driver = { .name = "temp_sensor", .of_match_table = temp_of_match },
};
module_i2c_driver(temp_driver);
I2C 读写函数。
| 函数 | 作用 |
|---|---|
| i2c_master_send(client, buf, len) | 写 len 字节 |
| i2c_master_recv(client, buf, len) | 读 len 字节 |
| i2c_smbus_read_byte_data(client, reg) | 读寄存器 1 字节 |
| i2c_smbus_write_byte_data(client, reg, val) | 写寄存器 1 字节 |
| i2c_smbus_read_word_data(client, reg) | 读寄存器 2 字节 |
设备树。
&i2c1 {
temp@48 {
compatible = "fanyi,temp-sensor";
reg = <0x48>;
};
};
用户态访问。
/dev/i2c-X:用 ioctl(I2C_RDWR) 直接读写,适合调试;
sysfs:驱动里创建属性文件,cat/echo 访问;
字符设备:封装成 /dev/temp0,read 直接读温度;
IIO 子系统:传感器推荐用 IIO 框架。
注意。
I2C 地址是 7 位,Linux 驱动里直接写 7 位(内核自动处理读写位);
多设备共享总线,驱动要能区分(不同地址或 id_table);
probe 里先读芯片 ID,确认设备存在且型号对;
I2C 读写可能睡眠,不能在中断上下文调用。

扫码关注




























