I2C bus
i2c_bus_type
用于表示 I2C 总线类型。bus_type
是 Linux 内核中用于表示总线类型的结构体,用于管理该类型总线上的设备。
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
};
-
.name
: 用于指定总线类型的名称。在这里,总线类型的名称被设置为 “i2c”,表示 I2C 总线类型。 -
.match
: 匹配设备与总线。 -
.probe
: 用于在设备与总线匹配成功后进行设备探测和初始化。 -
.remove
: 用于设备从总线上移除时的操作。 -
.shutdown
: 用于在系统关机时对设备进行关闭和清理操作。
I2C client
struct i2c_client
结构体用于表示 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 device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
i2c_slave_cb_t slave_cb; /* callback for slave mode */
#endif
};
-
unsigned short flags
: 存储一些标志位。 -
unsigned short addr
:表示 I2C 设备的地址。需要注意的是,I2C 设备地址通常只占用 7 个比特,而这里只使用了低 7 个比特来存储地址。 -
char name[I2C_NAME_SIZE]
:表示 I2C 设备的名称。I2C_NAME_SIZE
是一个宏定义,表示数组的大小。 -
struct i2c_adapter *adapter
: 一个指向struct i2c_adapter
结构体的指针,表示 I2C 设备所连接的适配器。 -
struct device dev
: 一个struct device
结构体,表示 I2C 设备对应的设备结构。 -
int irq
: 设备触发的中断请求(IRQ)。 -
struct list_head detected
: 链表头,用于存储已检测到的设备。 -
#if IS_ENABLED(CONFIG_I2C_SLAVE) ... #endif
: 这是一个条件编译块,用于在编译时根据是否启用了 I2C 从设备模式来条件地包含代码。在启用了 I2C 从设备模式时,这里会有一个i2c_slave_cb_t
类型的成员slave_cb
,它是一个用于从设备模式的回调函数。
I2C driver
struct i2c_driver
结构体用于表示 I2C 设备的驱动程序,并存储了与该驱动程序相关的各种函数指针、设备驱动结构、标识符表、设备检测回调函数等。
struct i2c_driver {
unsigned int class;
/* Notifies the driver that a new bus has appeared. You should avoid
* using this, it will be removed in a near future.
*/
int (*attach_adapter)(struct i2c_adapter *) __deprecated;
/* Standard driver model interfaces */
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
void (*shutdown)(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;
const struct i2c_device_id *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;
};
-
unsigned int class
: 表示驱动程序的类别。 -
int (*attach_adapter)(struct i2c_adapter *) __deprecated
: 通知驱动程序有新的总线出现。 -
int (*probe)(struct i2c_client *, const struct i2c_device_id *)
: 指向驱动程序的探测函数。当一个新的 I2C 设备与驱动程序匹配时,将调用该函数进行初始化和配置。 -
int (*remove)(struct i2c_client *)
: 表示驱动程序的移除函数。当一个已经存在的 I2C 设备与驱动程序不再匹配时,将调用该函数进行清理和释放资源。 -
void (*shutdown)(struct i2c_client *)
:表示驱动程序的关机函数。用于在系统关机时执行一些清理操作。 -
void (*alert)(struct i2c_client *, unsigned int data)
: 表示驱动程序的警报回调函数。该函数用于处理警报事件,例如 SMBus 警报协议中的警报。 -
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg)
:一个类似于 ioctl 的命令函数。用于执行特定的设备功能。 -
struct device_driver driver
: 一个struct device_driver
表示 I2C 设备驱动程序对应的设备驱动结构。 -
const struct i2c_device_id *id_table
: 一个指向struct i2c_device_id
结构体的常量指针,用于存储设备的标识符表。 -
int (*detect)(struct i2c_client *, struct i2c_board_info *)
: 设备检测回调函数,用于自动创建设备。 -
const unsigned short *address_list
: 无符号短整型数组的常量指针,用于存储设备的地址列表。 -
struct list_head clients
: 链表头,用于存储与该驱动程序关联的客户端列表。
I2C algorithm
在 Linux 内核中,每个 I2C 适配器通常都会有一个对应的 I2C 算法。struct i2c_algorithm
结构体用于表示 I2C 适配器的算法,并存储了与该适配器相关的各种函数指针,用于执行主设备传输、SMBus 传输和功能性查询。
struct i2c_algorithm {
/* If an adapter algorithm can't do I2C-level access, set master_xfer
to NULL. If an adapter algorithm can do SMBus access, set
smbus_xfer. If set to NULL, the SMBus protocol is simulated
using common I2C messages */
/* master_xfer should return the number of messages successfully
processed, or a negative value on error */
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
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 *);
#if IS_ENABLED(CONFIG_I2C_SLAVE)
int (*reg_slave)(struct i2c_client *client);
int (*unreg_slave)(struct i2c_client *client);
#endif
};
-
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
: I2C 主设备传输函数。该函数用于在总线上执行一系列 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 传输函数。该函数用于在总线上执行 SMBus 消息传输操作,根据给定的参数执行读取或写入操作,并返回操作结果。 -
u32 (*functionality)(struct i2c_adapter *)
: 指向功能性函数。该函数用于确定适配器支持的功能,并返回一个表示适配器功能的位掩码。 -
#if IS_ENABLED(CONFIG_I2C_SLAVE) ... #endif
: 条件编译块,用于在编译时根据是否启用了 I2C 从设备模式来条件地包含代码。在启用了 I2C 从设备模式时,这里会有两个函数指针reg_slave
和unreg_slave
,分别用于注册和注销从设备。
I2C adapter
struct i2c_adapter
结构体用于表示 I2C 适配器,并存储了与适配器相关的各种属性和状态信息,如适配器的拥有者、算法、超时时间、设备等。这些信息用于控制和管理 I2C 总线上的通信和操作。
struct i2c_adapter {
struct module *owner;
unsigned int class; /* classes to allow probing for */
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
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 mutex userspace_clients_lock;
struct list_head userspace_clients;
struct i2c_bus_recovery_info *bus_recovery_info;
const struct i2c_adapter_quirks *quirks;
};
-
struct module *owner
: 指向拥有该 I2C 适配器的内核模块的指针。 -
unsigned int class
: 指定可以进行探测的 I2C 设备类别。 -
const struct i2c_algorithm *algo
: 用于访问总线的 I2C 算法的指针。 -
void *algo_data
: 存储与 I2C 算法相关的数据。 -
struct rt_mutex bus_lock
: 用于保护 I2C 总线的互斥锁。 -
int timeout
: I2C 传输的超时时间,以 jiffies 为单位。 -
int retries
: 在传输期间发生错误时进行的重试次数。 -
struct device dev
: 表示适配器设备的结构体。 -
int nr
: 适配器的编号。 -
char name[48]
: 适配器的名称。 -
struct completion dev_released
: 设备释放的完成量。 -
struct mutex userspace_clients_lock
: 保护用户空间客户端列表的互斥锁。 -
struct list_head userspace_clients
: 用户空间客户端的链表。 -
struct i2c_bus_recovery_info *bus_recovery_info
: I2C 总线恢复信息的指针。 -
const struct i2c_adapter_quirks *quirks
: I2C 适配器的特殊属性的指针。
i2c_msg
struct i2c_msg
提供了在 Linux 内核中定义和组织 I2C 消息的方式,通过 I2C 总线与 I2C 设备进行通信。
struct i2c_msg {
__u16 addr; /* slave address */
__u16 flags;
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
-
__u16 addr
: I2C 设备的从设备地址。
-
__u16 flags
:保存了控制 I2C 消息行为的各种标志。 -
I2C_M_TEN
(0x0010):表示从设备地址为十位地址。通常,I2C 设备使用七位地址,但某些设备支持十位地址。 -
I2C_M_RD
(0x0001):表示消息是一个读操作,数据从从设备传输到主设备。 -
I2C_M_STOP
(0x8000):该标志与I2C_FUNC_PROTOCOL_MANGLING
特性一起使用。它表示主设备在消息之后应发送停止条件。 -
I2C_M_NOSTART
(0x4000):该标志与I2C_FUNC_NOSTART
特性一起使用。它表示主设备在此消息之前不应生成启动条件。 -
I2C_M_REV_DIR_ADDR
(0x2000):该标志与I2C_FUNC_PROTOCOL_MANGLING
特性一起使用。它表示在传输过程中地址字节应该被反转。 -
I2C_M_IGNORE_NAK
(0x1000):该标志与I2C_FUNC_PROTOCOL_MANGLING
特性一起使用。它表示如果从设备对数据字节发送 NAK(不应答),主设备应忽略它并继续传输。 -
I2C_M_NO_RD_ACK
(0x0800):该标志与I2C_FUNC_PROTOCOL_MANGLING
特性一起使用。它表示如果主设备接收到读传输的最后一个字节,它不应向从设备发送 ACK(应答)位。 -
I2C_M_RECV_LEN
(0x0400):该标志表示第一个接收到的字节将包含剩余数据的长度。这通常与I2C_M_RD
标志结合使用。 -
__u16 len
:表示消息的长度,指定主设备和从设备之间要传输的字节数。 -
__u8 *buf
:指向存储消息实际数据的数据缓冲区的指针。指针指向存储数据的内存位置。
i2c_board_info
i2c_board_info
描述一个I2C设备的板级信息,其中包括设备类型、地址、平台特定数据、体系结构数据、设备树节点、固件节点和中断号等。这些信息可以在设备驱动程序中使用,以便正确地配置和操作I2C设备。
struct i2c_board_info {
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
void *platform_data;
struct dev_archdata *archdata;
struct device_node *of_node;
struct fwnode_handle *fwnode;
int irq;
};
-
type
:表示I2C设备的类型名称。I2C_NAME_SIZE
是一个预定义的常量,表示数组的最大大小。 -
flags
:表示与设备相关的标志位。 -
addr
:表示I2C设备的地址。 -
platform_data
:表示特定于平台的数据。 -
archdata
:存储与设备体系结构相关的数据。 -
of_node
:表示与设备树相关的节点。这个字段用于与设备树中的节点进行关联。 -
fwnode
:表示固件节点(Firmware Node)相关的处理。固件节点是一种用于描述设备和其配置的数据结构,这个字段用于与固件节点进行关联。 -
irq
:表示与设备关联的中断号。这个字段用于指示设备在系统中使用的中断。
各结构体的作用与它们之间的关系
i2c_adapter与i2c_algorithm
i2c_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也非常关键,调用驱动中的发送接收函数需要填充该结构体
i2c_driver和i2c_client
i2c_driver对应一套驱动方法,其主要函数是attach_adapter()和detach_client()。i2c_client对应真实的i2c物理设备device,每个i2c设备都需要一个i2c_client来描述。i2c_driver与i2c_client的关系是一对多。一个i2c_driver上可以支持多个同等类型的i2c_client.文章来源:https://www.toymoban.com/news/detail-804910.html
i2c_adapter和i2c_client
i2c_adapter和i2c_client的关系与i2c硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adapter,由于一个适配器上可以连接多个i2c设备,所以i2c_adapter中包含依附于它的i2c_client的链表。文章来源地址https://www.toymoban.com/news/detail-804910.html
到了这里,关于【驱动】I2C驱动分析(三)-关键数据类型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!