首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
js
emoji
list
install
typescript
python
cPlusPlus
filter
object
golang
rsa
cmd
web
search
usb
loops
数组
bash
integer
process
include
utf-8
solr
callback
random
java
dll
php7
cookie
plugins
join
substring
client
timestamp
dockerfile
function
io
select
hash
blob
audio
config
iostream
format
char
byte
window
shell
int
tags
javascript
python3
hashcode
perl
heap
tree
vba
sum
hashset
foreach
hashtable
scala
command
netty
php5
regex
web3
vbscript
schema
eval
stream
require
export
default
case
match
go
future
frameworks
当前位置:
开发笔记
>
编程语言
> 正文
LinuxI2C几个结构体间的关系以及对于一个I2C设备的移植,我们需要做些什么工作
作者:虔州小小编_590 | 来源:互联网 | 2023-10-16 17:40
在Linux内核源代码中的drivers目录下包含一个i2c目录,而在i2c目录下又包含如下文件和文件夹:•i2c-core.c这个文件实现了I2C核心的功能以及proc
在Linux内核源代码中的drivers目录下包含一个i2c目录,而在i2c目录下又包含如下文件和文件夹:
• i2c-core.c
这个文件实现了I2C核心的功能以及/proc/bus/i2c*接口。
• i2c-dev.c
实 现了I2C适配器设备文件的功能,每一个I2C适配器都被分配一个设备。通过适配器访问设备时的主设备号都为89,次设备号为0~255。应用程序通过 “i2c-%d” (i2c-0, i2c-1, ..., i2c-10, ...)文件名并使用文件操作接口open()、write()、read()、ioctl()和close()等来访问这个设备。
i2c-dev.c并没有针对特定的设备而设计,只是提供了通用的read()、write()和ioctl()等接口,应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器并控制I2C设备的工作方式。
• chips文件夹
这个目录中包含了一些特定的I2C设备驱动,如Dallas公司的DS1337实时钟芯片、EPSON公司的RTC8564实时钟芯片和I2C接口的EEPROM驱动等。
• busses文件夹
这个文件中包含了一些I2C总线的驱动,如S3C2410的I2C控制器驱动为i2c-s3c2410.c。
• algos文件夹
实现了一些I2C总线适配器的algorithm。
此外,内核中的i2c.h这个头文件对i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这4个数据结构进行了定义。理解这4个结构体的作用十分关键,代码清单15.1、15.2、15.3、15.4分别给出了它们的定义。
代码清单15.1 i2c_adapter结构体
1 struct i2c_adapter {
2 struct module *owner;/*所属模块*/
3 unsigned int id; /*algorithm的类型,定义于i2c-id.h,以I2C_ALGO_开始*/
4 unsigned int class;
5 struct i2c_algorithm *algo;/*总线通信方法结构体指针 */
6 void *algo_data; /* algorithm数据 */
7 int (*client_register)(struct i2c_client *); /*client注册时调用*/
8 int (*client_unregister)(struct i2c_client *); /*client注销时调用*/
9 struct semaphore bus_lock; /*控制并发访问的自旋锁*/
10 struct semaphore clist_lock;
11 int timeout;
12 int retries; /*重试次数*/
13 struct device dev; /* 适配器设备 */
14 struct class_device class_dev; /* 类设备 */
15 int nr;
16 struct list_head clients; /* client链表头*/
17 struct list_head list;
18 char name[I2C_NAME_SIZE]; /*适配器名称*/
19 struct completion dev_released; /*用于同步*/
20 struct completion class_dev_released;
21};
代码清单15.2 i2c_algorithm结构体
1 struct i2c_algorithm {
2 int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
3 int num); /*i2c传输函数指针*/
4 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, /*smbus传输函数指针*/
5 unsigned short flags, char read_write,
6 u8 command, int size, union i2c_smbus_data * data);
7 int (*slave_send)(struct i2c_adapter *,char*,int);/*当i2c适配器为slave时,发送函数*/
8 int (*slave_recv)(struct i2c_adapter *,char*,int); /*当i2c适配器为slave时,接收函数*/
9 int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long); /*类似ioctl*/
10 u32 (*functionality) (struct i2c_adapter *);/*返回适配器支持的功能*/
11 };
上述代码第4行对应为SMBus传输函数指针,SMBus大部分基于I2C总线规范,SMBus不需增加额外引脚。与I2C总线相比,SMBus增加了一些新的功能特性,在访问时序也有一定的差异。
代码清单15.3 i2c_driver结构体
1 struct i2c_driver {
2 int id;
3 unsigned int class;
4 int (*attach_adapter)(struct i2c_adapter *); /*依附i2c_adapter函数指针 */
5 int (*detach_adapter)(struct i2c_adapter *); /*脱离i2c_adapter函数指针*/
6 int (*detach_client)(struct i2c_client *); /*i2c client脱离函数指针*/
7 int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); /*类似ioctl*/
8 struct device_driver driver; /*设备驱动结构体*/
9 struct list_head list; /*链表头*/
10 };
代码清单15.4 i2c_client结构体
1 struct i2c_client {
2 unsigned int flags; /* 标志 */
3 unsigned short addr; /* 低7位为芯片地址 */
4 struct i2c_adapter *adapter; /*依附的i2c_adapter*/
5 struct i2c_driver *driver; /*依附的i2c_driver */
6 int usage_count; /* 访问计数 */
7 struct device dev; /* 设备结构体 */
8 struct list_head list; /* 链表头 */
9 char name[I2C_NAME_SIZE]; /* 设备名称 */
10 struct completion released; /* 用于同步 */
11 };
下面分析一下i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这4个数据结构的作用及其盘根错节的关系。
• i2c_adapter与i2c_algorithm
i2c_adapter 对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个I2C适配器需要i2c_algorithm中提供的通信函数来控制适配 器上产生特定的访问周期。缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含其使用的 i2c_algorithm的指针。
i2c_algorithm中的关键函数master_xfer()用于产生I2C访问周期需要的信号,以i2c_msg(即I2C消息)为单位。i2c_msg结构体也非常关键,代码清单15.5给出了它的定义。
代码清单15.5 i2c_msg结构体
1 struct i2c_msg {
2 __u16 addr; /* 设备地址*/
3 __u16 flags; /* 标志 */
4 __u16 len; /* 消息长度*/
5 __u8 *buf; /* 消息数据*/
6 };
• i2c_driver与i2c_client
i2c_driver对应一套驱动方法,是纯粹的用于辅助作用的数据结构,它不对应于任何的物理实体。i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述。i2c_client一般被包含在i2c字符设备的私有信息结构体中。
i2c_driver 与i2c_client发生关联的时刻在i2c_driver的attach_adapter()函数被运行时。attach_adapter()会探测 物理设备,当确定一个client存在时,把该client使用的i2c_client数据结构的adapter指针指向对应的i2c_adapter, driver指针指向该i2c_driver,并会调用i2c_adapter的client_register()函数。相反的过程发生在 i2c_driver 的detach_client()函数被调用的时候。
• i2c_adpater与i2c_client
i2c_adpater 与i2c_client的关系与I2C硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adpater。由于一个适配器上可以连 接多个I2C设备,所以一个i2c_adpater也可以被多个i2c_client依附,i2c_adpater中包括依附于它的i2c_client 的链表。
假设I2C总线适配器xxx上有两个使用相同驱动程序的yyy I2C设备,在打开该I2C总线的设备结点后相关数据结构之间的逻辑组织关系将如图15.2所示。
图
15.2 I
2
C
驱动各数据结构关系
图15.2 I2C驱动各数据结构关系
从上面的分析可知,虽然I2C硬件体系结构比较简单,但是I2C体系结构在Linux中的实现却相当复杂。当工程师拿到实际的电路板,面对复杂的 Linux I2C子系统,应该如何下手写驱动呢?究竟有哪些是需要亲自做的,哪些是内核已经提供的呢?理清这个问题非常有意义,可以使我们面对具体问题时迅速地抓住 重点。
一方面,适配器驱动可能是Linux内核本身还不包含的。另一方面,挂接在适配器上的具体设备驱动可能也是Linux不存在的。即便上述设备驱动都存在于Linux内核中,其基于的平台也可能与我们的电路板不一样。因此,工程师要实现的主要工作将包括:
• 提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。
• 提供I2C适配器的algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。
• 实现I2C设备驱动与i2c_driver接口,用具体设备yyy的yyy_attach_adapter()函数指针、 yyy_detach_client()函数指针和yyy_command()函数指针的赋值给i2c_driver的attach_adapter、 detach_adapter和detach_client指针。
• 实现I2C设备驱动的文件操作接口,即实现具体设备yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等。
上述工作中1、2属于I2C总线驱动,3、4属于I2C设备驱动,做完这些工作,系统会增加两个内核模块。本章第3~4节将详细分析这些工作的实施方法,给出设计模板,而5~6节将给出两个具体的实例。
linux
文件
io
ip
go
client
struct
int
并发
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
数组
计算机存储系统的层次结构及其优势
本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ...
[详细]
蜡笔小新 2023-12-13 17:32:41
utf-8
eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ...
[详细]
蜡笔小新 2023-12-14 00:31:35
include
使用多进程实现TCP服务端的优势和注意事项
本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ...
[详细]
蜡笔小新 2023-12-13 18:25:30
search
Python正则表达式学习记录及常用方法
本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ...
[详细]
蜡笔小新 2023-12-13 16:37:19
usb
利用Visual Basic开发SAP接口程序初探的方法与原理
本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ...
[详细]
蜡笔小新 2023-12-13 10:56:31
process
clone的fork与pthread_create创建线程有何不同
本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ...
[详细]
蜡笔小新 2023-12-12 20:00:06
java
FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路
本文介绍了FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路。当图表系列较多时,用户希望可以自己设置哪些系列显示,哪些系列不显示。通过调用FR.Chart.WebUtils.getChart("chartID").getChartWithIndex(chartIndex).setSeriesVisible()接口,可以获取需要显示的系列图表对象,并在表单中显示这些系列。本文以决策报表为例,详细介绍了实现方法,并给出了示例。 ...
[详细]
蜡笔小新 2023-12-12 15:32:43
utf-8
移动端常用单位——rem的使用方法和注意事项
本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ...
[详细]
蜡笔小新 2023-12-12 07:20:50
utf-8
如何在HTML中获取鼠标的当前位置
本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ...
[详细]
蜡笔小新 2023-12-11 13:04:00
utf-8
centos安装Mysql的方法及步骤详解
本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ...
[详细]
蜡笔小新 2023-12-11 07:30:47
list
SpringBoot uri统一权限管理的实现方法及步骤详解
本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ...
[详细]
蜡笔小新 2023-12-14 16:11:30
java
实现下拉列表,点击其他位置自动隐藏效果的三种方式比较
目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ...
[详细]
蜡笔小新 2023-12-14 15:03:14
list
如何找到并终止在8080端口上运行的进程?
本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ...
[详细]
蜡笔小新 2023-12-14 13:45:13
include
使用C语言命令行参数在Windows上启动程序并传递参数
本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ...
[详细]
蜡笔小新 2023-12-12 10:21:44
include
Oracle存储过程写法小例子及已命名的异常
本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ...
[详细]
蜡笔小新 2023-12-11 15:10:15
虔州小小编_590
这个家伙很懒,什么也没留下!
Tags | 热门标签
js
emoji
list
install
typescript
python
cPlusPlus
filter
object
golang
rsa
cmd
web
search
usb
loops
数组
bash
integer
process
include
utf-8
solr
callback
random
java
dll
php7
cookie
plugins
RankList | 热门文章
1
QQ浏览器怎么设置快速保存图片?
2
html5页面缓存,HTML5的manifest缓存
3
CMake test目录和项目同名错误
4
"Coding Interview Guide" -- 在数组中找到一个局部最小的位置
5
win10一键重置电脑的方法
6
如何查询自家的网络有没有被DNS劫持?dns劫持是什么
7
Vuex来自组件的setter调用后的getters值
8
英语专业计算机基础知识,计算机专业英语基础知识
9
ubuntu服务器安装nodejs的完整过程
10
勿以恶小而为之,勿以善小而不为
11
在java项目启动时就执行某操作
12
9大“最佳微软Surface电脑”推荐:颜值与性能兼顾,轻巧 简洁 安全
13
SSH协商过程简版
14
工业级POE交换机技术优势及供电方法详解!
15
gnu.trove.map.hash.TObjectDoubleHashMap.clear()方法的使用及代码示例
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有