由NXP发明的I2C总线是双线制,由串行数据(SDA)、串行时钟(SCL)构成的异步串行总线。SCL有主设备生成,以便在总线上同步数据的传输。I2C用在嵌入式系统中,经常用于连接串行的EEPROM、RTC时钟、GPIO扩张器、温度传感器等。时钟频率常在10K~100K、400K~2M HZ不等。
一、I2C客户端驱动程序架构
I2C控制器驱动程序在设备和总线之间提供抽象层。实现了I2C总线框架,I2C客户端驱动有struct i2c_driver{}表示,而I2C客户端设备有struct i2c_client{}表示。
下面是i2c_driver{}的主要成员
struct i2c_driver {
//标准驱动程序模型接口
int (*probe)(struct i2_client *, const struct i2c_device_id);
int (*remove)(struct i2c_client *);
// 与枚举无关的驱动类型接口
void (*shutdown)(struct i2c_client *);
struct device_driver driver;
const struct i2c_device_id *id_table;
};
1. 驱动probe函数和remove流程
在probe函数中主要实现如下几个主要功能:
- 检查设备是否是所期望的设备;使用i2c_check_functionality()检查I2C总线控制器是否支持设备所需要的功能;
- 初始化设备,使用函数i2c_set_client_data()设置特定的数据;
- 注册合适的内核框架;
// probe函数的原型:
static int foo_probe(struct i2c_client *client, struct i2c_device_id *id);
// 其中struct i2c_client{}代表I2C设备本身,其主要成员如下:
struct i2c_client {
unsigned short flags;
unsigned short addr; // chip address, 7bit,地址被存储在低7位
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter;
struct device dev;
int irq; // 有设备发出的irq
struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
i2c_slave_cb_t slave_cb;
#endif
};
// 其中struc

本文介绍了I2C总线的特性,包括其双线制结构和常用时钟频率。详细讨论了I2C客户端驱动程序的架构,如probe和remove函数,以及如何通过id_table配置设备。此外,还概述了如何通过内核API与I2C设备交互,以及在设备树中声明和注册I2C设备的方法。
528

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



