Linux下I2C驱动架构全面分析概要
Linux下I2C驱动介绍
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设备。
详细讲解RT-Thread I2C设备驱动框架及相关函数
详细讲解RT-Thread I2C设备驱动框架及相关函数本应用笔记以驱动I2C接口的6轴传感器MPU6050为例,说明了如何使用I2C设备驱动接口开发应用程序,并详细讲解了RT-Thread I2C设备驱动框架及相关函数。
1 本文的目的和结构1.1 本文的目的和背景I2C(或写作i2c、IIC、iic)总线是由Philips公司开发的一种简单、双向二线制(时钟SCL、数据SDA)同步串行总线。
它只需要两根线即可在连接于总线上的器件之间传送信息,是半导体芯片使用最为广泛的通信接口之一。
RT-Thread中引入了I2C设备驱动框架,I2C 设备驱动框架提供了基于GPIO模拟和硬件控制器的2种底层硬件接口。
1.2 本文的结构本文首先描述了RT-Thread I2C设备驱动框架的基本情况,然后详细描述了I2C设备驱动接口,并使用I2C设备驱动接口编写MPU6050的驱动程序,并给出了在正点原子STM32F4探索者开发板上验证的代码示例。
2 I2C设备驱动框架简介在使用MCU进行项目开发的时候,往往需要用到I2C总线。
一般来说,MCU带有I2C 控制器(硬件I2C),也可以使用MCU的2个GPIO自行编写程序模拟I2C总线协议实现同样的功能。
RT-Thread提供了一套I/O设备管理框架,它把I/O设备分成了三层进行处理:应用层、I/O 设备管理层、底层驱动。
I/O设备管理框架给上层应用提供了统一的设备操作接口和I2C 设备驱动接口,给下层提供的是底层驱动接口。
应用程序通过I/O设备模块提供的标准接口访问底层设备,底层设备的变更不会对上层应用产生影响,这种方式使得应用程序具有很好的可移植性,应用程序可以很方便的从一个MCU移植到另外一个MCU。
本文以6轴惯性传感器MPU6050为例,使用RT-Thread I2C设备驱动框架提供的GPIO模拟I2C控制器的方式,阐述了应用程序如何使用I2C设备驱动接口访问I2C设备。
嵌入式Linux中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详解——精选推荐
I2C详解1、基本概念主机初始化发送,产⽣时钟信号和终⽌发送的器件从机被主机寻址的器件发送器发送数据到总线的器件接收器从总线接收数据的器件多主机同时有多于⼀个主机尝试控制总线但不破坏报⽂仲裁是⼀个在有多个主机同时尝试控制总线,但只允许其中⼀个控制总线并使报⽂不被破坏的过程同步两个或多个器件同步时钟信号的过程2、硬件结构每⼀个I2C总线器件内部的SDA、SCL引脚电路结构都是⼀样的,引脚的输出驱动与输⼊缓冲连在⼀起。
其中输出为漏极开路的场效应管、输⼊缓冲为⼀只⾼输⼊阻抗的同相器。
这种电路具有两个特点:(1)由于SDA、SCL 为漏极开路结构,借助于外部的上拉电阻实现了信号的“线与”逻辑;(2)引脚在输出信号的同时还将引脚上的电平进⾏检测,检测是否与刚才输出⼀致。
为“时钟同步”和“总线仲裁”提供硬件基础。
3、时钟同步如果从机希望主机降低传送速度可以通过将SCL主动拉低延长其低电平时间的⽅法来通知主机,当主机在准备下⼀次传送发现SCL的电平被拉低时就进⾏等待,直⾄从机完成操作并释放SCL线的控制控制权。
这样以来,主机实际上受到从机的时钟同步控制。
可见SCL 线上的低电平是由时钟低电平最长的器件决定;⾼电平的时间由⾼电平时间最短的器件决定。
这就是时钟同步,它解决了I2C总线的速度同步问题。
4、主机发送数据流程(1)主机在检测到总线为“空闲状态”(即SDA、SCL 线均为⾼电平)时,发送⼀个启动信号“S”,开始⼀次通信的开始(2)主机接着发送⼀个命令字节。
该字节由7 位的外围器件地址和1 位读写控制位R/W 组成(此时R/W=0)(3)相对应的从机收到命令字节后向主机回馈应答信号ACK(ACK=0)(4)主机收到从机的应答信号后开始发送第⼀个字节的数据(5)从机收到数据后返回⼀个应答信号ACK(6)主机收到应答信号后再发送下⼀个数据字节(7)当主机发送最后⼀个数据字节并收到从机的ACK 后,通过向从机发送⼀个停⽌信号P结束本次通信并释放总线。
i2c的基本工作原理
I2C(Inter-Integrated Circuit)是一种串行通信协议,用于在芯片之间进行数据传输。
它由飞利浦半导体(现在的恩智浦半导体)于1982年开发,并广泛应用于各种电子设备中。
I2C具有简单、高效和可靠的特点,成为众多芯片和模块之间常用的通信接口之一。
本文将详细介绍I2C的基本工作原理。
一、总线架构I2C采用了主从结构的总线架构,其中主设备(Master)负责发起数据传输请求,而从设备(Slave)则在接收到请求后进行响应。
一个I2C总线上可以连接多个从设备,每个从设备都有一个唯一的地址。
主设备通过发送起始信号(Start)来启动通信,然后选择要与之通信的从设备地址,最后发送停止信号(Stop)结束通信。
二、物理层I2C使用双线制进行数据传输,包括数据线(SDA)和时钟线(SCL)。
数据线上的信号是双向的,用于传输数据。
时钟线则由主设备控制,用于同步数据传输。
三、起始和停止信号I2C通信以起始信号(Start)和停止信号(Stop)来标识通信的开始和结束。
起始信号由主设备产生,它表示将要发起一次新的通信。
停止信号同样由主设备产生,表示一次通信的结束。
四、数据传输格式I2C采用了基于字节的数据传输格式。
每个字节都由8位二进制数据组成,包括7位数据位和1位数据方向位。
数据方向位为0表示发送数据,为1表示接收数据。
在每个字节的传输过程中,都会先发送数据方向位,然后再发送数据位。
五、时钟同步I2C使用时钟同步机制来确保通信的准确性。
时钟线由主设备产生,并控制整个数据传输过程的时序。
在每个时钟周期中,数据线上的数据必须稳定,并且只有在时钟线为低电平时才能改变。
六、地址传输在I2C通信中,每个从设备都有一个唯一的7位地址。
主设备通过发送地址来选择要与之通信的从设备。
地址由8个位组成,最高位是固定的0或1,用于表示读(1)或写(0)操作。
其余的7位用于指定从设备的地址。
七、数据传输流程I2C通信的数据传输流程如下:1. 主设备发送起始信号(Start)。
linux系统i2c协议详解
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协议正在不断发展,以满足新应用的需求。
I2C通信原理及程序详细讲解
I2C通信原理及程序详细讲解I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器、传感器和其他外部设备。
I2C通信协议由荷兰飞利浦公司于1982年开发,它使用两根信号线(SDA和SCL)进行数据传输。
I2C通信协议采用主从结构,一个主设备(如微控制器)可以连接多个从设备(如传感器)。
主从设备之间通过SDA和SCL线进行数据传输。
SDA线是双向数据线,用于传输数据,SCL线是时钟线,用于同步数据传输。
I2C通信协议中,设备的地址是一个重要概念。
每个设备都有一个唯一的地址,通过该地址可以选择和通信特定的设备。
地址由7个位组成,其中最高位是固定的,并取决于设备是主设备还是从设备。
如果最高位为0,则表示该设备是主设备;如果最高位为1,则表示该设备是从设备。
通过以下步骤,让我们详细了解如何在I2C总线上进行通信。
1.初始化I2C总线:在程序开始时,需要初始化I2C总线。
这通常包括初始化SDA和SCL引脚,设置时钟频率等。
具体的初始化步骤取决于使用的硬件和软件环境。
2.发送开始信号:开始信号表示I2C数据传输的开始。
它由主设备发送,并且SDA线从高电平转为低电平时发出。
发送开始信号后,SDA线上的数据将被解释为地址数据。
3.发送设备地址:主设备发送一个包含设备地址和读/写位(R/W)的数据字节。
设备地址是唯一的,并且由主设备选择。
读/写位指示从设备是要读取数据还是写入数据。
4.等待从设备响应:主设备发送设备地址后,会等待从设备的响应。
从设备将响应一个应答位(ACK)来确认地址接收成功。
如果收到ACK位,则继续进行下一步,否则可能是设备未连接或通信错误。
5.发送数据:主设备发送数据给从设备。
数据可以是命令、配置或实际数据,具体取决于应用场景。
发送数据的方式是将每个数据字节传输到SDA线上,并在每个数据字节后发送一个ACK位。
6.接收数据:从设备将数据发送给主设备。
数据可以是传感器读数、存储器数据等。
Linux下基于I2C的电源管理芯片驱动设计
0 引 言
内部 集 成 电路 (ne—ne rtd crut 2 itritg ae i i c ,IC)
12 IC 总 线 信 号 时序 . 2
S DA 和 S L2条 信 号 线 都 处 于 高 电平 ,即 总 线 C 空 闲状 态 , 2条 信 号 线 各 自的 上 拉 电阻 把 电平 拉 高 ;
( tritgae i ut u d r iu . h 2 u miga dtese il rhtcueo eICb s nte n xk re ae i e— e rtdcr i n e n x T eICb s i n n p ca ac i tr fh 2 u u en l r n n c ) L t h e t i h Li
23 I C设 备 驱 动 . 2
CON Dn1 oN
图 1 IC总 线起 始 信 号 与结 束信 号【 2
定 义 描 述 具 体 设 备 的 IC cin 2 l t和 可 能 的私 有 e 数 据 结 构 、借 助 IC 框 架 的 IC pr be 函 数 实 现 注 2 2 o
S
‘ 、
.
源 转 换 输 出 的应 用 ,提 供 简 单 易 用 而 又 可 以灵 活 配 置 的完 整 电源 解 决 方 案 , 充 分 满 足 目前 日益 复 杂 的 应 用 处 理器 系 统 对 于 电源 相 对 复 杂 而 精 确 控 制 的要 求 。AXP 9 提 供 了一 个 与主 机 通 讯 的 两 线 串行 通 12
接 收 端 接 收 完 一 个 字 节 后 , 会 立 刻 在 AC 周 期 内 K
1 IC总线 概 述 与时序 2
11 IC 总 线 介 绍 . 2
将 S DA 由高 电平 翻 转 为低 电 平 ,这 便 产 生 了 一 个
I2C实例解析
实例解析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设备。
Linux I2C设备驱动编写
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匹配函数了。
嵌入式Linux中I2C总线驱动程序设计
Ke r s e e d d L n x I C b s I C d v c ; d v c r e ; AT 1 ywo d : mb d e ; i u ; 2 u ; 2 e i e e ie d i r v 9 RM 9 0 2 0
0 引 言
ICit - tga d i u ) 线 , 由菲利 浦 公 司开 发 的一 2 ( e i ert c ci总 n rn e r t 是 种 同步 串行 总 线 协 议 , 于 连 接 微 控 制 器 及 其 外 围 设 备 。最 用 初 是 为 音 频 和 视 频 设 备 开 发 的 ,如 今 IC在 各 种 电 子 设 备 中 2
中图法分类 号 : P9 T 3 T 3 ; P
文献标 识码 : A
文章编 号 :0 072 (0 8 1—570 10 —0 4 2 0 ) 02 1—3
De in o C u r e n e mb d e n x s se sg f 2 b s i ru d r I d v e e d dLiu y tm
IC总 线 在 传 送 数 据 过 程 中共 有 3 类 型 信 号 , 们 分 别 2 种 它 是 开 始 信 号 、 束 信 号 和 应 答 信 号( 图 l 图 2 示 ) 结 如 、 所 。
得 到 了 广 泛 的 应 用 。嵌 入 式 系 统 中 常 常 使 用 这 个 总 线 连 接
HEYa u , DE jn NGF i i e— q
( o ee f uo t nS i c n n ier g o t C ia iesyo T cn lg,G agh u 6 0 C ia C lg A tmao ce e d gn e n ,S u h v r t f eh oo y un z o 1 4 , hn) l o i n a E i h n Un i 50
Linux I2C总线体系结构及I2C设备的访问控制研究
福 建 电
脑
21 0 1年第 3 期
Ln xIC总线体 系结构及 IC设 备 的访 问控 制研 究 iu 2 2
莫 丽娟 .王 静 文
(黄 河水利 职 业技 术 学院 河 南 开封 4 50 7 0 3)
【 摘 要 】 RM iu 用 的越 来越 广 泛,iu :A Ln x应 Ln x驱动 程序 的设计 也成 了工程 师们 开发硬 件设 备 必须
Ln x的 IC体 系结 构 分 为 3个 部 分 : C核 心 、 iu 2 I 2 内核 中 ie 2. h文件 对 ic d vri _ l n 、 c aa 2 _ f e、 e ci ti — d p i 2 e 2 t 和 ic l r m这 四个数 据结构进 行 了定义 . 析 e r 2 a oi g t h 分 IC总线 驱动 、 C设备 驱动 。 2 I 2 IC核 心对 应 的源 码 在 Ln X2 2 iU . 6内核 d vr目录 这 四个 数据 结构 复杂 的关 系是理解 IC体 系结 构 的关 i re 2 下 的 ic c . 2 — oe 它提供 了 IC总线 和 IC设备 驱动 的 键 所在 rc 2 2
C U内部 P
e ( ) c d vr ic ci n 。 2 i _ f e 与 2 l t 2 i ic di r 2 r e 对应 一套驱 动方法 .是 纯粹辅 助作 用 的 v 数 据 结构 。 不对 应 任何 的物 理实 体 。ic ci t 应 于 2 l n 对 e
_
真 实 的物 理设 备 . 每个 IC设 备 都需 要 一 个 icci t 2 2_ l n e
来 描述 。
( ica a t 3) d pe与 ic. in 2 2 l t c e 。‘
LinuxI2C驱动整理(以RK3399Pro+Kernel4.4为例)
LinuxI2C驱动整理(以RK3399Pro+Kernel4.4为例)⼀. Linux I2C驱动架构Linux内核⾥,I2C驱动框架可以分为两层,adapter驱动和deivce驱动。
Adapter驱动也可以理解为I2C总线驱动,指的是SOC⾥的I2C控制器驱动。
⼀个SOC可能包含多个I2C控制器,⽽每个控制器的使⽤⽅式是相同的(寄存器参数、收发数据的⽅法等),因此多个控制器可以共⽤⼀套adapter驱动;Deivce驱动,对应的是SOC外围的I2C设备,不同类型I2C设备需要开发不同的设备驱动,同⼀类型的I2C设备可以使⽤⼀种驱动,但是每⼀个I2C设备都由⼀个唯⼀的client来描述。
⼆. Adapter配置DTSI⽂件(kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi)描述了RK3399Pro所有的I2C控制器信息:i2c0: i2c@ff3c0000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff3c00000x00x1000>;clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c0_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c1: i2c@ff110000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1100000x00x1000>;clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c1_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c2: i2c@ff120000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1200000x00x1000>;clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c2_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c3: i2c@ff130000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1300000x00x1000>;clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c3_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c5: i2c@ff140000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1400000x00x1000>;clocks = <&cru SCLK_I2C5>, <&cru PCLK_I2C5>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c5_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c6: i2c@ff150000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1500000x00x1000>;clocks = <&cru SCLK_I2C6>, <&cru PCLK_I2C6>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c6_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c7: i2c@ff160000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff1600000x00x1000>;clocks = <&cru SCLK_I2C7>, <&cru PCLK_I2C7>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c7_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c4: i2c@ff3d0000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff3d00000x00x1000>;clocks = <&pmucru SCLK_I2C4_PMU>, <&pmucru PCLK_I2C4_PMU>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c4_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};i2c8: i2c@ff3e0000 {compatible = "rockchip,rk3399-i2c";reg = <0x00xff3e00000x00x1000>;clocks = <&pmucru SCLK_I2C8_PMU>, <&pmucru PCLK_I2C8_PMU>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;pinctrl-names = "default";pinctrl-0 = <&i2c8_xfer>;#address-cells = <1>;#size-cells = <0>;status = "disabled";};可以看出,该SOC共有9个I2C控制器,分别为I2C0~I2C8, 每个控制器对应了不同的寄存器基地址(例如I2C0对应0xff3c0000),它们的compatible匹配属性都是"rockchip,rk3399-i2c",也就是对应了同⼀个adapter驱动。
linux下i2c接口的电容触摸屏驱动开发
原文地址:电容触摸屏2011-01-14 15:361.Kconfig文件增加宏定义2.Makefile文件增加编译处理3.添加程序源码Touch screen remote control design document2010年11月08日星期一 13:08Touch screen remote control design document1. 开发板环境a) Mini2440 开发板。
Arm9 处理器+64M SRAM + 64M Flash +3.5’触摸屏LCDb) Linux 2.6.32 kernel,支持多点触摸触摸屏+Qtopia 2.2.20 图形用户界面系统c) AVR 单片机+加速度传感器+红外一体化接收头+红外发射二极管2. 主机开发环境a) Vmware 6.0 安装 Fedora 10 系统,按照友善之臂mini2440 使用手册来建立开发环境。
最好在安装fedora 10的过程中将所有的可选项全部安装,以免后续开发过程中遇到不可预知的问题。
Fedora 10默认不能以root用户登陆图形用户界面,需要以普通用户登陆之后在命令终端中su切换到root用户,然后修改文件/etc/pam.d/gdm。
将auth required pam_succeed_if.so user != root quiet 这句注销。
b) 按照友善之臂用户手册建立交叉开发环境。
安装arm-linux-gcc4.3.2,arm-qtopia, x86-qtopia, root-qtopia, linux-2.6.32-friendlyarm 到系统中。
安装的过程中有一个问题是,不能够同时编译arm-qtopia和x86-qtopia,如果这样做,会发生不可预知的错误。
典型问题是qt2的designer打开后是透明的,无法操作。
c) 遥控器解码目前采用FPGA平台来完成的,所以主机具有FPGA开发环境(quartus9.0)d) 红外发射和加速度传感器的手势操作室通过AVR单片机完成的,所以主机具有AVR单片机开发环境(Keil 4)3. 图形界面编码a) Arm-qtopia 文件夹中安装了qt2,在qt2的bin目录下执行 designer 就可以进入qt的图形开发界面。
rk linux下i2c总线驱动读写原理
RK Linux下I2C总线驱动读写原理RK Linux,一个开源的、强大的、可定制的操作系统,广泛应用于各种嵌入式系统。
I2C总线是一种常用的通信协议,常用于连接低速外围设备,如传感器、EEPROM等。
在RK Linux下,I2C总线驱动的读写原理是什么呢?首先,我们来了解下I2C总线的基本概念。
I2C总线是一种双线串行通信总线,由数据线SDA和时钟线SCL组成。
通过这两根线,多个设备可以在同一总线上进行通信。
每个设备都有一个唯一的地址,主机可以通过发送设备的地址来选择与之通信的设备。
在RK Linux下,I2C总线驱动的读写操作主要依赖于内核提供的API。
这些API 包括i2c_read()、i2c_write()等,它们提供了与I2C设备通信的接口。
那么,这些API是如何实现读写操作的呢?在内核中,I2C驱动程序负责管理I2C总线上所有的设备和它们的通信。
当需要从设备读取数据时,驱动程序首先会向设备发送读请求。
设备接收到请求后,会将数据写入SDA线。
驱动程序会持续监听SDA线,一旦接收到数据,就会将其保存并通知应用程序。
同样地,当需要向设备写入数据时,驱动程序会向设备发送写请求。
设备接收到请求后,会准备好接收数据。
驱动程序会将数据写入SDA线,设备接收到数据后,会将数据保存到内部寄存器中。
需要注意的是,I2C总线的读写操作都是通过驱动程序来完成的。
应用程序只需要调用内核提供的API即可与I2C设备进行通信。
这样设计的好处是应用程序可以专注于自己的业务逻辑,而不需要关心底层的通信细节。
同时,这也使得应用程序与具体的I2C设备无关,具有更好的可移植性和扩展性。
Mini2440之i2c驱动(2)
Linux下基于I2C总线的CAT1025设备驱动实现
1
IC总线 接 口 2
L 2 0 微 控 制 器 是 基 于 一 个 支 持 实 时 仿 真 和 嵌 入 跟 踪 的 3 /1 位 ARM7 PC 21 2 6 TD 集 成 了 两 路 高 速 IC 总 线 , 2 与 IC 总 线 接 口 有 关 的 专 用 寄 存 器 有 以 下 : 2
21 0 1年 4月
枣庄学 院学报
J OUR AL O AO HUAN I E 盯Y N FZ Z G UN V RS
Ap . 01 r2 1
第2卷 8
第 2期
V0 . 8 NO. 12 2
Ln x下 基 于 IC总 线 的 C T 5设 备 驱 动 实 现 iu 2 A 12 0
王 莹
( 枣庄学院 计算机科学 系, 山东 枣庄 27 6 ) 7 10
[ 摘
要] 本文介绍 了 L C 20处 理器 IC总线 的工作 原理 , P21 2 分析 了嵌 入式 l u i x内核 中 IC总线驱动的体 系结 构和各 n 2
个模块 的功能. 结合具体 的 IC接 口的存储器和 电源监 控的完 全解决 方案 C T 05芯 片 , 细给 出了嵌入式 l u 2 A 12 详 i x下 n 基于 IC总线 C T 0 5设备驱动程序 的开发过 程. 2 A 12 [ 关键词 ]2 IC总线 ; 设备驱动 ; A 12 ; C T 05 嵌入式 Lnx iu [ 中图分类 号] P 7 T24 [ 文献标识码 ] A ① [ 文章编号 ]04— 07 2 1 )2—08 0 10 7 7 (0 1 0 0 7— 5
1I 总 线 连 接 图 . 2C
12 IC 时 序 信 号 . 2
①
[ 收稿 日期] 0 0 1 — 6 2 1 — 1 1 [ 作者简介] 王莹 ( 92一 , , 枣庄人 , 学院计算机科 学系助 教, 1 8 ) 女 山东 枣庄 工学硕 士, 主要研究方 向 : 嵌入式 系统及 其应用 , 机 器人控制.
Linux下读写芯片的I2C寄存器
Linux下读写芯⽚的I2C寄存器要想在Linux下读写芯⽚的I2C寄存器,⼀般需要在Linux编写⼀份该芯⽚的I2C驱动,关于Linux下如何编写I2C驱动,前⼀篇⽂章已经做了初步的介绍,并且留下了两个疑问尚未解决,第⼀个是如何对Linux提供的I2C操作函数进⾏进⼀步封装,实现对芯⽚寄存器的读写;另⼀个是如何在⽤户空间调⽤该I2C驱动代码。
本⽂将讨论前⼀个问题。
⾸先,我们要了解Linux系统提供的I2C操作函数怎么使⽤,上篇⽂章已经提到过,对I2C设备的读写,Linux系统提供了多种接⼝,这些接⼝可以在内核的 i2c.h 中找到,这⾥我主要介绍下⾯这组读写接⼝:extern int i2c_master_send(struct i2c_client *,const char* ,int);extern int i2c_master_recv(struct i2c_client *,char* ,int);第⼀个参数是 i2c_client 对象指针,第⼆个参数是要传输的数据buffer指针,第三个参数为buffer的⼤⼩。
接⼝函数已经有了,下⾯我们要解决的问题就是以何种形式/规则去使⽤这些接⼝才能正确地读写芯⽚的相关寄存器。
⾸先,我们需要查询芯⽚⼿册,找到芯⽚⼿册中,关于寄存器的I2C读写时序,其实,⼤多数芯⽚的I2C寄存器的读写时序都是⼀样的,下⾯我还是以⼿头的TVP5158芯⽚为例。
⾸先分析写操作,该芯⽚的⼿册中给出的I2C寄存器写时序图如下:从上图可以看出,真正需要执⾏写操作的有两处,Step4 和 Step6 ,Step4⾸先写⼊寄存器的偏移地址,⽽Step6则是写⼊到该寄存器的值。
由此已经很清楚了,对于写I2C寄存器,我们需要做的就是给 i2c_master_send 函数传⼊两个字节的数据即可,第⼀个字节为寄存器的地址,第⼆个字节为要写⼊寄存器的数据。
⽰例如下:static int tvp5158_i2c_write( struct i2c_client* client,uint8_t reg,uint8_t data){unsigned char buffer[2];buffer[0] = reg;buffer[1] = data;if( 2!= i2c_master_send(client,buffer,2) ) {printk( KERN_ERR " tvp5158_i2c_write fail! \n" );return -1;}return 0;}其实挺简单的,没有什么复杂的代码。
Linux I2C驱动源码分析
内核版本:2.6.31.6首先在S3C2440平台的初始化函数中,主要是将开发平台的设备注册进了系统,也就是将device注册到了platform虚拟的总线上,并进行了一些初始化的工作,这里我们只关注I2C的部分。
static void __init smdk2440_machine_init(void){s3c24xx_fb_set_platdata(&smdk2440_fb_info);s3c_i2c0_set_platdata(NULL);platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));smdk_machine_init();}s3c_i2c0_set_platdata()函数将S3C2440上的I2C控制器进行了一些初始化,但是并没有写入硬件寄存器,仅仅是保存在了s3c2410_platform_i2c结构体中。
void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd){struct s3c2410_platform_i2c *npd;if (!pd)pd = &default_i2c_data0;npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);if (!npd)printk(KERN_ERR "%s: no memory for platform data\n", __func__);else if (!npd->cfg_gpio)npd->cfg_gpio = s3c_i2c0_cfg_gpio;/* s3c_i2c0_cfg_gpio为配置I2C控制器GPIO函数指针 */s3c_device_i2c0.dev.platform_data = npd;/*最后将struct device 中的platform_data指针直指向了初始化后的s3c2410_platform_i2c结构体 */}函数s3c_i2c0_cfg_gpio()很简单,实际上就是配置GPIO为I2C的工作模式void s3c_i2c0_cfg_gpio(struct platform_device *dev){s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);}s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)函数实际上就是把初始化数据段中的default_i2c_data0结构体复制过来,然后对GPIO进行配置的函数指针进行了初始化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux下I2C驱动架构全面分析I2C概述I2C是philips提岀的外设总线.I2C只有两条线,一条串行数据线:SDA, —条是时钟线SCL,使用SCL , SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线。
因此,I2C总线被非常广泛地应用在EEPROM,实时钟,小型LCD等设备与CPU的接口中。
linux下的驱动思路在linux系统下编写I2C驱动,目前主要有两种方法,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux下I2C驱动体系结构来完成。
下面比较下这两种方法:第一种方法:优点:思路比较直接,不需要花很多时间去了解linux中复杂的I2C子系统的操作方法。
缺点:要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器(I2C控制器)操作。
要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写岀的程序可以移植性差。
对内核的资源无法直接使用,因为内核提供的所有I2C设备器以及设备驱动都是基于I2C子系统的格式。
第一种方法的优点就是第二种方法的缺点,第一种方法的缺点就是第二种方法的优点。
I2C架构概述Linux的I2C体系结构分为3个组成部分:I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册,注销方法,I2C通信方法(” algorithm 上层的,与具体适配器无关的代码以及探测设备,检测设备地址的上层代码等。
I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。
I2C设备驱动:I2C设备驱动(也称为客户驱动)是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。
linux 驱动中i2c 驱动架构Algorithm12匚_Achpte 「 ]-- ------ ifi 问抽軀上图完整的描述了 linux i2c 驱动架构,虽然I2C 硬件体系结构比较简单,但是i2c 体系结构在 linux 中的实现却相当复杂。
那么我们如何编写特定i2c 接口器件的驱动程序?就是说上述架构中的那些部分需要我们完成, 而哪些是linux 内核已经完善的或者是芯片提供商已经提供的?架构层次分类第一层:提供i2c adapter 的硬件驱动,探测、初始化i2c adapter (如申请i2c 的io 地址和 中断号),驱动soc 控制的i2c adapter 在硬件上产生信号(start 、stop 、ack )以及处理i2c 中 断。
覆盖图中的硬件实现层Appl用户 访问driver驱动层与待走的阴匚愉2保件相关的代码 < --------- 厠4实规控制层12C AdaptorZSOC 芯片内部的)2G 模块121? Device 1IK I J L -vice 2J2C Device3,-挂lldZC 总线上的貝休番件diiv^rL licmd m Jii2c 核心层hdidwaTe第二层:提供i2c adapter 的algorithm ,用具体适配器的xxx_xferf() 函数来填充i2c_algorithm 的master_xfer 函数指针,并把赋值后的i2c_algorithm 再赋值给i2c_adapter的algo指针。
覆盖图中的访问抽象层、i2c核心层第三层:实现i2c设备驱动中的i2c_driver 接口,用具体的i2c device 设备的attach_adapter() 、detach_adapter() 方法赋值给i2c_driver 的成员函数指针。
实现设备device与总线(或者叫adapter )的挂接。
覆盖图中的driver驱动层第四层:实现i2c设备所对应的具体device的驱动,i2c_driver 只是实现设备与总线的挂接,而挂接在总线上的设备则是千差万别的,所以要实现具体设备device的write()、read()、ioctl()等方法,赋值给file_operations ,然后注册字符设备(多数是字符设备)。
覆盖图中的driver驱动层第一层和第二层又叫i2c总线驱动(bus),第三第四属于i2c设备驱动(device driver)。
在linux驱动架构中,几乎不需要驱动开发人员再添加bus,因为linux内核几乎集成所有总线bus,如usb、pci、i2c等等。
并且总线bus中的(与特定硬件相关的代码)已由芯片提供商编写完成,例如三星的s3c-2440 平台i2c 总线bus 为/drivers/i2c/buses/i2c-s3c2410.c第三第四层与特定device相干的就需要驱动工程师来实现了。
Linux下I2C体系文件构架在Linux内核源代码中的driver目录下包含一个i2c目录.built-in.o.cmcislqi2e-smbu^it 「]J2c-dev.OnCmdn-figMakefiliJ2c-二广弓i广;亡.c上irore r o,cmcli2c- bcardinfc^o ;2c-F2c- bojrdinfo.ci2c-core.c 这个文件实现了I2C核心的功能以及/proc/bus/i2c* 接口。
i2c-dev.c 实现了I2C适配器设备文件的功能,每一个I2C适配器都被分配一个设备。
通过适配器访设备时的主设备号都为89,次设备号为0-255。
I2c-dev.c 并没有针对特定的设备而设计,只是提供了通用的read(),write(), 和ioctl()等接口,应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器,并控制I2C设备的工作方式。
busses文件夹这个文件中包含了一些I2C总线的驱动,如针对S3C2410 ,S3C2440 ,S3C6410等处理器的I2C控制器驱动为i2c-s3c2410.c.algos文件夹实现了一些I2C总线适配器的algorithm.重要的结构体i2c_driver[cpp] view pla in copy1. struct i2c_driver {2. unsigned int class ;3. int (*attach_adapter)( struct i2c_adapter *); // 依附i2c_adapter 函数指针4. int (*detach_adapter)( struct i2c_adapter *); // 脱离i2c_adapter 函数指针5. int (*probe)( struct i2c_client *, const struct i2c_device_id *);6. int (*remove)( struct i2c_client *);7. void (*shutdown)( struct i2c_client *);8. int (*suspend)( struct i2c_client *, pm_message_t mesg);9. int (*resume)( struct i2c_client *);10. void (*alert)( struct i2c_client *, unsigned int data);11. int (*command)( struct i2c_client *client, unsigned int cmd, void *arg); // 命令列表12. struct device_driver driver;13. const struct i2c_device_id *id_table; // 该驱动所支持的设备ID 表14. int (*detect)( struct i2c_client *, struct i2c_board_info *);15. const unsigned short *address_list;16. struct list_head clients;17. };i2c_clie nt[cpp] view pla in copy1. struct i2c_client {unsigned short flags ;// 标志2.3. unsigned short addr; //低7位为芯片地址4. char name[I2C_NAME_SIZE]; //设备名称5. struct i2c_adapter *adapter; // 依附的i2c_adapter6. struct i2c_driver *driver; // 依附的i2c_driver7. struct device dev; // 设备结构体 8. int irq; //设备所使用的结构体 9. struct list_head detected; // 链表头 10.};i2c_adapter[cpp] view pla in copy1. struct i2c_adapter {2. struct module *owner; // 所属模块3. unsigned int id; //algorithm 的类型,定义于 i2c-id.h,4. unsigned int class ;5. const struct i2c_algorithm *algo; // 总线通信方法结构体指针6. void *algo_data; //algorithm 数据7. struct rt_mutex bus_lock; //控制并发访问的自旋锁8. int timeout; 9. int retries;// 重试次数10. struct device dev; // 适配器设备 11. int nr; 12. char name[48];// 适配器名称13. struct completion dev_released; // 用于同步 14. struct list_head userspace_clients; //client 链表头15.};i2c_algorithm[cpp] view pla in copy1. struct i2c_algorithm {各结构体的作用与它们之间的关系i2c_adapter 与 i2c_algorithm2.int (*master_xfer)( struct i2c_adapter *adap,struct i2c_msg *msgs, int num);3.传输函数指针 int (*smbus_xfer)( struct i2c_adapter *adap, u16 addr,unsigned short flags,〃I2Cchar read_write,u8 command, 4. i2c_smbus_data *data); 5.u32 (*functionality)( 6.};int size, union//smbus 传输函数指针 struct i2c_adapter *);//返回适配器支持的功能i2c_adapter 对应与物理上的一个适配器,而 i2c_algorithm 对应一套通信方法,一个i2c 适配器需要i2c_algorithm 中提供的(i2c_algorithm 中的又是更下层与硬件相关的代码提供)通信函数来控制适配器上产生特定的访问周期。