i2ctool i2cget读取16位地址的寄存器值的方法

这篇博客介绍了如何在ASUS设备上使用i2cdetect和i2cget等工具来检测和读取I2C总线上的设备。通过mmm命令编译并安装i2c-tools,然后利用这些工具列出I2C适配器和挂载点,并读取特定设备的寄存器内容。示例中展示了读取OV7251芯片ID的过程,强调了正确操作以避免对设备造成意外写入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ASUS的i2cdetect tool放在device/asus/Z00L/i2c-tools目录下,用mmm device/asus/Z00L/i2c-tools就会生成相应的bin文件,push到机台的system/bin文件目录下

root@ASUS_Z00L_63:/system/bin # ./i2cdetect  -l                                

i2c-0 i2c      MSM-I2C-v2-adapter              I2C adapter
i2c-4 i2c        MSM-I2C-v2-adapter               I2C adapter
i2c-5 i2c        MSM-I2C-v2-adapter               I2C adapter
i2c-6 i2c        MSM-I2C-v2-adapter               I2C adapter

root@ASUS_Z00L_63:/system/bin # ./i2cdetect  -y -r 0                           
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: UU -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
root@ASUS_Z00L_63:/system/bin # ./i2cdetect  -y -r 4                           
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
root@ASUS_Z00L_63:/system/bin # ./i2cdetect  -y -r 5                           
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
root@ASUS_Z00L_63:/system/bin # ./i2cdetect  -y -r 6                           
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

上面每一个 UU都是一个i2c设备的挂载点,对应的就是在这个bus上的slave address。

如果想要看某个设备里的register的内容则

1|root@ASUS_Z00L_63:/system/bin # ./i2cdump  -f -y 5 0x38                      
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: 57 50 19 19 19 70 01 05 0b 1e 00 01 00 00 00 00    WP???p????.?....
90: 00 89 00 00 00 00 09 00 00 00 00 00 00 00 00 22    .?....?........"
a0: 01 0a 10 54 01 01 b1 01 61 01 08 00 00 6f 01 09    ???T????a??..o??
b0: 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 55    .?.............U
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
d0: 01 30 1a 00 ff 40 10 20 00 00 64 00 00 05 64 00    ?0?..@? ..d..?d.
e0: 6c 02 20 10 51 06 8a 00 00 0f 1c eb 08 00 00 00    l? ?Q??..????...
f0: ff ff ff ff ff ff ff ff ff ff ff ff 01 00 41 ff    ............?.A.


————————————————
版权声明:本文为CSDN博主「苏西守护者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013308744/article/details/50128651

 

 

///读16bit 地址/

NAME

i2cget - read from I2C/SMBus chip registers

 

SYNOPSIS

i2cget [-f] [-y] [-ai2cbus chip-address [data-address [mode]]
i2cget -V

 

DESCRIPTION

i2cget is a small helper program to read registers visible through the I2C bus (or SMBus).

 

OPTIONS

-V

Display the version and exit.

-f

Force access to the device even if it is already busy. By default, i2cget will refuse to access a device which is already under the control of a kernel driver. Using this flag is dangerous, it can seriously confuse the kernel driver in question. It can also cause i2cget to return an invalid value. So use at your own risk and only if you know what you're doing.

-y

Disable interactive mode. By default, i2cget will wait for a confirmation from the user before messing with the I2C bus. When this flag is used, it will perform the operation directly. This is mainly meant to be used in scripts. Use with caution.

-a

Allow using addresses between 0x00 - 0x07 and 0x78 - 0x7f. Not recommended.

There are two required options to i2cget. i2cbus indicates the number or name of the I2C bus to be scanned. This number should correspond to one of the busses listed by i2cdetect -lchip-address specifies the address of the chip on that bus, and is an integer between 0x08 and 0x77.

data-address specifies the address on that chip to read from, and is an integer between 0x00 and 0xFF. If omitted, the currently active register will be read (if that makes sense for the considered chip).

The mode parameter, if specified, is one of the letters bw or c, corresponding to a read byte data, a read word data or a write byte/read byte transaction, respectively. A p can also be appended to the mode parameter to enable PEC. If the mode parameter is omitted, i2cget defaults to a read byte data transaction, unless data-address is also omitted, in which case the default (and only valid) transaction is a single read byte.

 

WARNING

i2cget can be extremely dangerous if used improperly. I2C and SMBus are designed in such a way that an SMBus read transaction can be seen as a write transaction by certain chips. This is particularly true if setting mode to cp (write byte/read byte with PEC). Be extremely careful using this program.

 

EXAMPLES

Get the value of 8-bit register 0x11 of the I2C device at 7-bit address 0x2d on bus 1 (i2c-1), after user confirmation:

# i2cget 1 0x2d 0x11
 

Get the value of 16-bit register 0x00 of the I2C device at 7-bit address 0x48 on bus 1 (i2c-1), after user confirmation:

# i2cget 1 0x48 0x00 w
 

Set the internal pointer register of a 24C02 EEPROM at 7-bit address 0x50 on bus 9 (i2c-9) to 0x00, then read the first 2 bytes from that EEPROM:

# i2cset -y 9 0x50 0x00 ; i2cget -y 9 0x50 ; i2cget -y 9 0x50
 

This assumes that the device automatically increments its internal pointer register on every read, and supports read byte transactions (read without specifying the register address, "Receive Byte" in SMBus terminology.) Most EEPROM devices behave that way. Note that this is only safe as long as nobody else is accessing the I2C device at the same time. A safer approach would be to use a "Read Word" SMBus transaction instead, or an I2C Block Read transaction to read more than 2 bytes.

Set the internal pointer register of a 24C32 EEPROM at 7-bit address 0x53 on bus 9 (i2c-9) to 0x0000, then read the first 2 bytes from that EEPROM:

# i2cset -y 9 0x53 0x00 0x00 ; i2cget -y 9 0x53 ; i2cget -y 9 0x53
 

这里实际以读取ov7251的chip id 为例,实际操作如下:

1、查看我的7251挂载iic总线(实际是iic-2)及设备地址(实际读取是0x60)

[root@Pen-997:/]# i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --

根据数据手册可知:

#define CHIP_ID                0x007750
#define OV7251_REG_CHIP_ID        0x300a

首先 设置要读取的地址 0x300a

[root@YoudaoDictionaryPen-997:/]# i2cset -y -f 2 0x60 0x30 0x0a

然后读取两个字节的数据:

[root@Pen-997:/]# i2cget -y -f 2 0x60
0x77
[root@Pen-997:/]# i2cget -y -f 2 0x60
0x50

 

 

This again assumes that the device automatically increments its internal pointer register on every read, and supports read byte transactions. While the previous example was for a small EEPROM using 8-bit internal addressing, this example is for a larger EEPROM using 16-bit internal addressing. Beware that running this command on a small EEPROM using 8-bit internal addressing would actually write 0x00 to the first byte of that EEPROM. The safety concerns raised above still stand, however in this case there is no SMBus equivalent, so this is the only way to read data from a large EEPROM if your master isn't fully I2C capable. With a fully I2C capable master, you would use i2ctransfer to achieve the same in a safe and faster way.

 

BUGS

To report bugs or send fixes, please write to the Linux I2C mailing list <linux-i2c@vger.kernel.org> with Cc to the current maintainer: Jean Delvare <jdelvare@suse.de>.

 

SEE ALSO

i2cdetect(8)i2cdump(8)i2cset(8)i2ctransfer(8)

 

AUTHOR

Jean Delvare

This manual page was strongly inspired from those written by David Z Maze for i2cset.

October 2017
<think>好的,用户现在问的是如何在Linux I2C总线上读取一个8位寄存器。首先,我需要确定用户的使用场景。可能的情况是用户正在开发嵌入式系统或者驱动,需要与某个I2C设备通信,比如传感器、EEPROM或者其他外设。读取寄存器是常见的操作,用户可能遇到了问题,或者想确认正确的方法。 接下来,用户可能是开发者,具备一定的Linux驱动开发经验,但对具体的I2C操作不太熟悉。他们可能需要详细的步骤,包括用户空间和内核空间的方法,以及示例代码。用户可能希望了解不同的方法,比如使用sysfs接口、i2c-tools工具,或者在内核驱动中使用API。此外,用户可能关心错误处理和注意事项,比如地址对齐、并发访问和硬件连接问题。 我需要回顾Linux下I2C子系统的结构。用户空间常用的工具是i2c-tools,特别是i2cget命令,可以直接读取寄存器。另外,通过sysfs的文件操作也是一种方法,虽然可能不太直观。对于内核驱动,使用i2c_transfer函数或封装好的i2c_smbus_read_byte_data函数是关键。需要确保用户了解如何编写内核模块,并处理可能的错误情况。 然后,检查可能的陷阱。比如,有些设备可能需要先写入寄存器地址,再进行读取,也就是两次i2c_transfer操作。此外,I2C设备的地址是否正确,7位地址是否需要左移一位,以及时序问题都可能影响读取结果。用户可能遇到读取失败的情况,需要指导他们如何调试,比如检查i2cdetect确认设备是否存在,使用示波器检查信号完整性。 另外,用户可能想知道用户空间和内核空间方法的优缺点。用户空间方法适合快速测试和脚本操作,而内核驱动适合集成到系统中。需要提醒用户权限问题,比如使用i2c-tools可能需要root权限,或者将用户加入i2c组。 最后,总结步骤,提供示例代码和命令,并强调注意事项。确保回答结构清晰,分点说明,覆盖用户可能需要的各个方面,并预见到他们可能遇到的问题,提供解决方案。</think>--- ### Linux I2C读取8位寄存器方法详解 --- #### 一、基本原理 在Linux系统中,I2C设备通过内核子系统管理。读取寄存器的核心操作包含两个步骤: 1. **写入寄存器地址**(1字节) 2. **读取寄存器**(1字节) 整个过程通过**I2C SMBus协议**实现,时序如下: ``` Start → 设备地址(W) → 寄存器地址 → Restart → 设备地址(R) → 数据读取 → Stop ``` --- #### 二、用户空间读取方法(无需编写驱动) ##### 1. 使用i2c-tools工具包 ```bash # 安装工具 sudo apt install i2c-tools # 扫描I2C总线(示例总线号为1) i2cdetect -y 1 # 读取寄存器(总线1,设备地址0x50,寄存器地址0x00) i2cget -y 1 0x50 0x00 ``` *输出示例*:`0x3a`(返回的8位寄存器) ##### 2. 通过sysfs直接操作 ```bash # 写入寄存器地址 echo 0x00 > /sys/bus/i2c/devices/1-0050/address # 读取寄存器 cat /sys/bus/i2c/devices/1-0050/data ``` --- #### 三、内核驱动实现方法 ##### 1. 使用SMBus接口(推荐) ```c #include <linux/i2c.h> int read_reg(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } // 调用示例 u8 val = read_reg(client, 0x00); ``` ##### 2. 原始I2C传输 ```c struct i2c_msg msgs[2]; u8 reg_addr = 0x00; u8 buf; // 写入寄存器地址 msgs[0].addr = client->addr; msgs[0].flags = 0; // 写标志 msgs[0].len = 1; msgs[0].buf = &reg_addr; // 读取数据 msgs[1].addr = client->addr; msgs[1].flags = I2C_M_RD; // 读标志 msgs[1].len = 1; msgs[1].buf = &buf; if (i2c_transfer(client->adapter, msgs, 2) != 2) { dev_err(&client->dev, "I2C read error\n"); return -EIO; } ``` --- #### 四、关键注意事项 1. **地址对齐** - 7位设备地址需左移1位(例如实际地址0x50对应操作地址0xA0) - 验证设备是否响应:`i2cdetect -y <bus_num>` 2. **并发访问** ```c mutex_lock(&i2c_lock); val = i2c_smbus_read_byte_data(client, reg); mutex_unlock(&i2c_lock); ``` 3. **错误处理** - 检查返回:负数表示错误代码(如-ENXIO表示设备无响应) - 常见错误代码: | 错误码 | 含义 | |--------------|--------------------------| | -ENODEV | 设备未注册 | | -ETIMEDOUT | 总线超时 | | -EIO | 数据传输错误 | 4. **硬件连接验证** - 使用示波器检查SCL/SDA波形 - 确认上拉电阻(标准I2C要求4.7kΩ@3.3V) --- #### 五、调试技巧 1. 启用I2C调试日志: ```bash echo 1 > /sys/module/i2c_core/parameters/debug dmesg -w | grep i2c ``` 2. 使用逻辑分析仪抓包(如Saleae Logic Pro 16) --- #### 六、性能优化 ```c // 批量读取连续寄存器 int i2c_smbus_read_block_data(struct i2c_client *client, u8 reg, u8 *values); ``` --- 通过以上方法,可稳定实现I2C寄存器读取操作。对于高频访问场景(如传感器数据采集),建议采用内核驱动方式并启用DMA传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值