Linux下I2C设备驱动的一种适配器层直接实现方法
- 格式:pdf
- 大小:208.42 KB
- 文档页数:3
1、I2C概述I2C是philips公司提供的外设总线,I2C有两条数据线,一条是串行数据线SDA、一条是时钟线SCL,使用SDA和SCL实现了数据的交换,便于布线。
I2C总线方便用在EEPROM、实时钟、小型LCD等与CPU外部的接口上。
2、Linux下的驱动思路Linux系统下编写I2c驱动主要有两种方法:一种是把I2C当做普通字符设备来使用;另一种利用Linux下驱动的体系结构来实现。
第一种方法:优点:思路比较直接,不用花费大量时间去了解Linux系统下I2C体系结构缺点:不仅对I2C设备操作要了解,还有了解I2C的适配器操作不仅对I2C设备器和设备操作需要了解,编写的驱动移植性差,内核提供的I2C设备器都没有用上。
第二种方法:第一种的优点就是第二种的缺点,第一种的缺点就是第二种的优点。
3、I2C框架概述Linux的I2C体系结构分为3部分:1)I2C核心I2C核心提供了I2C总线驱动和设备驱动的注册和注销的方法,I2C 通信方法(algorithm)上层,与具体适配器无关的代码,检测设备上层的代码等。
2)I2C总线驱动I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可以直接受CPU来控制。
3)I2C设备驱动I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备端挂在受CPU控制的适配器上,通过I2C适配器与CPU交换数据。
Linux下的I2C体系结构:1)Linux下的I2C体系结构4、I2C设备驱动编写方法首先让我们明白适配器驱动的作用是让我们能够通过它发出标准的I2C时序,在linux内核源代码中driver/I2C/buss包含一些适配器的驱动,例如s3c2410的驱动I2C-s3c2410.c,适配器被加载到内核中,接下的任务就是实现设备驱动的编写。
编写设备驱动的方法主要分为两种方法:第一种:利用设备提供的I2C-dev.c来实现I2C适配器设备文件,然后通过上层应用程序来操作I2C设备器来控制I2C设备。
嵌入式Linux中I2C设备驱动程序的研究与实现
朱南皓;李正祥
【期刊名称】《微计算机信息》
【年(卷),期】2010(026)011
【摘要】FC作为一种目前通用的总线技术,已广泛应用于EEPROM、实时钟、小型LCD等设备与CPU的接口中.分析了嵌入式Linux中I2C驱动程序的体系结构,I2C驱动程序中一些重要数据结构之间的关系以及I2C驱动程序的运行机制.最后,结合具体的EEPROM芯片AT24C08说明了在嵌入式Linux下开发I2C设备驱动程序的一般流程.另外还创新了一般的驱动方法,实现了单设备多驱动的驱动模式.【总页数】3页(P67-69)
【作者】朱南皓;李正祥
【作者单位】100024,北京,中国传媒大学广播电视数字化教育部工程研究中心;100024,北京,中国传媒大学广播电视数字化教育部工程研究中心
【正文语种】中文
【中图分类】TP316
【相关文献】
1.小型医疗仪器中嵌入式Linux设备驱动程序的开发 [J], 甄诚;董秀珍;付峰;刘晓东
2.设备驱动程序在嵌入式Linux系统中的实现分析 [J], 王莹
3.嵌入式Linux的I2C设备驱动程序的分析 [J], 余炽业;宋跃;雷瑞庭
4.嵌入式Linux系统中字符设备驱动程序的开发 [J], 李胜朝;黄先祥;谢建
5.设备驱动程序在嵌入式Linux系统中的实现分析 [J], 王莹
因版权原因,仅展示原文概要,查看原文内容请购买。
I2C调试笔记最近被VK3344搞的昏头转向,今天代理商打电话居然说这款芯⽚不兼容硬件IIC总线控制器,真是崩溃!就当花时间买个教训吧!总结⼀下免得以后不长进⼜犯这种低级错误。
1。
先分析⽰波器抓到的iic时序图,该时序图是vk3344在 smart arm lpc3250 & linux 下由主机发出的往VK3344写数据的时序图。
图中1处标出的尖峰⾼电平值很奇怪只有每次写寄存器地址的时候在最后从机应答之后释放总线到⾼电平的信号都是这么⼀个尖峰,应该跟⽰波器采集数据的频率没关系吧?尖峰过后应该是通信结束了,但是却出现了2标出的⼀个低电平周期信号,后来仔细阅读IIC协议⽂档才想起来,IIC的结束信号⼀定是要在IIC的SCAL保持稳定⾼电平的时候SDA由低到⾼的的⼀个上升沿跳变。
之所以如2那样拉低是因为当时的时钟信号为低,这时候如果SDA就⼀直保持⾼电平的话那么就成了在SCAL为低的时候SDA⼀直保持⾼电平了,这样也就不算是结束信号了,所以⼀定要有2中的在SCAL为低的时候SDA拉低⼀个周期然后再跳变才⾏。
这⾥的时钟脉冲是⾼电平的时候SDA信号保持电平稳定才算是⼀个有效数据,也就是说⼀个SDA的电平信号⼀定要在整个时钟为⾼电平的⼀个周期内保持不变才算有效数据。
2。
这⾥说说IIC设备驱动的⼤致情况。
这个没多少要说的,因为是作为串⼝扩展的,所以就注册成了字符驱动,IIC的设备检测直接调⽤IIC的核⼼代码就⾏了,这个是IIC设备驱动和总线适配器之间的⼀个连接纽带,就不多说了,看代码就明⽩了。
还有⼀点差点忘了,就是IIC设备的中断的响应和处理,最好的办法是在驱动⾥⾯注册中断的时候的中断回调函数(服务函数)⾥⾯完成所有的读写,读写的内容分别⾃⼰在内核空间⾥⾯开辟⼀块内存来保持,在驱动函数的⽤户层接⼝那⾥最好留连个读写缓存状态标志,当然留个读写回调函数接⼝更好,这样就直接通过回调函数把数据从内核空间内存拷贝到⽤户⾃⼰的内存⾥⾯就⾏了,然后在线程⾥⾯遍历缓存也⾏,或者消息触发也⾏,随便怎么做都可以,看⾃⼰的喜好了。
linux系统i2c协议详解I2C总线概述I2C(两线接口)是一种串行通信协议,用于连接嵌入式系统中的集成电路(IC)。
它以其低成本、低功耗和高可靠性著称。
I2C总线需要两条双向信号线:串行数据线(SDA)和串行时钟线(SCL)。
这些信号线由一个主设备控制,可以与多个从设备通信。
I2C通信I2C通信由以下步骤组成:起始条件:主设备将SDA线下拉至低电平,同时保持SCL线为高电平。
设备地址:主设备发送7位或10位从设备地址,后跟一个读/写位。
数据传输:主设备和从设备交换数据。
停止条件:主设备将SDA线拉至高电平,同时保持SCL线为高电平。
主设备和从设备I2C总线上的设备分为两种:主设备和从设备。
主设备:发起通信并控制总线。
通常是主微控制器或处理器。
从设备:响应主设备请求并提供或接收数据。
可以是传感器、执行器或其他外围设备。
I2C寻址从设备通过唯一的7位或10位地址进行寻址。
地址的最高位表示是否可读/写,0表示写,1表示读。
I2C模式I2C协议支持以下模式:主写从读:主设备向从设备写入数据,然后从从设备读取数据。
主读从写:主设备从从设备读取数据,然后向从设备写入数据。
从读从写:两个从设备在主设备的监督下进行通信。
I2C传输速率I2C传输速率通常在10kbps到400kbps之间。
速率由主设备设置。
I2C错误检测I2C协议包含几个错误检测机制,例如校验和和超时。
这些机制有助于确保数据的可靠传输。
I2C应用I2C总线用于各种应用,包括:传感器和执行器接口EEPROM和闪存编程LED和LCD控制模拟-数字转换器(ADC)和数字-模拟转换器(DAC)接口电源管理时钟同步I2C优点I2C协议的优点包括:低成本:无需额外的硬件接口低功耗:仅使用两根信号线高可靠性:错误检测机制确保数据完整性容易使用:简单的协议易于实施广泛采用:支持广泛的设备和库I2C缺点I2C协议的缺点包括:数据速率低:与其他串行接口相比,数据速率较低主机限制:总线上只能有一个主设备总线无仲裁:在总线冲突的情况下,没有内置的仲裁机制有限的寻址范围:仅支持有限数量的设备地址I2C技术演进I2C协议正在不断发展,以满足新应用的需求。
TI-I2C驱动一、与I2C驱动相关的文件分成两部分:1)应用层接口部分:程序在svn中的路径如下:在https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/user/i2c目录下,i2ctest.c文件,提供了lm75a_temp_read()方法,用来读取LM75A设备温度寄存器中的温度信息的功能。
2)内核驱动部分:内核位于svn中的路径如下:https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/kernel(1)总线驱动:i2c-davinci.c:在内核目录中driver/i2c/busses目录下,适用于TI的I2C总线驱动程序。
I2C总线驱动是对I2C硬件体系结构中适配器端的实现。
(2)I2C驱动代码核心:i2c-core.c:在内核目录中driver/i2c/目录下,是I2C代码的核心,用于沟通虚拟文件系统与底层实现。
该文件提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。
(3)I2C设备驱动:lm75.c:在内核目录中driver/hwmon目录下,是针对LM75A以及其他能兼容的温度传感器的设备驱动。
I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。
二、I2C简要工作流程1)在总线驱动初始化时候,当通过Linux内核源代码/driver/base/platform.c文件中定义platform_driver_register()函数注册platform_driver结构体时,其中probe指针指向的davinci_i2c_probe()函数将被调用,以初始化适配器硬件。
2)而davinci_i2c_remove()函数则完成与davinci_i2c_probe()相反的功能。
I2C设备驱动介绍I2C(Inter-Integrated Circuit)是一种串行通信协议,用于连接并使多个外部设备与主控制器进行通信。
在嵌入式系统中,I2C设备驱动起着至关重要的作用,负责将操作系统与I2C总线上的设备进行通信,促进数据的传输和交互。
1.初始化:驱动程序需要初始化I2C控制器,包括设置时钟频率、地址范围等。
2.设备注册:设备驱动需要在操作系统中注册I2C设备,以便操作系统能够识别和管理设备。
3.读写操作:驱动程序需要实现读写设备寄存器的功能,包括发送开始和停止信号、以及发送、接收数据等。
4.错误处理:驱动程序需要处理I2C通信过程中可能出现的错误,例如传输失败、设备无响应等情况。
5.中断处理:驱动程序需要支持I2C设备的中断机制,以便及时处理设备的状态变化或数据传输完成的中断信号。
6.电源管理:驱动程序需要支持设备的电源管理功能,包括设备的唤醒、睡眠等操作。
7.设备控制:驱动程序需要实现设备特定的控制功能,例如设置传感器的采样率、配置设备的工作模式等。
8. 虚拟文件系统接口:在Linux系统中,驱动程序通常通过虚拟文件系统接口(如/dev)与用户空间进行交互,提供读写设备寄存器的功能。
1.确定设备:首先,开发者应该确定需要驱动的I2C设备。
这可能包括传感器、EEPROM、显示器等。
2.确定硬件连接:确定I2C设备与主控制器之间的硬件连接和电气特性。
这包括设备的I2C地址、I2C总线上的物理接口等。
3.编写驱动程序:在操作系统中,开发者可以根据设备的文档或芯片厂商提供的驱动程序框架,编写自己的I2C设备驱动程序。
驱动程序需要实现上述提到的功能,并且根据设备的特点进行相应的适配和优化。
4.编译和测试:完成驱动程序的编写后,需要将其编译成与操作系统内核匹配的模块或静态链接库。
然后,通过加载驱动模块或重新编译内核来使驱动程序生效。
最后,进行测试,确保驱动程序在各种场景下的正常运行。
实例解析linux内核I2C体系结构(1)一、概述谈到在linux系统下编写I2C驱动,目前主要有两种方式,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux I2C驱动体系结构来完成。
下面比较下这两种驱动。
第一种方法的好处(对应第二种方法的劣势)有:●思路比较直接,不需要花时间去了解linux内核中复杂的I2C子系统的操作方法。
第一种方法问题(对应第二种方法的好处)有:●要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器操作;●要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写出的程序可移植性差;●对内核的资源无法直接使用。
因为内核提供的所有I2C设备器及设备驱动都是基于I2C子系统的格式。
I2C适配器的操作简单还好,如果遇到复杂的I2C适配器(如:基于PCI的I2C适配器),工作量就会大很多。
本文针对的对象是熟悉I2C协议,并且想使用linux内核子系统的开发人员。
网络和一些书籍上有介绍I2C子系统的源码结构。
但发现很多开发人员看了这些文章后,还是不清楚自己究竟该做些什么。
究其原因还是没弄清楚I2C子系统为我们做了些什么,以及我们怎样利用I2C子系统。
本文首先要解决是如何利用现有内核支持的I2C适配器,完成对I2C设备的操作,然后再过度到适配器代码的编写。
本文主要从解决问题的角度去写,不会涉及特别详细的代码跟踪。
二、I2C设备驱动程序编写首先要明确适配器驱动的作用是让我们能够通过它发出符合I2C标准协议的时序。
在Linux内核源代码中的drivers/i2c/busses目录下包含着一些适配器的驱动。
如S3C2410的驱动i2c-s3c2410.c。
当适配器加载到内核后,接下来的工作就要针对具体的设备编写设备驱动了。
编写I2C设备驱动也有两种方法。
一种是利用系统给我们提供的i2c-dev.c来实现一个i2c 适配器的设备文件。
然后通过在应用层操作i2c适配器来控制i2c设备。
i2c_register_driver函数详解在嵌入式软件开发中,I2C(Inter-Integrated Circuit)总线是一种常用的串行通信接口,用于在微控制器和外部设备之间传输数据。
i2c_register_driver函数是Linux内核中一个重要的函数,用于注册I2C 驱动程序。
本文将详细解析i2c_register_driver函数的功能、参数和应用。
一、i2c_register_driver函数概述i2c_register_driver函数是在Linux内核中注册一个I2C驱动程序的函数。
它的作用是将驱动程序与对应的I2C适配器绑定,使得操作系统能够正确地识别和管理该驱动程序。
在驱动程序注册后,当相应的I2C设备连接到系统时,驱动程序将会自动加载并为该设备提供服务。
二、i2c_register_driver函数参数i2c_register_driver函数包含一个结构体参数,该结构体用于指定驱动程序的相关信息和功能。
1. struct i2c_driverstruct i2c_driver是一个定义I2C驱动程序的结构体,包含了以下重要的成员:- .driver:指向内核的struct device_driver结构体,用于描述驱动程序的信息,如名称、文件操作方法等。
- .probe:指向I2C设备探测函数的指针,用于在设备连接时进行初始化和配置。
- .remove:指向I2C设备移除函数的指针,用于在设备断开连接时进行清理和释放资源。
- .id_table:指向I2C设备ID表的指针,用于匹配设备和驱动程序。
2. I2C设备探测函数(probe函数)I2C设备探测函数是I2C驱动程序的核心功能之一,在I2C设备连接到系统时被调用。
该函数的作用是检测和初始化I2C设备,并将设备与驱动程序进行绑定。
在probe函数中,可以执行一系列必要的操作,如配置寄存器、分配内存、注册字符设备等。
Linux I2C设备驱动编写(一)在Linux驱动中I2C系统中主要包含以下几个成员:如果一个I2C适配器不支持I2C通道,那么就将master_xfer成员设为NULL。
如果适配器支持SMBUS 协议,那么需要去实现smbus_xfer,如果smbus_xfer指针被设为NULL,那么当使用SMBUS协议的时候将会通过I2C通道进行仿真。
master_xfer指向的函数的返回值应该是已经成功处理的消息数,或者返回负数表示出错了。
functionality指针很简单,告诉询问着这个I2C主控器都支持什么功能。
在内核的drivers/i2c/i2c-stub.c中实现了一个i2c adapter的例子,其中实现的是更为复杂的SMBUS。
SMBus 与I2C的区别通常情况下,I2C和SMBus是兼容的,但是还是有些微妙的区别的。
时钟速度对比:在电气特性上他们也有所不同,SMBus要求的电压范围更低。
I2C driver具体的I2C设备驱动,如相机、传感器、触摸屏、背光控制器常见硬件设备大多都有或都是通过I2C 协议与主机进行数据传输、控制。
结构体如下:如同普通设备的驱动能够驱动多个设备一样,一个I2C driver也可以对应多个I2C client。
以重力传感器AXLL34X为例,其实现的I2C驱动为:这里要说明一下module_i2c_driver宏定义(i2c.h):module_driver():理解上述宏定义后,将module_i2c_driver(adxl34x_driver)展开就可以得到:这一句宏就解决了模块module安装卸载的复杂代码。
这样驱动开发者在实现I2C驱动时只要将i2c_driver结构体填充进来就可以了,无需关心设备的注册与反注册过程。
I2C client即I2C设备。
I2C设备的注册一般在板级代码中,在解析实例前还是先熟悉几个定义:下面还是以adxl34x为例:这样ADXL34X的i2c设备就被注册到了系统中,当名字与i2c_driver中的id_table中的成员匹配时就能够出发probe匹配函数了。