Linux下I2C驱动介绍

合集下载

linux下iic(i2c)读写AT24C02

linux下iic(i2c)读写AT24C02

/jammy_lee/

linux下iic(i2c)读写AT24C02

linux驱动2010-02-09 16:02:03 阅读955 评论3 字号:大中小订阅

linux内核上已有iic的驱动,因此只需要对该iic设备文件进行读写则能够控制外围的iic器件。这里以AT24C02为对象,编写一个简单的读写应用程序。iic设备文件在我的开发板上/dev/i2c/0 ,打开文件为可读写。AT24C02的器件地址为0x50 ,既是iic总线上从器件的地址,每次只读写一字节数据。

/************************************************************/

//文件名:app_at24c02.c

//功能:测试linux下iic读写at24c02程序

//使用说明: (1)

// (2)

// (3)

// (4)

//作者:jammy-lee

//日期:2010-02-08

/************************************************************/

//包含头文件

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//宏定义

#define Address 0x50 //at24c02地址

#define I2C_RETRIES 0x0701

#define I2C_TIMEOUT 0x0702

#define I2C_SLAVE 0x0703 //IIC从器件的地址设置

基于iic ds3231 linux驱动说明

基于iic ds3231 linux驱动说明

基于I2C 实时时钟DS3231驱动说明:

1Linux的I2C的整体架构

Linux的i2c框架中各个部分的关系如图(1)所示:

图(1)

内核中i2c相关代码可以分为三个层次:

●i2c框架:i2c.h和i2c-core.c为i2c框架的主体,提供了核心数据结构的定义、i2c

适配器驱动和设备驱动的注册、注销管理,i2c通信方法上层的、与具体适配器无

关的代码、检测设备地址的上层代码等;i2c-dev.c用于创建i2c适配器的/dev/i2c/%d

设备节点,提供i2c设备访问方法等。

●i2c总线适配器驱动:定义描述具体i2c总线适配器的i2c_adapter数据结构、实现

在具体i2c适配器上的i2c总线通信方法,并由i2c_algorithm数据结构进行描述。

●i2c设备驱动:定义描述具体设备的i2c_client和可能的私有数据结构、借助i2c框

架的i2c_probe函数实现注册设备的attach_adapter方法、提供设备可能使用的地址

范围、以及设备地址检测成功后创建i2c_client数据结构的回调函数。

2I2C驱动相关的数据结构

I2C传送信息的数据结构体

struct i2c_msg {

__u16 addr; /* slave address */

__u16 flags;

#define I2C_M_TEN 0x10 /* we have a ten bit chip address */

#define I2C_M_RD 0x01

#define I2C_M_NOSTART 0x4000

linux系统i2c协议详解

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控制

linux i2c驱动

linux i2c驱动

linux i2c驱动

1. i2c-dev interface

I2C dev-interface

通常,i2c设备由某个内核驱动控制。但是在用户空间,也可以访问某个I2C设备:你需要

加载i2c-dev模块。

每个被注册的i2c适配器(控制器)会获得一个数字号,从0开始。你可以检查/sys/class/i2c-dev,来查看适配器对应哪个数字号。你也可以通过命令

"i2cdetect -l"获

取你的当前系统的所有I2c适配器的列表。i2cdetct是i2c-tool包中的一个工具。

i2c设备文件是字符设备,主设备号是89,次设备号的分配如上所述。设备文件名通常被

规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...)i2c设备文件是字符设备,

主设备号是

89,次设备号的分配如上所述。设备文件名通常被规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...).所有256个次设备号都保留给i2c使用。

C example

=========

假定你要在你的C应用程序中访问i2c适配器。第一件事情就是包含头文件

"#include

"。注意,存在两个"i2c-dev.h"文件: 一个属于Linux kernel,用于

内核驱动中;一个由i2c-tools发布,用于用户程序。显然,这里需要使用第二个

i2c-dev.h文件。

现在,你需要确定访问哪个适配器。你需要通过查看/sys/class/i2c-dev/或者运行

"i2cdetect -l"确定。适配器号时常是动态分配的,你无法预先假定某个值。因为它们甚

i2c驱动传入probe的参数解释

i2c驱动传入probe的参数解释

I2C驱动传入probe的参数解释

在进行I2C设备的驱动开发过程中,常常会涉及到I2C驱动的probe 函数。probe函数是Linux内核驱动中的一种特殊函数,它在驱动被加载并且设备被检测到时被调用,用于初始化设备并注册设备驱动。在编写I2C驱动的probe函数时,通常需要传入不同的参数进行配置和初始化。本文将对I2C驱动传入probe的参数进行解释和说明,帮助读者更好地理解和使用I2C设备驱动。

1. struct i2c_client *client

在I2C驱动的probe函数中,通常需要传入一个指向struct

i2c_client结构体的指针作为参数。这个结构体是I2C设备在内核中的表示,包含了I2C设备的位置区域、总线信息、驱动信息等。通过这个参数,我们可以获取I2C设备的各种信息,并进行相应的初始化和配置。

2. const struct i2c_device_id *id

另一个常见的参数是一个指向const struct i2c_device_id结构体的指针,用于指定要注册的设备驱动的ID信息。这个结构体中通常包含了设备的厂商ID、设备类型、设备名称等信息,用于匹配加载指定的设备驱动。在probe函数中,我们可以使用这个参数来判断当前检测到

的I2C设备是否匹配当前的驱动,从而进行相应的初始化和注册操作。

3. int (*probe)(struct i2c_client *client, const struct i2c_device_id *id)

最后一个重要的参数是probe函数本身。这个参数是一个函数指针,用于指定实际的probe函数的位置区域。在probe函数中,我们可以根据传入的client和id参数,进行设备的初始化、资源的申请、注册设备驱动等操作。通过这个函数指针参数,内核可以在加载驱动并检

Linux2.6内核i2c驱动架构

Linux2.6内核i2c驱动架构

二. 驱动相关知识介绍
(3)支持热插拔 ) 越来越多的计算机设备可被动态的热插拔了, 越来越多的计算机设备可被动态的热插拔了,也 就是说,外围设备可根据用户的需要安装与卸载。 就是说,外围设备可根据用户的需要安装与卸载。内 核中的热插拔机制可以处理热插拔设备, 核中的热插拔机制可以处理热插拔设备,特别是能够 与用户空间进行关于插拔设备的通信, 与用户空间进行关于插拔设备的通信,而这种机制也 是通过设备模型管理的。 是通过设备模型管理的。
二. 驱动相关知识介绍
总线、 总线、Fra Baidu bibliotek备和驱动程序
总线是处理器与一个或者多个设备之间的通道。在设备模型中,所有的 设备通过总线相连。甚至是那些内部的虚拟“平台”总线。总线可以相互插 入,比如一个USB控制器通常是一个PCI设备。设备模型展示了总线和它们 所控制的设备之间的实际连接。 of_platform总线(平台总线)是2.6 kernel中引入的正对Linux PowerPC CPU SPI I2C 的一种虚拟总线,主要用来管理CPU的片上资源,例如串口、SPI、I2C、网 卡。 设备连接某条物理或者虚拟总线上的对象。可能是真正物理对象,也 可能是虚拟对象。例如U盘就是一个物理对象,pty设备就是一个虚拟的对象 。 驱动是用来和设备通信的软件程序。驱动可以从设备中获取数据,也 可以把相应数据发给设备进行处理。驱动一般都是和具体操作系统以及具体 硬件相关的。

linux 应用访问i2c设备原理

linux 应用访问i2c设备原理

linux 应用访问i2c设备原理

Linux是一个开放源代码的操作系统内核,支持许多硬件设备的驱动程序。其中一种常用的硬件接口是I2C(Inter-Integrated Circuit)总线。I2C总线允许多个设备通过共享同一组线路进行通信,这些设备可以是传感器、存储器、转换器等外围设备。

Linux提供了一种访问I2C设备的机制,通过此机制,应用程序可以与I2C设备进行通信。在本文中,将介绍Linux应用程序访问I2C

设备的原理及步骤。

1.硬件连接:

首先,需要将I2C设备连接到主机上。I2C总线由两根线路组成,即SDA(Serial Data Line)和SCL(Serial Clock Line)。SDA用于传输数据,SCL用于提供时钟信号。I2C设备通常具有一个I2C地址,

用于在总线上识别不同的设备。

2. Linux内核驱动:

Linux内核提供了I2C总线的驱动程序,用于与I2C设备进行通信。通常,这些驱动程序已经包含在内核中,不需要单独安装。但是,可

能需要通过编译内核时打开相应的配置选项来启用I2C支持。

3. I2C设备驱动:

每个I2C设备都需要一个设备驱动程序,用于与应用程序进行交互。这些驱动程序通常由设备制造商提供,也有一些常见的驱动程序

包含在Linux内核中。设备驱动程序将设备上的读写操作映射到I2C

总线上的读写操作。

4.用户空间库:

为了更方便地编写应用程序,Linux提供了一些用户空间库,用于访问I2C设备。其中最常用的库是libi2c-dev,它提供了一组API函数,可以通过文件描述符进行I2C通信。此库通常已经安装在Linux

I2C驱动架构

I2C驱动架构

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设备驱动介绍

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设备驱动程序。驱动程序需要实现上述提到的功能,并且根据设备的特点进行相应的适配和优化。

i2c_register_driver函数详解

i2c_register_driver函数详解

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_driver

struct i2c_driver是一个定义I2C驱动程序的结构体,包含了以下重要的成员:

- .driver:指向内核的struct device_driver结构体,用于描述驱动程序的信息,如名称、文件操作方法等。

- .probe:指向I2C设备探测函数的指针,用于在设备连接时进行初

始化和配置。

- .remove:指向I2C设备移除函数的指针,用于在设备断开连接时

进行清理和释放资源。

- .id_table:指向I2C设备ID表的指针,用于匹配设备和驱动程序。

linux i2c注册流程

linux i2c注册流程

linux i2c注册流程

Linux I2C注册流程

I2C(Inter-Integrated Circuit)是一种串行通信协议,用于连接在计算机系统中的多个外部设备。在Linux系统中,I2C总线的设备驱动程序通过I2C核心子系统进行注册和管理。本文将介绍Linux I2C注册流程的具体步骤,帮助读者了解Linux系统中I2C设备的注册过程。

1. 硬件连接和配置

在开始之前,首先需要进行硬件连接以及相关I2C控制器的配置。通常,I2C总线上的每个设备都有一个唯一的7位或10位地址。在Linux系统中,I2C控制器通过设备树(Device Tree)或Platform数据结构进行配置。根据硬件和芯片特定的要求,需要指定控制器的一些参数,例如时钟频率、地址模式等。

2. I2C核心子系统

I2C核心子系统是Linux内核中用于管理I2C设备的模块,包含了驱动程序和各种API函数。它将I2C设备的操作进行了抽象,并提供了一组统一的接口供驱动程序使用。I2C核心的代码位于"drivers/i2c"目录下。

3. I2C驱动程序

I2C设备驱动程序是一种与特定硬件相关的内核模块,用于与I2C设备进

行通信和控制。驱动程序的代码一般位于"drivers/i2c/busses"目录下。Linux内核已经提供了一些通用的I2C驱动程序供使用,例如“i2c-gpio”用于模拟I2C总线。

4. I2C设备结构体

在编写自定义I2C驱动程序之前,需要定义一个I2C设备结构体。该结构体用于描述设备的各种属性,包括设备的名称、地址、信号模式以及设备特定的配置等。通常可以基于设备树或Platform数据结构进行初始化。

28.Linux-IIC驱动(详解)

28.Linux-IIC驱动(详解)

28.Linux-IIC驱动(详解)

上⼀节我们学习了:

IIC接⼝下的24C02 驱动分析:

接下来本节, 学习Linux下如何利⽤linux下I2C驱动体系结构来操作24C02

1. I2C体系结构分析

1.1⾸先进⼊linux内核的driver/i2c⽬录下,如下图所⽰:

其中重要的⽂件介绍如下:

1)algos⽂件夹(algorithms)

⾥⾯保存I2C的通信⽅⾯的算法

2)busses⽂件夹

⾥⾯保存I2C总线驱动相关的⽂件,⽐如i2c-omap.c、 i2c-versatile.c、 i2c-s3c2410.c等。

3)chips⽂件夹

⾥⾯保存I2C设备驱动相关的⽂件,如下图所⽰,⽐如m41t00,就是RTC实时钟

4) i2c-core.c

这个⽂件实现了I2C核⼼的功能(I2C总线的初始化、注册和适配器添加和注销等相关⼯作)以及/proc/bus/i2c*接⼝。

5) i2c-dev.c

提供了通⽤的read()、 write()和ioctl()等接⼝,实现了I2C适配器设备⽂件的功能,其中I2C设备的主设备号都为89,次设备号为0~255。应⽤层可以借⽤这些接⼝访问挂接在适配器上的I2C设备的存储空间或寄存器,并控制I2C设备的⼯作⽅式

显然,它和前⼏次驱动类似, I2C也分为总线驱动和设备驱动,总线就是协议相关的,它知道如何收发数据,但不知道数据含义,设备驱动却知道数据含义

1.2 I2C驱动架构,如下图所⽰:

如上图所⽰,每⼀条I2C对应⼀个adapter适配器,在kernel中, adapter适配器是通过struct adapter结构体定义,主要是通过i2c core层将i2c设备与i2c adapter关联起来.

linux i2c协议类型

linux i2c协议类型

在Linux 操作系统中,I2C(Inter-Intergrated Circuit)是一种常用的串行通信协议,用于在电路板上的集成电路之间进行数据传输。Linux 提供了I2C 的相关功能和驱动程序,以便在系统中使用和控制I2C 设备。下面是一些常见的Linux I2C 协议类型:

1. 标准模式(Standard Mode): 标准模式是I2C 总线上最常见的协议类型,它支持最低传输速率为100 Kbps,每个数据字节由8 位数据位和1 位ACK(应答)位组成。

2. 快速模式(Fast Mode): 快速模式是一种高速的I2C 通信协议,其最高传输速率为400 Kbps。每个数据字节由8 位数据位和1 位ACK 位组成。

3. 快速模式加(Fast Mode Plus): 快速模式加是快速模式的扩展,增加了一个叫做Tlow(Fm+) 的参数,可以在某些硬件平台上支持更高的传输速率,最高可达到1 Mbps。

4. 高速模式(High-Speed Mode): 高速模式是一种更快的I2C 通信协议,其最高传输速率可以达到3.4 Mbps。高速模式在物理层上使用了不同的电气特性和数据传输方式,以支持更高的速率。

5. 低速模式(Low-Speed Mode): 低速模式是一种较慢的I2C 通信协议,最低传输速率为10 Kbps。低速模式主要用于通信距离较短或更为噪声敏感的应用场景。

这些不同的协议类型允许根据具体的应用需要选择适当的速率和性能。在Linux 中,可以借助I2C 子系统的API 和驱动程序来实现对I2C 设备的访问和控制。通过适当的配置和编程,可以在Linux 系统中轻松地使用和操作I2C 设备。

Linux 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)展开就可以得到:

LinuxI2C驱动整理(以RK3399Pro+Kernel4.4为例)

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";

LinuxI2C驱动框架

LinuxI2C驱动框架

LinuxI2C驱动框架

⼀、I2C总线概述

I2C是由Philips公司开发的⼀种简单的、双向同步串⾏总线,它只需要两条线即可在连接于总线上的器件之间传送信息,其硬件连接框图如下所⽰:

SCL:串⾏时钟线,数据传输过程中⽤于同步的时钟信号,低电平时允许SDA线上数据改变。

SDA:串⾏数据线,在时钟信号作⽤下,数据按位在数据线上进⾏传输。

I2C总线上的设备之间通信都要遵从I2C总线协议,I2C总线由起始信号、停⽌信号、应答信号、⾮应答信号组成。

起始信号:当时钟线SCL为⾼期间,数据线SDA由⾼到低的跳变。

停⽌信号:当时钟线SCL为⾼期间,数据线SDA由低到⾼的跳变。

应答信号(ACK):应答位为低电平时,规定为有效应答位,表⽰接收器已经成功接收到该字节。

⾮应答信号(NACK):应答位为⾼电平时,规定为⾮应答位,⼀般表⽰接收器接收该字节没有成功。

挂接在同⼀条I2C总线上的设备都要⾃⼰的物理地址,I2C主机控制器在和设备通信前需要先发送设备的地址,设备接收到总线上传过来的地址,看是否是⾃⼰的地址,如果是产⽣后续的应答。

主机控制器和设备通信⼀般是由⼀个起始信号开始和⼀个停⽌信号结束,地址信息⼀般是7bit,发送地址的最后⼀位代表数据传输的⽅向,1表⽰是读,0表⽰写操作,其发送时序⼀般如下所⽰:

主机发送数据

主机读取数据

前⾯对I2C总线的⼀些基本概念和I2C协议的做了简单的介绍,下⾯开始来分析Linux内核的I2C驱动框架,看看内核中如何实现对I2C设备的⽀持。

⼆、Linux内核I2C驱动

1、⼏个重要对象

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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设备。

第二种:为I2C设备独立编写一个设备驱动

注意:第二种方法不能用设备提供的I2C-dev.c

5、I2C系统下的文件架构

在linux下driver下面有个I2C目录,在I2C目录下包含以下文件和文件夹

1)I2C-core.c 这个文件实现I2C核心功能以及/proc/bus/I2C*接口

2)I2C-dev.c 实现I2C适配器设备文件的功能,每个I2C适配器被分配一个设备,通过

适配器访问设备的时候,主设备号是89,此设备号是0-255. I2C-dev.c并没有针对特定设备而设计,只提供了read() write()和ioctl()等接口,应用层可以通过这些接口访问挂在适配器上的I2C设备存储空间和寄存器,并控制I2C设备的工作方式。

3)Chips 这个文件下面包含特定的I2C设备驱动。

4)Busses 这个文件包含一些I2C总线驱动。

5)Algos文件夹下实现了I2C总线适配器的algorithm

6、重要结构体

1)在内核中的I2C.h这个头文件中对I2C_driver;I2C_client;I2C_adapter和I2C_algorithm 这个四个结构体进行了定义。理解这4个结构体的作用十分关键。

i2c_adapter结构体

struct i2c_adapter {

struct module *owner; //所属模块

unsigned int id; //algorithm的类型,定义于i2c-id.h,

unsigned int class;

const struct i2c_algorithm *algo; //总线通信方法结构体指针

void *algo_data;//algorithm数据

struct rt_mutex bus_lock; //控制并发访问的自旋锁

int timeout;

int retries; //重试次数

struct device dev; //适配器设备

int nr;

char name[48]; //适配器名称

struct completion dev_released; //用于同步

struct list_head userspace_clients; //client链表头

};

I2c_algorithm结构体

struct i2c_algorithm {

int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);//I2C传输函数指针

int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union

i2c_smbus_data *data);//smbus传输函数指针

u32 (*functionality) (struct i2c_adapter *);//返回适配器支持的功能

};

SMbus大部分基于I2C总线规范,SMbus不需要增加额外引脚。与I2C总线相比,SMbus 增加了一些新的功能特性,在访问时序也有

一定的差异。

i2c_driver结构体

struct i2c_driver {

unsigned int class;

int (*attach_adapter)(struct i2c_adapter *);//依附i2c_adapter函数指针

int (*detach_adapter)(struct i2c_adapter *);//脱离i2c_adapter函数指针

int (*probe)(struct i2c_client *, const struct i2c_device_id *);

int (*remove)(struct i2c_client *);

void (*shutdown)(struct i2c_client *);

int (*suspend)(struct i2c_client *, pm_message_t mesg);

int (*resume)(struct i2c_client *);

void (*alert)(struct i2c_client *, unsigned int data);

int (*command)(struct i2c_client *client, unsigned int cmd, void*arg);//命令列表

struct device_driver driver;

const struct i2c_device_id *id_table;//该驱动所支持的设备ID表

int (*detect)(struct i2c_client *, struct i2c_board_info *);

const unsigned short *address_list;

struct list_head clients;

};

i2c_client结构体

struct i2c_client {

unsigned short flags;//标志

unsigned short addr; //低7位为芯片地址

char name[I2C_NAME_SIZE];//设备名称

struct i2c_adapter *adapter;//依附的i2c_adapter

struct i2c_driver *driver;//依附的i2c_driver

struct device dev;//设备结构体

int irq;//设备所使用的结构体

struct list_head detected;//链表头

};

2)各结构体的作用和他们之间的关系

i.I2C_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个i2c

相关文档
最新文档