linux IIC子系统分析(一)——linux i2c 架构概述和主要的数据结构

(1)

IIC总线架构分析:

i2c设备驱动层组件(i2c-dev.c)

============================================================================

功能:

1.给用户提供调用接口

2.实现策略问题:它知道发什么数据,但是不知道怎么发数据

 

i2c核心层组件(i2c-core.c)

============================================================================

功能:

1.注册一根i2c总线

2.给驱动编程人员提供编程接口

 

i2c总线驱动层组件(i2c-s3c2410.c)

============================================================================

功能:

1.初始化硬件(初始化i2c控制器)

2.实现操作方法:(根据i2c操作时序进行控制i2c控制器实现数据接收/发送)它知道怎么去发送数据,但是不知道发什么数据。

 

I2C架构概述

Linux 的I2C体系架构分为3个组成部分:

(1)I2C核心:I2C核心提供了I2C总线驱动和总线设备注册,注销,通信方法。还提供了与适配器相关的代码以及探测代码等。

(2)I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器驱动的实现。(IIC使用的是平台设备驱动模型)

(3)I2C设备驱动:I2C设备驱动是对设备端的实现(客户驱动),比如EEPROM设备。

 

 

Hardware 是我们的硬件设备,调试设备的时候我们经常在这用示波器来跟踪I2C通讯波形。

根据I2C架构概述的介绍,可以知道:

I2C核心:I2C核心层

I2C总线驱动(platform bus):硬件实现控制层,访问抽象层

I2C设备驱动(device driver):driver层

注意:在我们linux I2C子系统中,有使用到平台设备驱动机制。使用平台设备驱动的主要目是:将硬件/平台相关的东西分离出来,以提高程序的可移植性。

 

 

(2)

i2c是很流行的串行半双工通信协议,主从架构。

linux 中有关于i2c子系统的实现支持,其和平台无关的,具体实现需要驱动工程师自己实现。

linux i2c中核心代码是i2c-core.c 其有i2c适配器、i2c算法、i2c驱动以及i2c设备注册、注销以及数据处理的实现。

i2c子系统各部分的关系:i2c适配器是设备,是i2c具体外设(外部或芯片内部)的抽象,i2c算法是i2c适配器的驱动,i2c设备是挂载到i2c外设的设备抽象,i2c驱动是i2c设备的驱动

 

 

(3)

主要数据结构

 

struct bus_type i2c_bus_type = {

.name = "i2c",

.match = i2c_device_match,

.probe = i2c_device_probe,

.remove = i2c_device_remove,

.shutdown = i2c_device_shutdown,

.pm = &i2c_device_pm_ops,

};

 

 

struct i2c_adapter //i2c适配器抽象(其实算上相关操作函数才是真正的抽象),代表i2c外设设备,其需要由相关的algorithms才能工作。

{

struct module *owner; 内核模块指针。

unsigned int class; 代表哪类设备,不需要具体class指针,只是标记是哪类设备,用来匹配用的。

const struct i2c_algorithm *algo; 其用来操作设备的算法,是其驱动,没有算法适配器无法工作。

void *algo_data; 算法用到的数据。

struct rt_mutex bus_lock; 实时互斥锁,用来防止优先级翻转的,是实时进程需要的锁。

int timeout; 操作超时时间。

int retries;

struct device dev; 设备驱动模型的代表。

int nr; 适配器号,即总线号,linux idr模块使用的,用来所以适配器其指针的。

char name[48]; 名称

struct completion dev_released; linux完成量

struct mutex userspace_clients_lock; 互斥量

struct list_head userspace_clients; 设备链表

}

#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) 通过设备地址找到相应的适配器地址。

 

 

struct i2c_algorithm //i2c算法即适配器驱动,是i2c通信协议的时序实现。

{

int (*master_xfer) 和外设的通信函数

int (*smbus_xfer) smbus协议通信函数

u32 (*functionality) (struct i2c_adapter *); 查询是否支持适配器

}

 

struct i2c_msg //i2c信息段:包含一包发送或接受数据的信息。

{

__u16 addr; i2c从设备地址,可以是7bit或10bit

__u16 flags i2c信息标志,代表地址长度 、读写数据等一些i2c协议标志

__u16 len; i2c消息长度*/

__u8 *buf; i2c消息指针

}

 

struct i2c_client //是挂载i2c外设上的设备抽象。

{

unsigned short flags i2c设备标志,用来表示设备的地址长度以及设备协议类型

unsigned short addr; 设备地址

char name[I2C_NAME_SIZE]; 名称

struct i2c_adapter *adapter; 所需适配器设备

struct i2c_driver *driver; 所匹配的设备驱动

struct device dev; 设备模型的设备代表

int irq; 设备所使用的中断后

struct list_head detected; i2c驱动中设备链表节点

}

 

struct i2c_driver //是i2c设备驱动的抽象

{

unsigned int class; 所属的类,和i2c适配器匹配

int (*attach_adapter) 以及废弃的函数,保持兼容

int (*probe)(struct i2c_client *, const struct i2c_device_id *); 驱动探测设备函数

int (*remove)(struct i2c_client *); 驱动移除设备函数

struct device_driver driver; 设备驱动模型中驱动代表

const struct i2c_device_id *id_table; i2c设备匹配表

int (*detect)(struct i2c_client *, struct i2c_board_info *); i2c设备检查函数,用来探测相关i2c设备

const unsigned short *address_list; i2c设备地址指针

struct list_head clients; i2c设备链表头,用来遍历驱动中设备

}

 

 

struct i2c_device_id //i2设备匹配表,i2c驱动用来匹配i2c设备的,

{

char name[I2C_NAME_SIZE]; i2c支持的设备名称

}

 

struct i2c_board_info //是静态创建i2c设备的模板,i2c设备分为静态创建和动态探测创建。

{

type: chip type, to initialize i2c_client.name 用来初始化设备名称

flags: to initialize i2c_client.flags 初始化设备标志

addr: stored in i2c_client.addr 初始化设备地址

platform_data: stored in i2c_client.dev.platform_data 初始化设备模型的平台相关数据

archdata: copied into i2c_client.dev.archdata 初始化设备模型子架构数据

of_node: pointer to OpenFirmware device node 用来构建设备树

irq: stored in i2c_client.irq

}

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值