I2C驱动架构
51单片机的I2C底层驱动程序(IO口模拟)
51单片机的I2C底层驱动程序(IO口模拟)/*Title:I2C for 80C51Author:yuyouliang51单片机(本人使用STC89C52单片机,12T模式)的I2C驱动程序,使用逻辑分析仪对该协议进行分析,发现波形比较美观,SCL 的频率在70KHz左右(11.0592M晶振),低于标准的100K,可以适应大多数的I2C器件。
如果感觉速度过快或过慢,可以自行修改延时。
希望可以给读者一个参考,给读者一些帮助!*//*i2c.h文件 */#ifndef __I2C_H_#define __I2C_H_sbit SCL = P2^1;sbit SDA = P2^0;void start_i2c(); //启动I2C总线:SCL高电平期间,SDA由高变低void stop_i2c(); //停止I2C总线:SCL高电平期间,SDA由低变高void send_i2c(unsigned char c); //主机发送一个字节,先发送最高位unsigned char receive_i2c(); //主机接收一个字节,先接收最高位void master_ack(bit ack); //主机非应答信号(填参数0)或应答信号(填参数1)void slave_ack(); //等待从机应答信号#endif/* i2c.c文件 */#include#include#include#define nop() _nop_()void start_i2c() //启动I2C总线:SCL高电平期间,SDA由高变低{SDA=1;SCL=1;nop();nop();nop();nop();SDA=0;SCL=0;}void stop_i2c() //停止I2C总线,SCL高电平期间,SDA由低变高{SDA=0;SCL=1;nop();nop();nop();nop();SDA=1;}void slave_ack() //等待从机应答信号,如果从机迟迟没有应答,则结束总线。
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设备。
基于S3C2410ARM的I2C总线驱动架构的设计
, i i。 t n
ch r n me【 a a 8];
被广泛的应用于嵌人式设备中, 本文将基于 3 4 s C2 10ARM 处理器 C 总线驱动程序进 对IZ 行设计。 1 1 ℃总线驱动体系结构
IZ 设备在Lulux 下可以作为一个字符设 C 备, 根据需要写一个字符设备驱动程序, 实现 IZ 通信。IZ 是一个标准设备,Linux 专门 C C 为IZ 定义了驱动程序接口 C 标准, 按照这个标 准编写IZ 驱动程序, C 使驱动程序有统一的接 口, 方便挂载在IZ 总线上的其他驱动程序和 C 应用程序的移植。 Llnux 标淮的IZ 驱动程序在内核源码的 C dr ver / iZ 目 i s c 录下, 最主要的文件是iZ c代刀 , 正.c 它负 责管理总线设备驱动接口, 实现IZ 设备 C ( 包括 IZC 适配器和 IZC 从设备)的注册、删 除、 通信等。L ntIX标准的I C 驱动程序也是 i Z
根据图2的Li u IZ 动 nx C驱 程序体系 构, 结 需
程序, 需要填充1 _ad P e , 弋 a t r 定义如下: tU z a s r ct i _ad pter { c ch r name 32]; a I
un及 le illt i , g d d t s r uct iZ algor hln *algo . c一 i t vold * 1 _d t , a 9 a a 0
6 0 1 NC E & TE O ll《】 3 Y INF O日MA TIO N 卜 LI)
工 业 技 术
基于 S3C241 ARM 的 1 总线驱动架构的设计 0 2C
杨德芳
(潍坊学院计算机系
山东潍坊
2e O ) l 4 1
I2C设备与驱动的关联
I2C设备与驱动的关联作者:leeoo 联系方式:neu_linuxer@在Linux操作系统中,驱动程序的加载分为两种:内核启动时自动加载和用户手动加载;硬件设备也可以采用两种方式添加到系统中:在系统启动前及系统运行时的热插拨。
下面,我们以arm体系结构下的at91处理器中的I2C控制器为例,介绍一下硬件设备及相关的驱动程序是如何绑定及松绑的。
1.平台驱动注册过程1.1 at91_i2c_init()函数在文件drivers/i2c/busses/i2c-at91.c中,定义了结构体struct platform_driver并进行了初始化,通过使用module_init()宏进行声明,当模块被加载到内核时会调用 at91_i2c_init()函数。
在此函数中,调用了platform_driver_register()函数来完成注册。
static struct platform_driver at91_i2c_driver = {.probe = at91_i2c_probe,.remove = __devexit_p(at91_i2c_remove),.suspend = at91_i2c_suspend,.resume = at91_i2c_resume,.driver = {.name = "at91_i2c",.owner = THIS_MODULE,},};static int __init at91_i2c_init(void){return platform_driver_register(&at91_i2c_driver);}1.2 platform_driver_register()函数在文件drivers/base/platform.c中,实现并导出了platform_driver_register()函数,以便使其他模块中的函数可以调用此函数。
I2C总线驱动在嵌入式系统中的两种实现,I2C,嵌入式,AR.
I2C总线驱动在嵌入式系统中的两种实现,I2C,嵌入式,ARM,软件模拟1引言I2C总线(Inter-ICBus)是一种通用的串行总线,是用于IC器件之间连接的二线制总线。
他通过串行数据线(SerialDataLines,SDL)及串行时钟线(SerialClockLine,SCL)两线在连接到总线上的器件之间传送信息,并根据地址识别每个器件。
一个或多个微控制器以及外围器件可以通过I2C总线接口非常方便的连接在一起构成系统。
这种总线结构的连线和连接引脚少,器件间总线简单。
结构紧凑,因此其构成系统的成本较低;并且在总线上增加器件不1 引言I2C总线(Inter-IC Bus)是一种通用的串行总线,是用于IC器件之间连接的二线制总线。
他通过串行数据线(SerialData Lines,SDL)及串行时钟线(Serial ClockLine,SCL)两线在连接到总线上的器件之间传送信息,并根据地址识别每个器件。
一个或多个微控制器以及外围器件可以通过I2C总线接口非常方便的连接在一起构成系统。
这种总线结构的连线和连接引脚少,器件间总线简单。
结构紧凑,因此其构成系统的成本较低;并且在总线上增加器件不会影响系统的正常工作,所有的I。
C 器件共用一套总线,因此其系统修改和可扩展性好。
即使有不同时钟速度的器件连接到总线上,时间同步机制也能够很方便地确定总线时钟,因此在嵌入式系统中得到了广泛的应用。
2 I2C总线原理2.1 I2C工作原理I2C总线是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。
每个连接到总线的器件都可以通过惟一的地址与主机通讯,主机可以作为主机发送器或主机接收器。
他是一个真正的多主机总线,如果两个或更多主机同时初始化,数据传输可以通过冲突检测和仲裁防止数据被破坏。
串行的8位双向数据传输位速率在标准模式下可达100kb/s,快速模式下可达400 kb/s,高速模式下可达3.4 Mb/s。
TI-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的讲解
1. 几个基本概念1.1. 设备模型由总线(bus_type)+ 设备(device)+ 驱动(device_driver)组成,在该模型下,所有的设备通过总线连接起来,即使有些设备没有连接到一根物理总线上,linux为其设置了一个内部的、虚拟的platform总线,用以维持总线、驱动、设备的关系。
因此,对于实现一个linux下的设备驱动,可以划分为两大步:1、设备注册;2、驱动注册。
当然,其中还有一些细节问题:1、驱动的probe函数2、驱动和设备是怎么进行绑定的。
1.2. i2c设备驱动的几个数据结构i2c_adapter:每一个i2c_adapter对应一个物理上的i2c控制器,在i2c总线驱动probe函数中动态创建。
通过i2c_add_adapter注册到i2c_core。
i2c_algorithm:i2c_algorithm中的关键函数master_xfer(),以i2c_msg为单位产生i2c访问需要的信号。
不同的平台所对应的master_xfer()是不同的,需要根据所用平台的硬件特性实现自己的xxx_xfer()方法以填充i2c_algorithm的master_xfer指针;在A31上即是sun6i_i2c_algorithm函数。
i2c_client:代表一个挂载到i2c总线上的i2c从设备,包含该设备所需要的数据:该i2c从设备所依附的i2c控制器 struct i2c_adapter *adapter该i2c从设备的驱动程序struct i2c_driver *driver该i2c从设备的访问地址addr, name该i2c从设备的名称name。
2. i2c总线驱动2.1. 功能划分从硬件功能上可划分为:i2c控制器和i2c外设(从设备)。
每个i2c控制器总线上都可以挂载多个i2c外设。
Linux中对i2c控制器和外设分开管理:通过i2c-sun6i.c 文件完成了i2c控制器的设备注册和驱动注册;通过i2c-core.c为具体的i2c外设提供了统一的设备注册接口和驱动注册接口,它分离了设备驱动device driver和硬件控制的实现细节(如操作i2c的寄存器)。
I2C设备驱动介绍
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.编译和测试:完成驱动程序的编写后,需要将其编译成与操作系统内核匹配的模块或静态链接库。
然后,通过加载驱动模块或重新编译内核来使驱动程序生效。
最后,进行测试,确保驱动程序在各种场景下的正常运行。
Android平台Camera及I2C总线驱动学习小结
Android平台Camera及I2C总线驱动学习⼩结Android平台Camera及I2C总线驱动学习⼩结——基于MSM8x60平台硬件开发⼆部BSP科党潇⼯号:101131511.MSM8x60平台简介High-performance high-level operating system(HLOS) platform(45nm)多核处理器(Modem+Dual Apps in a single chip),⽀持Android TMDual 1.2GHz Scorpion TM +512kB shared L2 cache,eMMC LPDDR2内存专属ARM7 ⽤于功率资源控制及传感器外设操作1080pHD 编解码,Adreno TM 220图形处理器,4-lane MIPI摄像头,最⾼⽀持12M像素WCDMA,GSM,HSDPA,1x advanced,1xEV-DO Rev A/BgpsOne,BT3.0,FM Rx/Tx,WIFI WCN1314AAC,AMR-NB,EVRC,QCELP,etc2.MSM8x60平台Camera及Graphics特性Camera特性:VFE 3.1,MIPI接⼝(4-lane)优异的3A算法(AF,AE,AWB),⾃动帧率AFR(Auto Frame Rate)最⾼⽀持12MegaPixel,12bit/pixel,⽀持BAYER和YUV模式1080p预览@30fps闪光灯⽀持,触摸屏⾃动对焦⽀持业界领先的图像特效集:Hand Jitter Reduction(HJR),Motion ISO,Best-Shot mode,Anti-banding,EV control,JPEG encode & decodeGraphics特性:Adreno 220(MSM v2.0)图形处理器,88M triangles/sOpenGL ES 1.1/ OpenGL ES 1.1/ OpenVG 1.1/SVG tiny 1.2LCD显⽰最⾼⽀持到WSXGA(1440×900),60Hz刷新率。
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匹配函数了。
I2C总线及其驱动程序
SDA SCL 起始 信号 static void __zyI2cAckSend (void) { __ZY_I2C_SDA = 0; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 1; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 0; } 1 2 8 9 应答 信号 1 2 8 9 非应答 信号 停止 信号
1 0 1 0 1 0 1 0
MSB LSB
主机
MSB
LSB
从机
接收一个字节的数据
程序示例
static unsigned char __zyI2cByteReceive(void) { unsigned char ucRt; unsigned char i; // 接收数据 i = 8; do { ucRt = (ucRt << 1) + __zyI2cBitReceive(); } while (--i != 0); }
空闲时SDA状态未知, 需手动拉低
发送重复起始信号
在I2C总线忙时,产生起始条件,以改变数据收发方向。
SDA(I/O) SDA
80C51
SCL(I/O)
I2C从机
SCL
static void __zyI2cStartSend (void) { __ZY_I2C_SDA = 1; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 1; __ZY_I2C_DELAY(); __ZY_I2C_SDA = 0; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 0; }
从机具有I2C地址,内部寄存器均对应具体地址 主机对从机的操作即对寄存器的读写操作
初始化
读操作
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驱动。
Android平台Camera及I2C总线驱动学习小结
Android平台Camera及I2C总线驱动学习小结——基于MSM8x60平台硬件开发二部BSP科党潇工号:101131511.MSM8x60平台简介ØHigh-performance high-level operating system(HLOS) platform(45nm)Ø多核处理器(Modem+Dual Apps in a single chip),支持Android TMØDual 1.2GHz Scorpion TM +512kB shared L2 cache,eMMC LPDDR2内存Ø专属ARM7 用于功率资源控制及传感器外设操作Ø1080pHD 编解码,Adreno TM 220图形处理器,4-lane MIPI摄像头,最高支持12M像素ØWCDMA,GSM,HSDPA,1x advanced,1xEV-DO Rev A/BØgpsOne,BT3.0,FM Rx/Tx,WIFI WCN1314ØAAC,AMR-NB,EVRC,QCELP,etc2.MSM8x60平台Camera及Graphics特性Camera特性:ØVFE 3.1,MIPI接口(4-lane)Ø优异的3A算法(AF,AE,AWB),自动帧率AFR(Auto Frame Rate)Ø最高支持12MegaPixel,12bit/pixel,支持BAYER和YUV模式Ø1080p预览@30fpsØ闪光灯支持,触摸屏自动对焦支持Ø业界领先的图像特效集:Hand Jitter Reduction(HJR),Motion ISO,Best-Shot mode,Anti-banding,EV control,JPEG encode & decodeGraphics特性:ØAdreno 220(MSM v2.0)图形处理器,88M triangles/sØOpenGL ES 1.1/ OpenGL ES 1.1/ OpenVG 1.1/SVG tiny 1.2ØLCD显示最高支持到WSXGA(1440×900),60Hz刷新率。
AN0003+RT-Thread应用笔记之I2C设备应用指南
图4.2.1-1 发送数据函数调用关系
drv_mpu6050.c 中的 mpu6050_write_reg() 函数是MCU向mpu6050寄存器写数据。此函数的实现共有2种,分别 调用了I2C设备驱动接口 rt_i2c_transfer() 和 rt_i2c_master_send() 实现。
图3.2-2 修改MCU 图3.2-3 修改调试选项
5. 编译工程后下载程序至开发板运行。在终端PuTTY(打开对应端口,波特率配置为115200)输入 list_device 命令可以看到名为i2c2的设备,设备类型是I2C Bus,说明I2C设备驱动添加成功了。如图所示:
图3.2-4使用list_device命令查看i2c总线
1. 用户可以在msh shell输入 list_device 命令查看已有的I2C设备,确定I2C设备名称。 2. 查找设备使用 rt_i2c_bus_device_find() 或者 rt_device_find() ,传入I2C设备名称获取i2c总线设备句
柄。 3. 使用 rt_i2c_transfer() 即可以发送数据也可以接收数据,如果主机只发送数据可以使用
3.3 运行示例代码
将I2C示例代码里的 main.c 拷贝到\rt-thread\bsp\stm32f4xx-HAL\applications目录,替换原有的 main.c 。 drv_mpu6050.c、drv_mpu6050.h 拷贝到\rt-thread\bsp\stm32f4xx-HAL\drivers目录,并将它们添加到工程中对应 分组。如图所示:
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设备无关,具有更好的可移植性和扩展性。
i2c,lcd usb驱动
----杨军(2012 年 4 月 5 日)一、 uboot 启动流程第一阶段启动流程: cpu/arm920t/start.S(汇编阶段)进入 SVC-->关闭看门狗-->关闭中断-->进入 cpu_init_crit()--->(临时设置栈指针 SP)-->调整 CPU 的频率 clock_init() -->把完整的 {初始化 CPU 和 SDRAM 1.刷新出去 I/D cache 2.关闭 MMU 和 cache(一定关闭数据 CACHE,指令 CACHE 无所谓) 3.调用 lowlevel_init}UBOOT 代码从 FLASH 搬移到 SDRAM 中 CopyCode2Ram() -->清除 BSS、设置堆栈-->跳入真正的 C 函数 start_armboot第二阶段启动流程:使能 I/D cache,配置 GPIO 端口【board_init()】 -->:注册倒计时定时器,初始化一个早期串口-->输出 UBOOT 第一条打印 -->NOR/NAND FLASH 初始化-->把环境参数读到 SDRAM-->建立设备管理链表-->重新初始化串口为全功能串口-->网卡初始化-->进入 main_loop()大循环 第一二两个阶段合到一起的描述(这个过程要求面试的时候直接能够说的出来): UBOOT 的启动流程:首先初始化 CPU(进 SVC,关看门狗,关中断,调整 CPU 频率)和 RAM(SDRAM 和 DDR 都需要初始化一次), 将 FLASH 上的 BUOOT拷贝到 RAM 中,清除 BSS 和设置堆栈指针,跳转到 C 函数,接着初始化外设(GPIO 口设置,串口初始化,完整功能的 FLASH,, 网卡初始化),进入一个大的循环检测用户是否有按键按下,如有按下: 停止倒计时,等待用户的后续输入;若 规定时间里面 没有按下,执行 bootcmd 所保存的指令(经常这时是加载内核),然后启动内核二、 内核启动过程head.S arch\arm\boot\Compressed(解压内核)—》head.S arch\arm\Kernel(初始化工作)—》head-common.S arch\arm\Kernel(start_kernel 执行内核) start_kernel() [init/main.c] //vmlinux 的第一个 C 函数 -->setup_arch() 处理 UBOOT 传递过来的 TAG 参数(内存其实位置和大小,bootgars) 把 bootargs 参数各项进行拆解(后续代码可以用__setup()接收参数,例如: __setup("init=", init_setup);) 建立 4KB/页的内存管理,丢弃之前 arch/arm/kernel/head.S 中建立的 1MB/段的内存映射关系-->console_init(); //VMLINUX 的第一行打印输出 -->rest_init()Rest_init()函数分析:内核压缩过程:三、 I2C 驱动Random Read 时序图Byte Write 时序图:I2C 协议:1. i2c 协议特点: ============================================================================================== 1.1 它是飞利浦公司生产的一种串口协议 1.2 1.3 它是两根线传输的 SDA,SCl 数据时钟线 两根线上必须要由上拉电阻1.4 1.5 1.6可以挂多个设备,采用的是主从模式 I2c 的时钟都是由主机产生的 半双工通信方式 (SPI 全双工的,四根线,串行的)1.7 速度问题,低速模式:100K/s 全速模式:400k/s 高速模式:3.4M/s (SPI 的速度一般在 10M 左右) 1.8 真正的多主机总线(解释)1.9 串行 8 位双向传输,先传高位再传低位I2C 驱动分析:四、 LCD 驱动TFT LCD 的 TTL 信号 信号名称 VSYNC HSYNC HCLK VD[23:0] LEND PWREN Framebuffer 概述: 用户可以将 FramBuffer 看成是显卡内存的一个映像,将其映射到进程地址空 间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。
Mini2440之i2c驱动(2)
I2C设备驱动介绍
盈量而知芯,方行天下
I2C子系统
盈量而知芯,方行天下
I2C子系统
在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控制器驱动为i2cs3c2410.c。 • algos文件夹 : 实现了一些I2C总线适配器的algorithm。 此外,内核中的i2c.h这个头文件对i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这 4个数据结构进行了定义。理解这4个结构体的作用十分关键,分别给出了它们的定义。
I2C子系统
struct i2c_client { unsigned short flags; /* div., see below */ unsigned short addr; /* chip address - NOTE: 7bit */ /* addresses are stored in the */ /* _LOWER_ 7 bits */ char name[I2C_NAME_SIZE]; struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq; /* irq issued by device */ struct list_head detected; };
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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驱动架构上图完整的描述了linux i2c驱动架构,虽然I2C硬件体系结构比较简单,但是i2c体系结构在linux中的实现却相当复杂。
那么我们如何编写特定i2c接口器件的驱动程序?就是说上述架构中的那些部分需要我们完成,而哪些是linux内核已经完善的或者是芯片提供商已经提供的?架构层次分类第一层:提供i2c adapter的硬件驱动,探测、初始化i2c adapter(如申请i2c的io地址和中断号),驱动soc控制的i2c adapter在硬件上产生信号(start、stop、ack)以及处理i2c中断。
覆盖图中的硬件实现层第二层:提供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目录i2c-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_driver1 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_client1 struct i2c_client {2 unsigned short flags;//标志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_adapter1 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_algorithm1 struct i2c_algorithm {2 int (*master_xfer)(struct i2c_adapter *adap, structi2c_msg *msgs, int num);//I2C传输函数指针3 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union4 i2c_smbus_data *data);//smbus传输函数指针5 u32 (*functionality) (struct i2c_adapter *);//返回适配器支持的功能6 };各结构体的作用与它们之间的关系i2c_adapter与i2c_algorithmi2c_adapter对应与物理上的一个适配器,而i2c_algorithm对应一套通信方法,一个i2c适配器需要i2c_algorithm中提供的(i2c_algorithm中的又是更下层与硬件相关的代码提供)通信函数来控制适配器上产生特定的访问周期。
缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含其使用i2c_algorithm的指针。
i2c_algorithm中的关键函数master_xfer()用于产生i2c 访问周期需要的start stop ack信号,以i2c_msg(即i2c消息)为单位发送和接收通信数据。
i2c_msg也非常关键,调用驱动中的发送接收函数需要填充该结构体1 struct i2c_msg {2 __u16 addr; /* slave address */3 __u16 flags;4 __u16 len; /* msg length */5 __u8 *buf; /* pointer to msg data */6 };i2c_driver和i2c_clienti2c_driver对应一套驱动方法,其主要函数是attach_adapter()和detach_client()i2c_client对应真实的i2c物理设备device,每个i2c设备都需要一个i2c_client来描述i2c_driver与i2c_client的关系是一对多。