Linux的操作系统I2C驱动架构解说
Linux的操作系统I2C驱动架构解说
发布时间:2006.10.16 04:52 来源:赛迪网技术社区 作者:LoneStar
最近因为工作需要涉及到了I2C总线。虽然我过去用过I2c,但看了 Linux kernel 后才发现,一个 layer 能被做到这样完善。
1.Linux的I2C驱动架
Linux中I2C总线的驱动分为两个部分,总线驱动(BUS)和设备驱动(DEVICE)。其中总线驱动的职责,是为系统中每个I2C总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动调用其函数。
设备驱动则是与挂在I2C总线上的具体的设备通讯的驱动。通过I2C总线驱动提供的函数,设备驱动可以忽略不同总线控制器的差异,不考虑其实现细节地与硬件设备通讯。
1.1. 总线驱动
在系统开机时,首先装载的是I2C总线驱动。一个总线驱动用于支持一条特定的I2C总线的读写。一个总线驱动通常需要两个模块,一个struct i2c_adapter和一个struct i2c_algorithm来描述:
static struct i2c_adapter pb1550_board_adapter =
{
name: "pb1550 adapter",
id: I2C_HW_AU1550_PSC,
algo: NULL,
algo_data: &pb1550_i2c_info,
inc_use: pb1550_inc_use,
dec_use: pb1550_dec_use,
client_register: pb1550_reg,
client_unregister: pb1550_unreg,
client_count: 0,
};
这个样例挂接了一个叫做“pb1550 adapter”的驱动。但这个模块并未提供读写函数,具体的读写方法由第二个模块,struct i2c_algorithm提供。
static struct i2c_algorithm au1550_algo =
{
.name = "Au1550 algorithm",
.id = I2C_ALGO_AU1550,
.master_xfer = au1550_xfer,
.functionality = au1550_func,
};
i2c_adap->algo = &au1550_algo;
这个样例给上述总线驱动增加了读写“算法”。通常情况下每个I2C总线驱动都定义一个自己的读写算法,但鉴于有些总线使用相同的算法,因而可以共用同一套读写函数。本例中的驱动定义了自己的读写算法模块,起名叫“Au1550 algorithm”。
全部填妥后,通过调用:
i2c_add_adapter(i2c_adap);
将这两个模块注册到操作系统里,总线驱动就算装上了。对于AMD au1550,这部分已经由AMD提供了
1.2 设备驱动
如前所述,总线驱动只是提供了对一条总线的读写机制,本身并不会去做通信。通信是由I2C设备驱动来做的,设备驱动透过I2C总线同具体的设备进行通讯。一个设备驱动有两个模块来描述,struct i2c_driver和struct i2c_client。
当系统开机、I2C总线驱动装入完成后,就可以装入设备驱动了。首先装入如下结构:
static struct i2c_driver driver =
{
.name = "i2c TV tuner driver",
.id = I2C_DRIVERID_TUNER,
.flags = I2C_DF_NOTIFY,
.attach_adapter = tuner_probe,
.detach_client = tuner_detach,
.command = tuner_command,
};
i2c_add_driver(&driver);
这个i2c_driver一旦装入完成,其中的attach_adapter函数就会被调用。在其中可以遍历系统中的每个i2c总线驱动,探测想要访问的设备:
static int tuner_probe(struct i2c_adapter *adap)
{
return i2c_probe(adap, &addr_data, tuner_attach);
}
注意探测可能会找到多个设备,因而不仅一个I2C总线可以挂多个不同类型的设备,一个设备驱动也可以同时为挂在多个不同I2C总线上的设备服务。
每当设备驱动探测到了一个它能支持的设备,它就创建一个struct i2c_client来标识这个设备:
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &driver;
/* Tell the I2C layer a new client has arrived */
err = i2c_attach_client(new_client);
if (err)
goto error;
可见,一个i2c_client代表着位于adapter总线上,地址为address,使用driver来驱动的一个设备。它将总线驱动与设备驱动,以及设备地址绑定在了一起。一个i2c_client就代表着一个I2C设备。
当得到I2C设备后,就可以直接对此设备进行读写:
/* * The master routines are the ones normally used to transmit data to devices * on a bus (or read from them). Apart from two basic transfer functions to * transmit one message at a time, a more complex version can be used to * transmit an arbitrary number of messages without interruption. */ extern int i2c_master_send(struct i2c_client *,const char* ,int); extern int i2c_master_recv(struct i2c_client *,char* ,int);
与通常意义上的读写函数一样,这两个函数对i2c_client指针指定的设备,读写int个char。返回值为读写的字节数。对于我们现有的SLIC的驱动,只要将最后要往总线上进行读写的数据引出传输到这两个函数中,移植工作就算完成了,我们将得到一个Linux版的I2C设备驱动。
Linux的操作系统I2C驱动架构解说的更多相关文章
- linux i2c驱动架构-dm368 i2c驱动分析
linux i2c驱动架构-dm368 i2c驱动分析 在阅读本文最好先熟悉一种i2c设备的驱动程序,并且浏览一下i2c-core.c以及芯片提供商的提供的i2c总线驱动(i2c-davinc ...
- 【驱动】linux下I2C驱动架构全面分析
I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...
- linux驱动学习(八) i2c驱动架构(史上最全) davinc dm368 i2c驱动分析【转】
转自:http://blog.csdn.net/ghostyu/article/details/8094049 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 预备知识 lin ...
- linux下I2C驱动架构全面分析【转】
本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...
- Linux内核调用I2C驱动_驱动嵌套驱动方法
禁止转载!!!! Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于 ...
- Linux和Windows设备驱动架构比较
毕业后一直在学操作系统, 有时候觉得什么都懂了,有时候又觉得好像什么都不懂,但总体来说自认为对操作系统实现机制的了解比周围的人还是要多一些.去年曾花了几个星期的晚上时间断断续续翻译了这篇对Linux和 ...
- linux下的声卡驱动架构
1.linux下的声卡驱动架构主要分为OSS架构和ALSA架构. 2.OSS架构 OSS全称是Open Sound System,叫做开放式音频系统,这种早期的音频系统这种基于文件系统的访问方式,这意 ...
- linux内核中i2c驱动中slave模式接口的调用
1. 关注unreg_slave接口 1.1 这个接口在哪里被调用呢? 在drivers/i2c/i2c-core-slave.c中 int i2c_slave_unregister(struct i ...
- 嵌入式开发之zynq---Zynq PS侧I2C驱动架构
http://blog.chinaunix.net/uid-24148050-id-120532.html http://bbs.csdn.net/topics/390538368?page=1 ht ...
随机推荐
- C++ 判断
C++ 判断判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的). #include <iostream> /* ru ...
- 用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的(1)
用C结构体来实现面向对象编程,ti xDAIS标准算法就这么搞的. 测试代码如下: #include <stdio.h> #include <stdlib.h> #includ ...
- 谷歌修复了 FFmpeg 中上千个 bug
谷歌在科技业界中几乎每天都会创造出新闻素材,它的触手涉及到了生活中的多个领域.最近谷歌将其Google +社交网络与邮件服务Gmail相结合.然而今天谷歌宣布他们修复了FFmpeg的上千个bug. ...
- (转)如何根据RGB值来判断这是种什么颜色?
如何根据RGB值来判断这是种什么颜色? 下面介绍几种典型颜色的RGB值,格式为:颜色(R,G,B). 想象一下有红.绿.蓝三盏射灯打出三束光. 这三束光叠加在一起时产生白色,如果三盏灯的亮度都减半就产 ...
- list模块
一. concat(Things) -> string() Types: Things = [Thing] Thing = atom() | integer() | float( ...
- 【Java面试题】6 判断下面代码是否有问题
1. if(username.equals(“zxx”){} 2. int x = 1; return x==1?true:false; 1.一个变量直接调用equals方法会给程序带来安全隐患,直接 ...
- Spring-处理自动装配的歧义性
自动装配可以对依赖注入提供很大帮助,因为它会减少装配应用程序组件时所需的显式装配的数量. 不过,仅有一个bean匹配所需的结果时,自动装配才是有效的.如果不仅有一个bean能够匹配的话,这种歧义性会阻 ...
- SharePoint Server 2013 通过IP无法访问站点
通过IP访问SharePoint站点,出现“The Web application at http://172.21.19.132:1000 could not be found.... ”如下错误: ...
- SQL Server死锁的解除方法
如果想要查出SQL Server死锁的原因,下面就教您SQL Server死锁监控的语句写法,如果您对此方面感兴趣的话,不妨一看. 下面的SQL语句运行之后,便可以查找出SQLServer死锁和阻塞的 ...
- 巧妙的利用Mongodb做地理空间查询