(5)LinuxI2C驱动--浅谈LinuxI2C驱动架构

来源:互联网 发布:淘宝水果许可证怎么办 编辑:程序博客网 时间:2024/05/16 06:20

前面几个小结介绍了i2c总线的协议,又介绍了我们关注的eeprom的读写访问时序,还给出了两个访问eeprom的例子,我的目的是为了能更好的理解后面解析Linux下i2c驱动。

网上介绍Linux I2C驱动架构的文章非常的多,我把这些内容做了个归纳与简化,但是在搬出这些非常抽象的内容之前,我想先谈下我的理解。

如下图:
这里写图片描述
图中画了一个三星的s5pv210处理器,在处理器的里面集成了一个I2C适配器,外面有一个eeprom,通过SDA、SCL连接到cpu内集成的i2c适配器上。这样cpu就可以控制i2c适配器与外部的eeprom进行交互,也就是i2c适配器产生符合i2c协议的信号与eeprom进行通信。

所以对应到linux驱动下,控制i2c适配器有一套驱动代码,叫做i2c总线驱动,是用来产生i2c时序信号的,可以发送和接受数据;控制eeprom有一套驱动代码,叫做i2c设备驱动,这套驱动代码才是真正的对硬件eeprom控制。这也符合linux设备驱动分层的思想。而两套驱动代码之间有一个i2c核心,用来起到承上启下的作用。

以一个写eeprom为例,应用层发出写eeprom消息,i2c设备驱动接到消息,把消息封装成一个前文提到的i2c消息结构体,然后经i2c核心的调度把消息传给i2c适配器,i2c适配器就根据当前cpu的i2c总线协议把消息通过SDA和SCL发给了eeprom。

接下来开始搬运,,

1. I2C体系结构

linux的i2c体系结构分为三个组成部分。放张图加深理解。
这里写图片描述

(1)i2c核心

  • 提供了I2C总线驱动的注册、注销方法
  • 提供了I2C设备驱动的注册、注销方法
  • 提供了I2C通信方法(algorithm)
    对应代码:drivers/i2c/i2c-core.c

(2)i2c总线驱动

I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至集成在CPU内部(大多数微控制器都这么做)。适配器就是我们经常所说的控制器。

经由I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生开始位,停止位,读写周期,以及以从设备方式被读写,产生ACK等。

I2C总线驱动由i2c_adapter和i2c_algorithm来描述
对应代码:drivers/i2c/busses/i2c-s3c2410.c

(3)i2c设备驱动

I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备一般挂接在收CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。

I2C设备驱动程序由i2c_driver来描述

对应代码:drivers/misc/eeprom/at24.c

2. I2C重要数据结构

在include/linux/i2c.h中定义四个I2C驱动中重要的数据结构:i2c_adapter,i2c_algorithm,i2c_driver,i2c_client.

i2c_adapter对应物理上的一个i2c适配器

 struct i2c_adapter {     struct module *owner;//所属模块     unsigned int id;     unsigned int class;       /* classes to allow probing for */     const struct i2c_algorithm *algo; /* 总线通讯方法指针,需要其产生特定的访问周期信号 */     void *algo_data;     /* data fields that are valid for all devices   */     struct rt_mutex bus_lock;     int timeout;            /* in jiffies */     int retries;/* 重复次数 */     struct device dev;      /* the adapter device */     int nr;     char name[48];     struct completion dev_released;     struct list_head userspace_clients; };

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);     /* To determine what the adapter supports */     u32 (*functionality) (struct i2c_adapter *);//返回说支持的通讯协议 };

i2c_driver对应一套驱动方法

struct i2c_driver {     unsigned int class;     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;//该驱动所支持的i2c设备的ID表     int (*detect)(struct i2c_client *, struct i2c_board_info *);     const unsigned short *address_list;     struct list_head clients; };

i2c_client对应真实的物理设备,每个i2c设备都需要一个i2c_client来描述

 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)i2c_adapter与i2c_algorithm
一个I2C适配器需要i2c_algorithm中提供的通信函数来控制适配器上产生特定的访问周期。i2c_algorithm中的关键函数master_xfer()用于产生I2C访问周期需要的信号,以i2c_msg为单位。

 struct i2c_msg {     __u16 addr; /* slave address            */     __u16 flags;     __u16 len;      /* msg length               */     __u8 *buf;      /* pointer to msg data          */ };

(2)i2c_adapter与i2c_client
i2c_driver与i2c_client是一对多的关系,一个i2c_driver上可以支持多个同等类型的i2c_client。

(3)i2c_adapter与i2c_client
i2c_adapter与i2c_client的关系与I2C硬件体系中适配器和从设备的关系一致,i2c_client依附在i2c_adapter上。

0 0
原创粉丝点击