I2C内核数据结构之间的关系Word文档格式.docx
- 文档编号:14780246
- 上传时间:2022-10-24
- 格式:DOCX
- 页数:74
- 大小:233.81KB
I2C内核数据结构之间的关系Word文档格式.docx
《I2C内核数据结构之间的关系Word文档格式.docx》由会员分享,可在线阅读,更多相关《I2C内核数据结构之间的关系Word文档格式.docx(74页珍藏版)》请在冰豆网上搜索。
i2c_adap_pxa_init函数15
i2c_add_adapter函数16
i2c_del_adapter函数18
i2c_adap_pxa_exit函数20
第4章安装、卸载ltc3445驱动程序21
ltc3445_init函数21
i2c_add_driver函数22
i2c_probe函数23
i2c_check_functionality函数26
i2c_smbus_xfer函数27
i2c_transfer函数29
ltc3445_detect_client函数30
i2c_attach_client函数31
ltc3445_cleanup函数32
i2c_del_driver函数33
ltc3445_detach_client函数35
i2c_detach_client函数35
第5章与pxa255的i2c适配器相关的代码37
i2c_pxa_reset函数37
i2c_pxa_abort函数38
i2c_pxa_xfer函数38
i2c_pxa_do_xfer函数39
i2c_pxa_start_message函数41
i2c_pxa_handler函数42
i2c_pxa_irq_txempty函数42
i2c_pxa_irq_rxfull函数47
第6章i2c-dev的初始化49
i2c_dev_init函数49
i2cdev_attach_adapter函数50
第7章i2c框架提供的设备访问方法52
i2cdev_open函数52
i2cdev_ioctl函数53
i2cdev_read函数54
i2c_master_recv函数55
对i2cdev_read和i2c_master_recv的修改56
i2cdev_release函数59
第8章编写i2c设备驱动程序模块的方法61
第9章用户进程访问i2c设备的步骤64
讨论和总结65
i2c操作中的同步问题65
总结各个模块初始化函数的作用65
对i2c框架代码的修改66
有关i2c设备私有数据结构的讨论68
遗留的问题68
(注意:
本文档中的源代码以i2c-2.9.1包及www.arm.linux.org.uk上下载的pxa的i2c适配器的补丁2360-2为准!
)
第1章i2c核心数据结构之间的关系
i2c总线适配器(adapter)就是一条i2c总线的控制器,在物理连接上若干i2c设备并联于该i2c总线的SCL和SDA线上,如下图所示:
那么相应软件数据结构的设计、数据结构之间的关系就至少应该描述硬件物理连接的这种组织关系。
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:
structi2c_driver{
charname[32];
intid;
unsignedintflags;
int(*attach_adapter)(structi2c_adapter*);
int(*detach_client)(structi2c_client*);
int(*command)(structi2c_client*client,unsignedintcmd,void*arg);
void(*inc_use)(structi2c_client*client);
void(*dec_use)(structi2c_client*client);
};
其中name为最大长度为32字节的字符串,id可选0xf000到0xffff中的任一数值,flags域可以直接设置为I2C_DF_NOTIFY。
attach_adapter回调函数在安装i2c设备驱动程序模块时、或者在安装i2c适配器驱动程序模块时被调用,用于检测、认领设备并为设备分配i2c_client数据结构。
detach_client方法在卸载适配器或设备驱动程序模块时被调用,用于从总线上注销设备、并释放i2c_client及相应的私有数据结构。
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
通过最顶层的i2c_use/release_client函数来同时改变i2c设备和i2c适配器驱动程序模块的引用计数。
另外,不能在attach_adapter函数检测到一个i2c设备时就增加驱动程序模块的引用计数,而应该在用户进程访问一个/dev/i2c/%d设备节点时增加模块的引用计数,则关闭设备节点时减少引用计数(但在当前的应用中,适配器和设备的驱动程序都是静态地链接入内核映像的,所以在pxa255的i2c补丁中并没有使用控制引用计数的函数)。
2.一个i2c设备由i2c_client数据结构进行描述:
structi2c_client{
/*div.,seebelow*/
unsignedintaddr;
/*chipaddress-NOTE:
7bitaddressesarestoredinthe*/
/*_LOWER_7bitsofthischar*/
structi2c_adapter*adapter;
/*theadapterwesiton*/
structi2c_driver*driver;
/*andouraccessroutines*/
void*data;
/*fortheclients*/
intusage_count;
/*Howmanyaccessescurrentlytotheclient*/
在安装适配器或者设备的驱动程序时通过设备驱动程序i2c_driver中的attach_adapter函数检测设备地址。
如果检测成功则调用设备驱动程序提供的回调函数创建描述设备的i2c_client数据结构,并将其中的driver指针指向设备驱动程序的i2c_driver数据结构。
这样将来就可以使用i2c_driver中的注销设备和控制引用计数的方法了。
由下文可见在描述i2c适配器的i2c_adapter数据结构中设计了指向该总线上所有i2c设备的i2c_client数据结构的指针数组clients,而每个i2c_client又通过adapter指针回指i2c_adapter。
数据结构之间类似的组织关系在Linux内核中屡见不鲜,比如父子进程的PCB之间、父目录及子目录和子文件的dentry之间,等等。
每个i2c设备都有唯一的7位地址addr。
由于设备可能支持多个地址,所以在设备驱动程序模块中要指出需要检测的地址范围(由i2c_client_address_data二维数组指定),而设备实际使用的地址在检测成功并为之分配i2c_client数据结构时填入。
以i2c设备ltc3445为例,硬件支持的地址为1001011或者0101011,即7位地址的高2位由具体的布线方法决定(可以分别接到VCC或者GND)。
如果ltc3445驱动程序的开发者知道具体的布线方法,那么在驱动程序中就可以直接指定。
否则可以指定地址检测范围为这两个地址,而在加载驱动程序模块时由软件进行地址检测。
需要说明的是,i2c设备的7位地址是就当前i2c总线而言的,是“相对地址”。
不同的i2c总线上的设备可以使用相同的7位地址,但是它们所在的i2c总线不同。
所以在系统中一个i2c设备的“绝对地址”由二元组(i2c适配器的ID和设备在该总线上的7位地址)表示。
i2c_client数据结构为描述i2c设备的“模板”,而具体的i2c设备可能需要描述个性的私有数据。
私有数据结构由i2c_client数据结构中的data域指向。
设备驱动程序开发者可以设计合适的私有数据结构来描述硬件的特性。
值得一提的是,目前在Linux内核中常用的表示与具体设备、对象等相关的私有数据结构的方法有两种,一种就是采用void类型的指针data来指向具体的私有数据结构,又比如file结构中的private_data域在设备驱动程序中往往被设置为指向具体的设备数据结构;
第二种方法就是采用union域,比如VFS的super_block、inode数据结构。
super_block和inode数据结构本身集中描述了各种文件系统的共性,而具体文件系统的个性则放到union中进行描述,在挂载具体的文件系统时实例化为具体的union对象,比如ext2_inode_union或者jffs2_inode_info。
有关设计私有数据的的讨论可参见本文末尾的讨论部分。
当不同进程访问同一i2c总线时,对i2c总线的互斥访问由i2c_adapter的lock信号量实现,系统调用执行流只有在获得该信号量期间才能调用master_xfer,并且在阻塞期间不释放信号量(类似在读写正规文件期间必须持有inode.i_sem,参见本文末尾的讨论部分)。
而usage_count域为设备的使用引用计数,在i2c_use_client和i2c_release_client函数中控制usage_count域的值(但是当前pxa255的i2c补丁中并没有使用这两个函数,usage_count的值自初始化后就一直为0)。
3.一个i2c适配器由i2c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- I2C 内核 数据结构 之间 关系
![提示](https://static.bdocx.com/images/bang_tan.gif)