I2C中重要结构体
在I2C(Inter-Integrated Circuit)通信中,涉及的主要结构体通常用于描述设备、消息和传输的配置。以下是一些常见的I2C结构体及其作用:
-
i2c_adapter
:- 这是一个代表I2C总线适配器的结构体。它包含与该I2C总线相关的各种信息和操作函数指针。
- 常见字段:
name
: 适配器的名称。algo
: 指向一个i2c_algorithm
结构体的指针,定义了适配器支持的操作集。nr
: 适配器的编号。owner
: 模块的所有者。
-
i2c_msg
:- 该结构体用于描述I2C消息,通常用于I2C传输过程中。
- 常见字段:
addr
: 设备的I2C地址。flags
: 用于设置读/写操作以及其他标志。len
: 数据缓冲区的长度。buf
: 指向数据缓冲区的指针。
-
i2c_client
:- 代表一个连接到I2C总线上的设备。
- 常见字段:
addr
: 设备的7位或10位I2C地址。adapter
: 指向设备所在的I2C适配器的指针。driver
: 指向设备驱动程序的指针。name
: 设备的名称。
-
i2c_driver
:- 代表I2C设备驱动程序。
- 常见字段:
driver
: 内嵌的驱动程序模型驱动结构体。id_table
: 支持的I2C设备ID表。probe
: 当匹配到设备时调用的函数。remove
: 当设备被移除时调用的函数。
-
i2c_algorithm
:- 定义I2C适配器所支持的操作。
- 常见字段:
master_xfer
: 主传输函数,用于执行读写操作。smbus_xfer
: 用于SMBus协议的传输函数。functionality
: 返回适配器支持的功能。
这些结构体是I2C子系统的核心组件,用于管理和描述I2C设备及其操作。它们在Linux内核的I2C子系统中非常重要,有助于实现I2C设备之间的通信和控制。
I2C数据传输
在Linux内核中,I2C数据传输是通过i2c-core
和i2c-bus
驱动来完成的。I2C设备通常使用以下机制进行数据传输:
i2c_msg
结构体: 描述单个I2C消息,包含设备地址、操作标志、数据长度和数据缓冲区。i2c_transfer
函数: 用于执行I2C传输。该函数使用i2c_msg
结构体描述的消息序列在I2C总线上传输数据。i2c_adapter
结构体: 代表I2C总线适配器,包含传输功能的实现。
i2c_transfer
函数
i2c_transfer
是 Linux 内核中用于执行 I2C 数据传输的核心函数。它负责通过 I2C 总线执行一系列的数据读写操作。以下是对 i2c_transfer
函数的详细介绍:
函数原型
int i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num);
参数说明
-
struct i2c_adapter *adapter
:- 描述 I2C 总线适配器的结构体。
- 这个适配器结构体通常由 I2C 驱动程序提供,并包含了与具体 I2C 总线相关的操作函数。
-
struct i2c_msg *msgs
:- 指向
i2c_msg
结构体数组的指针。i2c_msg
结构体描述了单个 I2C 消息的内容。 - 每个
i2c_msg
描述一个读写操作,包括目标设备的地址、读写标志、数据长度和数据缓冲区。
- 指向
-
int num
:- 要传输的消息数量,即
i2c_msg
数组中的元素个数。
- 要传输的消息数量,即
成员说明
-
addr
:- 目标 I2C 设备的地址,通常是一个 7 位或 10 位地址。
-
flags
:- 操作标志,定义了传输的方向和特性。
0
表示写操作。I2C_M_RD
表示读操作。
-
len
:- 数据的长度,以字节为单位。
-
buf
:- 数据缓冲区的指针,用于存放要发送或接收的数据。
函数返回值
- 成功: 返回成功传输的消息数量。通常应该等于传入的
num
。 - 失败: 返回负值,表示发生了错误。常见的错误码包括
-EINVAL
(无效参数)和-EIO
(I/O 错误)。
功能概述
-
传输消息:
i2c_transfer
函数会遍历msgs
数组中的所有i2c_msg
,并逐一通过指定的 I2C 适配器进行传输。
-
处理读写操作:
- 根据
i2c_msg
结构体中的flags
,确定是进行读操作还是写操作,并将数据从缓冲区发送到设备或从设备接收。
- 根据
-
同步执行:
- 所有消息按顺序执行,传输完成后函数返回。
示例代码
以下是一个使用 i2c_transfer
函数进行 I2C 数据读写的示例:
#include <linux/i2c.h>
#include <linux/module.h>static int i2c_read_write_example(struct i2c_client *client)
{struct i2c_msg msgs[2];unsigned char write_data[2] = {0x00, 0x01}; // 写入数据unsigned char read_data[2];int ret;// 配置写操作的消息msgs[0].addr = client->addr;msgs[0].flags = 0; // 写操作msgs[0].len = sizeof(write_data);msgs[0].buf = write_data;// 配置读操作的消息msgs[1].addr = client->addr;msgs[1].flags = I2C_M_RD; // 读操作msgs[1].len = sizeof(read_data);msgs[1].buf = read_data;// 执行 I2C 传输ret = i2c_transfer(client->adapter, msgs, 2);if (ret < 0) {pr_err("i2c_transfer failed: %d\n", ret);return ret;}pr_info("Data read: 0x%02x 0x%02x\n", read_data[0], read_data[1]);return 0;
}MODULE_LICENSE("GPL");
注意事项
-
I2C 总线配置:
- 确保 I2C 适配器和设备已经正确初始化,并且
i2c_client
指针有效。
- 确保 I2C 适配器和设备已经正确初始化,并且
-
消息顺序:
- 消息会按顺序执行。确保在发送写操作后再进行读操作。
-
错误处理:
- 检查返回值以处理错误,确保 I2C 操作的稳定性。
I2C-Tools使用
i2c-tools
是一个用于操作和调试 I2C 总线设备的工具集,常用于 Linux 系统中。它包括多个命令行工具,允许你与 I2C 总线上的设备进行交互,例如读取和写入寄存器,扫描总线等。
访问i2c 设备框架如下
常用工具和命令
以下是一些 i2c-tools
工具的简要介绍及其用法:
1. i2cdetect
-
功能: 探测 I2C 总线上连接的设备,列出所有活动的 I2C 地址。
-
用法:
i2cdetect -y <bus>
<bus>
是要扫描的 I2C 总线编号。例如,i2cdetect -y 1
扫描 I2C 总线 1。
-
示例:
sudo i2cdetect -y 1
输出格式:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2. i2cget
-
功能: 从 I2C 设备的寄存器读取数据。
-
用法:
i2cget -y <bus> <addr> <reg> [mode]
<bus>
是 I2C 总线编号。<addr>
是设备的 I2C 地址。<reg>
是寄存器地址。[mode]
是读取模式,例如b
(字节模式)或w
(字模式)。
-
示例:
sudo i2cget -y 1 0x50 0x00
读取地址
0x50
设备的寄存器0x00
的值。
3. i2cset
-
功能: 向 I2C 设备的寄存器写入数据。
-
用法:
i2cset -y <bus> <addr> <reg> <value> [mode]
<bus>
是 I2C 总线编号。<addr>
是设备的 I2C 地址。<reg>
是寄存器地址。<value>
是要写入的数据。[mode]
是写入模式,例如b
(字节模式)或w
(字模式)。
-
示例:
sudo i2cset -y 1 0x50 0x00 0xFF
向地址
0x50
设备的寄存器0x00
写入0xFF
。
4. i2cdump
-
功能: 显示 I2C 设备寄存器的完整内容。
-
用法:
i2cdump -y <bus> <addr> [mode]
<bus>
是 I2C 总线编号。<addr>
是设备的 I2C 地址。[mode]
是显示模式,例如b
(字节模式)或w
(字模式)。
-
示例:
sudo i2cdump -y 1 0x50
显示地址
0x50
设备的所有寄存器内容。
5. i2cmsg
-
功能: 提供低级访问 I2C 总线的功能,允许发送和接收 I2C 消息。
-
用法:
i2cmsg <bus> <addr> <cmd> [data...]
<bus>
是 I2C 总线编号。<addr>
是设备的 I2C 地址。<cmd>
是要发送的命令或数据。
-
示例:
i2cmsg 1 0x50 0x00