i2c总线

I2C(Inter Integrated Circuit,内部集成电路)总线

SDA/SCL

利用 I2C 接口在设备之间进行连接使用的两根线是 SDA(串行数据)和 SCL(串行时钟),它们都是开漏,通过一个上拉电阻接到正电源,因此在不使用的时候扔保持高电平。使用 I2C 总线进行通信的设备驱动这两根线变为低电平,在不使用的时候就让它们保持高电平。

I2c的地址格式

七位地址格式:一个地址字节由7个地址位和1个指示位组成。指示位是0表示一个写操作,是1就要求从机将数据发送回主机
十位地址格式:

i2c_adapter

i2c适配器, 即封装了i2c控制器的"控制信息"

struct i2c_adapter {
    struct module *owner;             // 所有者
    unsigned int id;                  
    unsigned int class;               // 该适配器支持的从设备的类型
    const struct i2c_algorithm *algo; // 该适配器与从设备的通信算法
    void *algo_data;                                    

    /* data fields that are valid for all devices    */
    struct rt_mutex bus_lock;

    int timeout;              // 超时时间
    int retries;
    struct device dev;        // 该适配器设备对应的device

    int nr;                   // 适配器的编号
    char name[48];            // 适配器的名字
    struct completion dev_released;

    struct list_head userspace_clients;  // 用来挂接与适配器匹配成功的从设备i2c_client的一个链表头
};

i2c_algorithm

i2c算法,适配器的通信算法,在构建i2c_adapter结构体变量的时候会去填充这个元素

i2c_client

描述一个i2c次设备,包括i2c_adapter 、i2c_driver ..

struct i2c_client {    //  用来描述一个i2c次设备
    unsigned short flags;        //  描述i2c次设备特性的标志位  
    unsigned short addr;         //  i2c 次设备的地址
                    
    char name[I2C_NAME_SIZE];    //  i2c次设备的名字
    struct i2c_adapter *adapter; //  指向与次设备匹配成功的适配器
    struct i2c_driver *driver;   //  指向与次设备匹配成功的设备驱动
    struct device dev;           //  该次设备对应的device
    int irq;                     //  次设备的中断引脚
    struct list_head detected;   //  作为一个链表节点挂接到与他匹配成功的i2c_driver 相应的链表头上                
};

i2c_driver

i2c设备驱动

struct i2c_driver {    // 代表一个i2c设备驱动
    unsigned int class;      // i2c设备驱动所支持的i2c设备的类型  

    /* Notifies the driver that a new bus has appeared or is about to be
     * removed. You should avoid using this if you can, it will probably
     * be removed in a near future.
     */
    int (*attach_adapter)(struct i2c_adapter *);   // 用来匹配适配器的函数 adapter
    int (*detach_adapter)(struct i2c_adapter *);                          

    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *, const struct i2c_device_id *); // 设备驱动层的probe函数
    int (*remove)(struct i2c_client *);                              // 设备驱动层卸载函数

    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *);
    int (*suspend)(struct i2c_client *, pm_message_t mesg);
    int (*resume)(struct i2c_client *);

    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     */
    void (*alert)(struct i2c_client *, unsigned int data);

    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

    struct device_driver driver;           //  该i2c设备驱动所对应的device_driver
    const struct i2c_device_id *id_table;  //  设备驱动层用来匹配设备的id_table   

    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list;    //  该设备驱动支持的所有次设备的地址数组
    struct list_head clients;              //  用来挂接与该i2c_driver匹配成功的i2c_client (次设备)的一个链表头
};

i2c_board_info

板级i2c设备信息

struct i2c_board_info {      //  这个结构体是用来描述板子上的一个i2c设备的信息
    char        type[I2C_NAME_SIZE];    //  i2c 设备的名字,用来初始化i2c_client.name
    unsigned short    flags;            //  用来初始化i2c_client.flags
    unsigned short    addr;             //  用来初始化 i2c_client.addr
    void        *platform_data;         //  用来初始化 i2c_client.dev.platform_data
    struct dev_archdata    *archdata;   //  用来初始化i2c_client.dev.archdata
#ifdef CONFIG_OF
    struct device_node *of_node;
#endif
    int        irq;                     //  用来初始化i2c_client.irq
};



struct i2c_devinfo {
    struct list_head    list;            // 作为一个链表节点挂接到__i2c_board_list 链表上去 
    int            busnum;               // 适配器的编号
    struct i2c_board_info    board_info; //  内置的i2c_board_info 结构体
};

i2c_msg

表示一个通信周期的数据相关的结构体

struct i2c_msg {
    __u16 addr;           /* slave address 设备地址 */
    __u16 flags;          /* 本次消息的标志位,就是下面的这些 */
#define I2C_M_TEN           0x0010    /* 设置了这个标志位表示从设备的地址是10bit */
#define I2C_M_RD            0x0001    /* 设置了这个标志位表示本次通信i2c控制器是处于接收方,否则就是发送方 */
#define I2C_M_NOSTART       0x4000    
#define I2C_M_REV_DIR_ADDR  0x2000    /* 设置这个标志位表示需要将读写标志位反转过来 */
#define I2C_M_IGNORE_NAK    0x1000    /* 设置这个标志意味当前i2c_msg忽略I2C器件的ack和nack信号 */
#define I2C_M_NO_RD_ACK     0x0800    /* 设置这个标志位表示在读操作中主机不用ACK */
#define I2C_M_RECV_LEN      0x0400    
    __u16 len;                        /* 数据长度 */
    __u8 *buf;                        /* 数据缓冲区指针 */
};
posted @ 2020-01-10 14:19  熊云港  阅读(274)  评论(0编辑  收藏  举报