LV08-01-I2C子系统-02-I2CTools
了解下I2C-Tools。若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.2的64位版本 | |
VMware® Workstation 17 Pro | 17.6.0 build-24238078 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 | |
linux内核 | linux-4.19.71(NXP官方提供) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
nxp-imx/linux-imx/releases/tag/v4.19.71 | NXP linux内核仓库tags中的v4.19.71 | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 | NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) | |
Source Code | https://elixir.bootlin.com/linux/latest/source | linux kernel源码 |
kernel/git/stable/linux.git - Linux kernel stable tree | linux kernel源码(官网,tag 4.19.71) | |
https://elixir.bootlin.com/u-boot/latest/source | uboot源码 |
一、参考资料
1. Linux驱动程序
i2c-dev.c - drivers/i2c/i2c-dev.c
2. I2C-Tools
这个工具官网在:I2C Tools - Linux i2c Wiki

github仓库在这里:GitHub - oudream/i2c-tools
下载页面在这里:Index of /pub/software/utils/i2c-tools/
二、I2C-Tools简介
1. I2C-Tools是什么?
i2c-tools工具是一个专门调试i2c的,开源,可获取挂载的设备及设备地址,还可以在对应的设备指定寄存器设置值或者获取值等功能。通过这个工具,我们无需编写驱动程序即可访问I2C设备。

对于APP访问硬件肯定是需要驱动程序的,对于I2C设备,内核提供了驱动程序 i2c-dev.c - drivers/i2c/i2c-dev.c,通过它可以直接使用下面的I2C控制器驱动程序来访问I2C设备。基本框架如下:

i2c-tools是一套好用的工具,也是一套示例代码。
2. I2C-Tools的访问I2C设备的2种方式
I2C-Tools可以通过SMBus来访问I2C设备,也可以使用一般的I2C协议来访问I2C设备。使用一句话概括I2C传输:APP通过I2C Controller与I2C Device传输数据。在APP里,有这几个问题:
- 怎么指定I2C控制器?
i2c-dev.c提供为每个I2C控制器(I2C Bus、I2C Adapter)都生成一个设备节点:/dev/i2c-0、/dev/i2c-1等
open某个/dev/i2c-X节点,就是去访问该I2C控制器下的设备
- 怎么指定I2C设备?通过ioctl指定I2C设备的地址
(1)I2C_SLAVE
1 | ioctl(file, I2C_SLAVE, address) |
如果该设备已经有了对应的设备驱动程序,则返回失败。
(2)I2C_SLAVE_FORCE
1 | ioctl(file, I2C_SLAVE_FORCE, address) |
如果该设备已经有了对应的设备驱动程序,但是还是想通过i2c-dev驱动来访问它,则使用这个ioctl来指定I2C设备地址。
- 怎么传输数据?
(1)一般的I2C方式:ioctl(file, I2C_RDWR, &rdwr)
(2)SMBus方式:ioctl(file, I2C_SMBUS, &args)
3. 交叉编译
- 设置交叉编译工具
1 | export ARCH=arm |
- 修改I2C-Tools的Makefile指定交叉编译工具链
1 | CC ?= gcc |
在Makefile中,“?=”在第一次设置变量时才会起效果,如果之前设置过该变量,则不会起效果。
- 执行make即可。
1 | make |
执行make时,是动态链接,需要把libi2c.so
也放到单板上:
1 | sudo cp -avf libi2c.so libi2c.so.0 libi2c.so.0.1.1 ~/4nfs/imx6ull_rootfs/lib/ |
想静态链接的话,执行:make USE_STATIC_LIB=1
。
三、使用I2C-Tools
使用一句话概括I2C传输:APP通过 I2C Controller 与 I2C Device传输数据。所以使用 I2C-Tools 时也需要指定:
- 哪个I2C控制器(或称为I2C BUS、I2C Adapter)
- 哪个I2C设备(设备地址)
- 数据:读还是写、数据本身
1. i2cdetect:I2C检测
1.1 使用说明
1 | 列出当前的I2C Adapter(或称为I2C Bus、I2C Controller) |
1.2 使用实例
1 | i2cdetect -l |
2. i2cget:I2C读
2.1 使用说明如下
1 | i2cget |
2.2 使用示例
1 | 读一个字节: I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址 |
3. i2cset:I2C写
3.1 使用说明
1 | i2cset |
3.2 使用示例
1 | 写一个字节: I2CBUS为0、1、2等整数, 表示I2C Bus; CHIP-ADDRESS表示设备地址 |
4. i2ctransfer:I2C传输(不是基于SMBus)
4.1 使用说明
1 | i2ctransfer |
4.2 使用实例
1 | Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50): |
四、AP3216C的操作
1. AP3216C简介
正点原子的开发板上有光感芯片AP3216C:

I.MX6U-ALPHA 开发板上通过 I2C1 连接了一个三合一环境传感器: AP3216C, AP3216C是由敦南科技推出的一款传感器,其支持环境光强度(ALS)、接近距离(PS)和红外线强度(IR)这三个环境参数检测。该芯片可以通过 IIC 接口与主控制相连,并且支持中断。寄存器也比较简单:

0X00 这个寄存器是模式控制寄存器,用来设置 AP3216C 的工作模式,一般开始先将其设置为 0X04,也就是先软件复位一次 AP3216C。接下来根据实际使用情况选择合适的工作模式,比如设置为 0X03,也就是开启 ALS+PS+IR。从 0X0A~0X0F 这 6 个寄存器就是数据寄存器,保存着 ALS、 PS 和 IR 这三个传感器获取到的数据值。如果同时打开 ALS、PS 和 IR 则读取间隔最少要 112.5ms,因为 AP3216C 完成一次转换需要 112.5ms。
我们编写程序会先检测 AP3216C 是否存在,一般的芯片是有个 ID 寄存器,通过读取 ID 寄存器判断 ID 是否正确就可以检测芯片是否存在。但是 AP3216C 没有 ID 寄存器,所以我们就可以通过向寄存器 0X00 写入一个值,然后再读取 0X00 寄存器,判断读出得到值和写入的是否相等,如果相等就表示 AP3216C 存在,否则的话 AP3216C 就不存在。
2. 硬件原理图

3. 设备地址
AP3216 的设备地址为 0X1E ,这个我们可以看芯片手册:datasheet_my.pdf:

4. 读写步骤
AP3216C是红外、光强、距离三合一的传感器,以读出光强、距离值为例,步骤如下:
- 复位:往寄存器0写入0x4。
- 使能:往寄存器0写入0x3。
- 读光强:读寄存器0xC、0xD得到2字节的光强。
- 读距离:读寄存器0xE、0xF得到2字节的距离值。
5. I2C-Tools的使用
5.1 i2cdetect
- 列出当前的I2C Adapter(或称为I2C Bus、I2C Controller)
1 | i2cdetect -l |

- 打印某个I2C Adapter的Functionalities, I2CBUS为0、1、2等整数
1 | i2cdetect -F I2CBUS |

- 看看有哪些I2C设备, I2CBUS为0、1、2等整数
1 | i2cdetect -y -a I2CBUS |

1 | -- :表示没有该地址对应的设备 |
前面我们知道AP3216C接在I2C1上面,这里对应的是i2c-0。
5.2 使用SMBus协议
1 | i2cset -f -y 0 0x1e 0 0x4 # 复位 |

5.3 使用I2C协议
1 | i2ctransfer -f -y 0 w2@0x1e 0 0x4 # 复位 |

五、源码分析
1. 使用I2C方式
示例代码:i2ctransfer.c

2. 使用SMBus方式
示例代码:i2cget.c、i2cset.c
