打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
linux下S3C2440–I2C驱动学习之一“I2C核心数据结构” | 技术文章 | 狂...

最近学习I2C驱动,来操作AT24C08芯片进行读写,现在研究一下内核自带I2C驱动的代码,首先简单了解一下I2C核心数据结构的相互关系。由此来展开,也许能够对驱动代码有更好地理解。软件数据结构的设计、数据结构之间的关系就至少应该描述硬件物理连接的这种组织关系。

Linux的i2c 框架中各个部分的关系如下图所示:

 

内核中 i2c 相关代码可以分为三个层次:
1. i2c 框架:i2c.h 和i2c-core.c 为i2c 框架的主体,提供了核心数据结构的定义、i2c 适配器驱动和设备驱动的注册、注销管理,i2c 通信方法上层的、与具体适配器无关的代码、检测设备地址的上层代码等;i2c-dev.c 用于创建i2c 适配器的/dev/i2c/%d 设备节点,提供i2c 设备访问方法等。
2. i2c 总线适配器驱动:定义描述具体i2c 总线适配器的i2c_adapter 数据结构、实现在具体i2c 适配器上的i2c 总线通信方法,并由i2c_algorithm 数据结构进行描述。
3. i2c 设备驱动:定义描述具体设备的i2c_client 和可能的私有数据结构、借助i2c 框架的i2c_probe 函数实现注册设备的attach_adapter 方法、提供设备可能使用的地址范围、以及设备地址检测成功后创建i2c_client 数据结构的回调函数。

I2C主要数据结构如下:

1. 一个 i2c 设备的驱动程序由i2c_driver 数据结构描述,定义于include/linux/i2c.h:

struct i2c_driver {
char name[32];          //最大32字节的字符串
int id;                       //id 可选0xf000 到0xffff 中的任一数值
unsigned int flags;     //一般直接设置为I2C_DF_NOTIFY
int (*attach_adapter)(struct i2c_adapter *);
int (*detach_client)(struct i2c_client *);
int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
void (*inc_use)(struct i2c_client *client);
void (*dec_use)(struct i2c_client *client);
};

现在讲解一下这个结构体

(1).attach_adapter 回调函数在安装i2c 设备驱动程序模块时、或者在安装i2c 适配器驱动
程序模块时被调用,用于检测、认领设备并为设备分配i2c_client 数据结构.

(2).detach_client 方法在卸载适配器或设备驱动程序模块时被调用,用于从总线上注销设备、并释放i2c_client 及相应的私有数据结构。

(3).inc_use 和dec_use 所指向的函数用于改变i2c 设备驱动程序模块的引用计数。注意不要直接调用i2c_driver数据结构中的这两个方法,而要通过如下函数调用路径:
i2c_use_client > i2c_inc_use_client > inc_use
i2c_release_client > i2c_dec_use_client > dec_use

2. 一个 i2c 设备由i2c_client 数据结构进行描述:

struct i2c_client {
char name[32];
int id;
unsigned int flags; /* div., see below */
unsigned int addr; /* chip address - NOTE: 7bit addresses are stored in the */
/* _LOWER_ 7 bits of this char */
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
void *data; /* for the clients */
int usage_count; /* How many accesses currently to the client */
};

现在讲解一下这个结构体:

在安装适配器或者设备的驱动程序时通过设备驱动程序 i2c_driver 中的attach_adapter 函数检测设备地址。如果检测成功则调用设备驱动程序提供的回调函数创建描述设备的i2c_client 数据结构,并将其中的driver指针指向设备驱动程序的i2c_driver 数据结构。这样将来就可以使用i2c_driver 中的注销设备和控制引用计数的方法了。

3. 一个 i2c 适配器由i2c_adapter 数据结构描述:

struct i2c_adapter {
char name[32];
unsigned int id; /* == is algo->id | hwdep.struct->id, for registered values see below */
struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data;
void (*inc_use)(struct i2c_adapter *);
void (*dec_use)(struct i2c_adapter *);
int (*client_register)(struct i2c_client *);
int (*client_unregister)(struct i2c_client *);
void *data; /* private data for the adapter */
struct semaphore lock;
unsigned int flags; /* flags specifying div. data */
struct i2c_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
#ifdef CONFIG_PROC_FS
/* No need to set this when you initialize the adapter */
int inode;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)
struct proc_dir_entry *proc_entry;
#endif
#endif /* def CONFIG_PROC_FS */
};

现在讲解一下这个结构体:

在 i2c_adapter 数据结构中设计了clients 指针数组,指向该总线上每个设备的i2c_client 数据结构。由于一条i2c 总线上最多只有I2C_CLENT_MAX 个设备,所以可以使用静态数组(题外话,如果相关数据结构的个数是未知的,链表显然是更好的选择)。lock 信号量用于实现对i2c 总线的互斥访问:在访问i2c 总线上的任一设备期间当前进程必须首先获得该信号量,并且在阻塞等待i2c 操作完成期间不释放。

4.具体 i2c 适配器的通信方法由i2c_algorithm 数据结构进行描述:

struct i2c_algorithm {
char name[32]; /* textual description */
unsigned int id;
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data);
int (*slave_send)(struct i2c_adapter *,char*,int);
int (*slave_recv)(struct i2c_adapter *,char*,int);
int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);
u32 (*functionality) (struct i2c_adapter *);
};

现在讲解一下这个结构体:

(1).master_xfer/smbus_xfer 指针指向i2c 适配器驱动程序模块实现的i2c 通信协议或者smbus 通信协议。由下文分析可见在用户进程通过i2c-dev 提供的/dev/i2c/%d 设备节点访问i2c 设备时,最终是通过调用master_xfer 或者smbus_xfer 指向的方法完成的。

(2).slave_send/recv 函数用于实现当i2c 适配器扮演slave 角色时的传输方法。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux I2C驱动(1)
Linux设备驱动子系统第一弹 - I2C
Linux I2C驱动分析与实现(一)
i2c struct i2c
linux内核I2C体系结构(注意结构体原型)
I2C驱动架构
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服