深圳幻海软件技术有限公司 欢迎您!

手把手教你使用 i2c-tools

2023-02-28

i2c-tools简介在嵌入式开发中,有时候需要确认硬件是否正常连接,设备是否正常工作,设备的地址是多少等等,这里我们就需要使用一个用于测试I2C总线的工具:i2c-tools。i2c-tools工具是一个专门调试i2c的,开源,可获取挂载的设备及设备地址,还可以读写I2C设备寄存器。调试新的设备驱

i2c-tools 简介

在嵌入式开发中,有时候需要确认硬件是否正常连接,设备是否正常工作,设备的地址是多少等等,这里我们就需要使用一个用于测试 I2C 总线的工具:i2c-tools。

i2c-tools 工具是一个专门调试 i2c 的,开源,可获取挂载的设备及设备地址,还可以读写 I2C 设备寄存器。

调试新的设备驱动时,难免要反复修改寄存器,然后看结果现象。传统的做法是【修改驱动代码寄存器值->编译->下载->运行->看结果】,这一过程比较费时间,而每次需要改的可能只是 1 个 bit,这种情况下 i2c-tools 是神器。

i2c-tools 官方说明:

https://i2c.wiki.kernel.org/index.php/I2C_Tools
  • 1.

i2c-tools 下载网站

https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/
  • 1.

下载后在 Ubuntu 解压,如果想在开发板使用,就用自己板子对应的 gcc 工具链编译;如果想在 ubuntu 使用,就用 ubuntu 的默认的 gcc 编译即可。

编译会生成五个工具:i2cdetect、i2cset、i2cget、i2cdump、i2ctransfer,拷贝到开发板中就可以使用;也可以直接把 i2c-tools 源码包放到自己的源码中,直接编译进固件。

i2cdetect:用于扫描 i2c 总线上的设备,并显示地址
i2cset:设置i2c设备某个寄存器的值
i2cget:读取i2c设备某个寄存器的值
i2cdump:读取某个i2c设备所有寄存器的值
i2ctransfer:一次性读写多个字节
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

该工具原本是在 Linux 上使用,因为 Android 系统的内核也是 Linux,故很方便的可以移植到 Android 中。

Android-i2ctools 下载:

​​https://github.com/skyxiaoyan1/android-i2ctool​​
  • 1.

这是某位大佬根据 i2c-tools 4.1 移植的,关于 Android 下的编译博主上次写过 Android 系统编译技巧,大概流程如下:

源码包放在 /external/i2c-tools/...
在Android源码根目录输入
    source build/envsetup.sh
    lunch rk3399_mid-userdebug(自己的工程名字)
在 /external/i2c-tools/ 目录下输入 mm 模块编译
在 Android 根目录输入 make snod 重新打包 system.img
烧写 system.img
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

使用示例

i2cdetect:用于扫描 i2c 总线上的设备

Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]
       i2cdetect -F I2CBUS
       i2cdetect -l
  I2CBUS is an integer or an I2C bus name
  If provided, FIRST and LAST limit the probing range.
  
  y:关闭交互式,不会显示警告信息
  a:扫描总线上所有设备
  q:使用SMBus的"quick write"命令进行检测,不建议使用
  r:使用SMBus的"receive byte"命令进行检测,不建议使用
  i2cbus:指定查询某个总线编号
  first、last:扫描的地址范围
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

./i2cdetect -r -y 0。

-- 表示该地址被检测,但是没有芯片应答,UU 表示该地址被当前内核驱动使用。

如上图显示,在i2c0总线上,有三个器件,设备地址分别是:0x1b、0x40、0x41。

./i2cdetect -F i2cbus 查询总线的功能

./i2cdetect -V 打印软件版本号。

./i2cdetect -l 检测当前系统有几组i2c总线。

i2cset:向i2c设备某个寄存器写入值

Usage: i2cset [-f] [-y] [-m MASK] [-r] [-a] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
  MODE is one of:
    c (byte, no value)
    b (byte data, default)
    w (word data)
    i (I2C block data)
    s (SMBus block data)
    Append p for SMBus PEC
    
    f:强制访问
    y:指令执行自动yes,否则会提示确认执行Continue? [Y/n] Y,不加参数y会有很多执行提示,可以帮助判断
    r:写入后立即回读寄存器的值,并将结果与写入的值进行比较
    i2cbus:总线编号
    chip-address:i2c设备地址
    data-address:i2c寄存器地址
    value 要写入的值
    mode:指定读取的大小,b字节,w字,s是SMBus块,i是i2c块

设置i2c-1上0x20器件的0x77寄存器值为0x3f
./i2cset -f -y 1 0x20 0x77 0x3f
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

i2cget:读取i2c设备某个寄存器的值

Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
  MODE is one of:
    b (read byte data, default)
    w (read word data)
    c (write byte/read byte)
    Append p for SMBus PEC
    
    f:强制访问
    y:关闭交互模式,不会提示警告信息
    i2cbus:总线编号
    chip-address:i2c设备地址
    data-address:i2c寄存器地址
    mode:指定读取的大小,b字节,w字,s是SMBus块,i是i2c块

读取i2c-1上0x20器件的0x77寄存器值
./i2cget -f -y 1 0x20 0x77 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

i2cdump:读取某个i2c设备所有寄存器的值

Usage: i2cdump [-f] [-y] [-r first-last] [-a] I2CBUS ADDRESS [MODE [BANK [BANKREG]]]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
  MODE is one of:
    b (byte, default)
    w (word)
    W (word on even register addresses)
    s (SMBus block)
    i (I2C block)
    c (consecutive byte)
    Append p for SMBus PEC
    
    r:指定寄存器范围,只能扫描从 first 到 last 区域
    f:强制访问设备
    y:关闭人机交互模式
    i2cbus:总线编号
    address:指定设备地址
    mode:指定读取的大小,b字节,w字,s是SMBus块,i是i2c块

读取i2c1上0x38器件的所有寄存器
./i2cdump -f -y -a 1 0x38
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

一般寄存器都是8位地址的,i2cdump、i2cget、i2cset 也是设置读取8位的地址,如果一次超过8位,需要用 i2ctransfer。

i2ctransfer:一次性读写多个字节

Usage: i2ctransfer [-f] [-y] [-v] [-V] [-a] I2CBUS DESC [DATA] [DESC [DATA]]...
  I2CBUS is an integer or an I2C bus name
  DESC describes the transfer in the form: {r|w}LENGTH[@address]
    1) read/write-flag 2) LENGTH (range 0-65535) 3) I2C address (use last one if omitted)
  DATA are LENGTH bytes for a write message. They can be shortened by a suffix:
    = (keep value constant until LENGTH)
    + (increase value by 1 until LENGTH)
    - (decrease value by 1 until LENGTH)
    p (use pseudo random generator until LENGTH with value as seed)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

查看系统上存在的 i2c 总线及其设备地址。

ls /sys/bus/i2c/devices/
  • 1.

可以在这里查看实际的设备,然后对比 i2c-tools 扫描出来的对不对。

备注:

i2c-tools 是通过操作 /dev 路径 i2c-× 设备文件完成,因此你的 kernel 必须开启 CONFIG_I2C_CHARDEV 宏控,否者会报找不到节点。