linux i2c framework(6) -- I2C tools

  • 了解linux i2c-tools

1.Introduction

  i2c-tools工具是一个专门调试i2c的,开源,可获取挂载的设备及设备地址,还可以在对应的设备指定寄存器设置值或者获取值等功能。

1.1.下载i2c-tools,交叉编译

  从https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/下载i2c-tools,解压,修改Makefile,保存退出,直接make,进行编译。

CROSS_COMPILE :=xxx/arm-linux/gnueabihf-
CC := $(CROSS_COMPILE)gcc

  编译之后,在tools目录生成可执行文件i2cdetect, i2cdump, i2cget, i2cset,在lib目录生成libi2c.so.0.1.1,将这些文件push到android 设备。测试过程中发现执行 i2cdetect命令时,会出现报错,如下所示,解决方法参考如下即可。

[root@test]# ls -l
total 256
-rwxrwxr-x    1 1008     1008         23080 Jan  1 00:06 i2cdetect
-rwxrwxr-x    1 1008     1008         23384 Jan  1 00:06 i2cdump
-rwxrwxr-x    1 1008     1008         23132 Jan  1 00:06 i2cget
-rwxrwxr-x    1 1008     1008         23428 Jan  1 00:06 i2cset
-rwxrwxr-x    1 1008     1008         23024 Jan  1 00:06 i2ctransfer
-rwxrwxr-x    1 1008     1008          9224 Jan  1 00:06 libi2c.so.0.1.1

[root@test]# ./i2cdetect 
./i2cdetect: error while loading shared libraries: libi2c.so.0: cannot open shared object file: No such file or directory

解决方法:创建软连接
[root@ test]# ln -s libi2c.so.0.1.1 libi2c.so.0   

2.命令

2.1. i2cdetect

i2cdetect [-y] [-a] [-q|-r] i2cbus [first last]
i2cdetect -F i2cbus
i2cdetect -V
i2cdetect -l

  i2cdetect is a userspace program to scan an I2C bus for devices. It outputs a table with the list of detected devices on the specified bus. i2cbus indicates the number or name of the I2C bus to be scanned, and should correspond to one of the busses listed by i2cdetect -l. The optional parameters first and last restrict the scanning range (default: from 0x03 to 0x77).

  i2cdetect can also be used to query the functionalities of an I2C bus (see option -F.)

Interpreting the Output
  Each cell in the output table will contain one of the following symbols:

  • “–”. The address was probed but no chip answered.
  • “UU”. Probing was skipped, because this address is currently in use by a driver. This strongly suggests that there is a chip at this address.
  • An address number in hexadecimal, e.g. “2d” or “4e”. A chip was found at this address.

Options

  • -y
    Disable interactive mode. By default, i2cdetect 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.

  • -a
    Force scanning of non-regular addresses. Not recommended.

  • -q
    Use SMBus “quick write” commands for probing (by default, the command used is the one believed to be the safest for each address). Not recommended. This is known to corrupt the Atmel AT24RF08 EEPROM found on many IBM Thinkpad laptops.

  • -r
    Use SMBus “read byte” commands for probing (by default, the command used is the one believed to be the safest for each address). Not recommended. This is known to lock SMBus on various write-only chips (most notably clock chips at address 0x69).

  • -F
    Display the list of functionalities implemented by the adapter and exit.

  • -l
    Output a list of installed busses.

2.2.i2cdump

i2cdump [-f] [-r first-last] [-y] i2cbus address [mode [bank [bankreg]]]
i2cdump -V

  i2cdump is a small helper program to examine registers visible through the I2C bus.

Options

  • -f
    Force access to the device even if it is already busy. By default, i2cdump 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 i2cdump to return invalid results. So use at your own risk and only if you know what you’re doing.

  • -r first-last
    Limit the range of registers being accessed. This option is only available with modes b, w, c and W. For mode W, first must be even and last must be odd.

  • -y
    Disable interactive mode. By default, i2cdump 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.

2.3.i2cset

i2cset [-f] [-y] [-m mask] [-r] i2cbus chip-address data-address [value] … [mode]
i2cset -V

  i2cset is a small helper program to set registers visible through the I2C bus.

Options

  • -f
    Force access to the device even if it is already busy. By default, i2cset 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 i2cset to silently write to the wrong register. So use at your own risk and only if you know what you’re doing.
  • -y
    Disable interactive mode. By default, i2cset 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.
  • -m mask
    The mask parameter, if specified, describes which bits of value will be actually written to data-address. Bits set to 1 in the mask are taken from value, while bits set to 0 will be read from data-address and thus preserved by the operation. Please note that this parameter assumes that the read and write operations for the specified mode are symmetrical for the device you are accessing. This may or may not be the case, as neither I2C nor SMBus guarantees this.
  • -r
    Read back the value right after writing it, and compare the result with the value written. This used to be the default behavior. The same limitations apply as those of option -m.

2.4.i2cget

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

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

  • -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.

2.5.i2ctransfer

  一次性读写多个字节,i2ctransfer支持16位/32位寄存器的读写,i2cset和i2cget只能读取8位的寄存器。所以i2ctransfer可以替代i2cset和i2cget。一般寄存器都是8位地址的,i2cdump、i2cget、i2cset 也是设置读取8位的地址,如果一次超过8位,需要用 i2ctransfer。

  • -f
    Force access to the device even if it is already busy. By default, i2ctransfer 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 i2ctransfer to silently write to the wrong register. So use at your own risk and only if you know what you’re doing.

  • -y
    Disable interactive mode. By default, i2ctransfer 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.

  • -v
    Enable verbose output. It will print infos about all messages sent, i.e. not only for read messages but also for write messages.

  • -V
    Display the version and exit.

  • -a
    Allow using addresses between 0x00 - 0x02 and 0x78 - 0x7f. Not recommended.

"Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):\n"
"  # i2ctransfer 0 w1@0x50 0x64 r8\n"

## 从i2c 4号总线0x38设备的0x3a01寄存器开始读16个字节的数据,w2:表示寄存器0x3a01的长度为2个字节
i2ctransfer -y -f 4 w2@0x38 0x3a 0x01 r16
## 向i2c 4号总线0x38设备的0x3a01寄存器写0x10,w3:表示寄存器0x3a01和写入值0x10的长度为3字节
i2ctransfer -y -f 4 w3@0x38 0x3a 0x01 0x10

3.Debug i2c

  使用i2c-tools的命令i2cdetect , i2cdump. i2cget. i2cset,本质上是在userspace操作i2c,这就需要内核的支持,即在/dev下有i2c-x 的字符设备节点存在(kernel/i2c/i2c-dev.c)。编译内核添加:

CONFIG_I2C_CHARDEV=y

相关测试命令:

1)./i2cdetect -l ===> 列出一共有几个 i2c Bus

2)./i2cdetect -r -y 1 ===> 列出 Bus 1上的所有Device
如下所示,I2C Bus1上,有4個Device,位置分別在 0x37, 0x4a, 0x4b, 0x50在这里插入图片描述
Note:UU表示该设备在driver中被使用。

3)./i2cdump -f -y 1 0x34 w ===> 列出 i2c-1 的 Device 0x50的 Register值(w: word读)

./i2cdump -f -y 1 0x34 w                                                                                                                                              
     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f
00: 2100 0000 8888 0606 0000 0000 0000 0000
08: 0000 0000 0000 0000 0000 0083 0000 0606
10: 0808 0000 0000 0000 0000 0000 0000 0000
18: 0000 afaf afaf 000c afaf 2f2f 0000 0000
20: 0000 0000 0000 0000 0000 0000 0000 6078

Note:如上所示0x27读到的值为:0x7860

4)./i2cset -y 1 0x34 0x2a 0x05 ===> 设置i2c-1上0x34器件的0x2a寄存器值为0x05
或者./i2cset -y 1 0x34 0x2a 0x05 w ===> 设置i2c-1上0x34器件的0x2a寄存器值为0x05

5)./i2cget -f -y 1 0x34 0x2a ==>读取i2c-1上0x34器件的0x2a寄存器值
或者./i2cget -f -y 1 0x34 0x2a w ==>读取i2c-1上0x34器件的0x2a寄存器值(w:word读)

[root@xxx test]# ./i2cget -y 1 0x34 0x2a 
[ 1862.833301] i2c i2c-1: master_xfer[0] W, addr=0x34, len=1
[ 1862.849038] i2c i2c-1: master_xfer[1] R, addr=0x34, len=1
0x05
[root@xxx test]# ./i2cget -y 1 0x34 0x2a w
[ 1866.914180] i2c i2c-1: master_xfer[0] W, addr=0x34, len=1
[ 1866.932165] i2c i2c-1: master_xfer[1] R, addr=0x34, len=2
0x0005

测试如下:(设备地址为0x34)

1.[root@ test]# ./i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
50: [  168.375419] i2c i2c-1: ioctl, cmd=0x703, arg=0x50
[  168.384297] i2c i2c-1: ioctl, cmd=0x720, arg=0xbeffac24
[  168.393030] albert:i2c_transfer,num=1
[  168.400218] i2c i2c-1: master_xfer[0] R, addr=0x50, len=1
[  168.409344] mhxxx-i2c d4010c00.i2c: mh1908_i2c_xfer: msgs: 1
[  168.418778] mhxxx-i2c d4010c00.i2c: Doing read 1 bytes to 0x50 - 1 of 1 messages
[  168.430522] i2c_read_data: 
[  168.431289]  0x80
[  168.435444] 

[root@ test]# ./i2cset -f -y 1 0x34 0x30 10
[  612.067028] albert:i2cdev_open,minor=1
[  612.076711] i2c i2c-1: ioctl, cmd=0x705, arg=0xbea56c68
[  612.085909] i2c i2c-1: ioctl, cmd=0x706, arg=0x34
[  612.094917] i2c i2c-1: ioctl, cmd=0x720, arg=0xbea56bdc
[  612.103927] albert:i2c_transfer,num=1
[  612.109315] i2c i2c-1: master_xfer[0] W, addr=0x34, len=2

[root@ test]# ./i2cget  -y 1 0x34 0x30
albert:main,i2cbus=1,flags=1
albert:main,i2cbus=1,argv[flags+2]=0x34,all_addrs=0
albert:main,address=52
[  616.699691] albert:i2cdev_open,minor=1
[  616.718629] i2c i2c-1: ioctl, cmd=0x705, arg=0xbedd7c98
[  616.733400] i2c i2c-1: ioctl, cmd=0x703, arg=0x34
albert:main,size =2,filename=/dev/i2c-1[  616.746687] i2c i2c-1: ioctl, cmd=0x720, arg=0xbedd7c2c

[  616.756755] albert:i2c_transfer,num=2
[  616.764043] i2c i2c-1: master_xfer[0] W, addr=0x34, len=1
[  616.773015] i2c i2c-1: master_xfer[1] R, addr=0x34, len=1
0x0a

Note:报错如下

root@overo:~#./i2cget -y 1 0x34 0x2a
Error: Could not set address to 0x49: Device or resource busy 

解决方法:
root@overo:~#./i2cget -y -f 1 0x34 0x2a

-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 danger‐
ous, 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.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值