前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >i2c-tools快速调试E2PROM

i2c-tools快速调试E2PROM

作者头像
知否知否应是绿肥红瘦
发布于 2025-02-19 13:33:58
发布于 2025-02-19 13:33:58
16800
代码可运行
举报
文章被收录于专栏:Linux知识Linux知识
运行总次数:0
代码可运行

一、i2c_tool

i2c-toolLinux应用层调试I2C设备(特别是E2PROM)的利器,这个工具是开源的,并且几乎可以交叉编译到任何Linux系统上。 它是一个工具集,具体包括如下工具:

i2cdetect: i2c总线探测工具,探测总线上的I2C设备 i2cdump:i2c总线dump工具 i2cget:i2c读取工具 i2cset: i2c写入工具 i2ctransfer:自定义I2C消息发送

下载 & 编译
i2c_tool下载地址

源码解压如下:

如果是交叉编译到开发板,则需要修改makefile文件,主要做了以下修改:

  • PREFIX 是i2c_tool编译后安装的目录前缀,改为./output
  • sbindir = (PREFIX)/i2c_tools 编译产物生成目录改为(PREFIX)/i2c_tools
  • 增加COMPILE_PREFIX:=arm-linux-gnueabihf-,指向实际使用的交叉工具链
  • CC ?= (COMPILE_PREFIX)gcc ;AR ?= (COMPILE_PREFIX)ar ;STRIP ?=
  • 为了调试方便,这些工具使用静态库编译,好处是工具可以直接运行而不需要考虑库依赖,静态库的配置如下: BUILD_DYNAMIC_LIB ?= 0 BUILD_STATIC_LIB ?= 1 USE_STATIC_LIB ?= 1

完整的makefile如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# I2C tools for Linux
#
# Copyright (C) 2007-2012  Jean Delvare <jdelvare@suse.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

DESTDIR	?=
PREFIX	?= ./output
bindir	= $(PREFIX)/bin
sbindir	= $(PREFIX)/i2c_tools
mandir	= $(PREFIX)/share/man
man3dir	= $(mandir)/man3
man8dir	= $(mandir)/man8
incdir	= $(PREFIX)/include
libdir	= $(PREFIX)/lib

INSTALL		:= install
INSTALL_DATA	:= $(INSTALL) -m 644
INSTALL_DIR	:= $(INSTALL) -m 755 -d
INSTALL_PROGRAM	:= $(INSTALL) -m 755
LN		:= ln -sf
RM		:= rm -f
COMPILE_PREFIX:=arm-linux-gnueabihf-

CC	?= $(COMPILE_PREFIX)gcc
AR	?= $(COMPILE_PREFIX)ar
STRIP	?= $(COMPILE_PREFIX)strip

CFLAGS		?= -O2
# When debugging, use the following instead
#CFLAGS		:= -O -g
CFLAGS		+= -Wall
SOCFLAGS	:= -fpic -D_REENTRANT $(CFLAGS)

BUILD_DYNAMIC_LIB ?= 0
BUILD_STATIC_LIB ?= 1
USE_STATIC_LIB ?= 1

ifeq ($(USE_STATIC_LIB),1)
BUILD_STATIC_LIB := 1
endif

ifeq ($(BUILD_DYNAMIC_LIB),0)
ifeq ($(BUILD_STATIC_LIB),0)
$(error BUILD_DYNAMIC_LIB and BUILD_STATIC_LIB cannot be disabled at the same time)
else
USE_STATIC_LIB := 1
endif
endif

KERNELVERSION	:= $(shell uname -r)

.PHONY: all strip clean install uninstall

all:

EXTRA	:=
#EXTRA	+= eeprog py-smbus
SRCDIRS	:= include lib eeprom stub tools $(EXTRA)
include $(SRCDIRS:%=%/Module.mk)
编译 & 安装
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
make  #编译
make install # 安装
make clean #清除之前编译结果

执行make install后,生成的工具都在i2c-tools-4.3/output/i2c_tools/目录下,将它们拷贝到开发板,即可直接运行。

二、开发板调试

内核需要支持i2c-dev设备,否则i2c-tool无法使用。

开启内核配置后/dev/i2c有如下设备即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# ls /dev/i2c*
/dev/i2c-0  /dev/i2c-1  /dev/i2c-2  /dev/i2c-3  /dev/i2c-4  /dev/i2c-6

开发板设备树描述如下,并且I2C1上已经接了一个E2PROM AT24C08.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
&i2c1
{
       status = "okay";  
       clock-frequency = <100000>;
	at24c02: at24c08@50 {
		compatible = "atmel,24c08";
		reg = <0x50>;
	};
};

同时在/sys/devices/platform/ff140000.i2c/i2c-1目录下也是能看到该设备的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/sys/devices/platform/ff140000.i2c/i2c-1]# ls
1-0050         device   name        of_node  subsystem
delete_device  i2c-dev  new_device  power    uevent

[root@rk3288:/sys/devices/platform/ff140000.i2c/i2c-1/1-0050]# cat name
24c08

接下来就可以使用i2c-tools进行调试了。

i2cdetect

i2cdetect用于扫描设备的 I2C 总线。 它输出一个表,其中包含指定总线上检测到的设备列表。 I2CBUS 表示要扫描的 I2C 总线的编号或名称,应与 i2cdetect -l列出的总线之一相对应。 可选参数 FIRST 和 LAST限制扫描范围(默认:从 0x08 到 0x77)。 由于没有标准的 I2C 检测命令,i2cdetect 使用任意 SMBus 命令(即 SMBus 快速写入和 SMBus 接收字节)来探测设备。 默认情况下,使用的命令是被认为对每个地址最安全的命令。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]
-y
禁用交互模式。 默认情况下,i2cdetect 会在处理 I2C 总线之前等待用户的确认。 使用此标志时,将直接执行操作。这主要是为了在脚本中使用。
-a
强制扫描非常规地址。 不建议。
-q
使用 SMBus“快速写入”命令进行探测。 不建议。 众所周知,这会损坏许多 IBM Thinkpad 笔记本电脑上的 Atmel AT24RF08 EEPROM-r
使用 SMBus“接收字节”命令进行探测。 不建议。 众所周知,这会将 SMBus 锁定在各种只写芯片上(最显着的是地址 0x69 处的时钟芯片)。
-F
显示适配器实现的功能列表并退出。
-V
显示版本并退出。
-l
输出已安装总线的列表。 
I2CBUS
指定i2c总线,整形,1即代表i2c1
FIRST LAST
探测地址的范围,如果不指定,默认探测 0x08 to 0x77
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/sys/devices/platform/ff140000.i2c/i2c-1/1-0050]# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 53 -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

结果显示在0x50,0x51,0x52,0x53这4个地址都探测到了i2c设备,但是实际上只有一个AT24C08挂在i2c1总线下。 这是因为我的设备是at24c08,它的设备地址如下图8K所示:

at24c08的大小是8Kbit,也就是1024字节,超过了256字节,所以需要通过页寻址,总共分为4页,每页256字节。 P1P0就是页片选位,由于A2引脚接地,故at24c08有4个有效设备地址。

i2cget

i2cget 用于读取通过 I2C 总线(或 SMBus)可见的寄存器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cget [-f] [-y] [-a] i2cbus chip-address [data-address [mode]]
-V
显示版本并退出。
-F
强制访问设备,即使它已经很忙。 默认情况下,i2cget 将拒绝访问已经在内核驱动程序控制下的设备。
使用这个标志是危险的,它会严重混淆有问题的内核驱动程序。
它还可能导致 i2cget 返回无效值。因此,仅当您知道自己在做什么时,风险自负。
-y
禁用交互模式。 默认情况下,i2cget 会在处理 I2C 总线之前等待用户的确认。
使用此标志时,将直接执行操作.这主要是为了在脚本中使用。 谨慎使用。
-a
允许使用 0x00 - 0x070x78 - 0x7f 之间的地址。 不建议。
i2cbus 
指定i2c总线,整数,1即代表i2c1
chip-address
指定该总线上芯片的地址,是一个介于 0x080x77 之间的整数。
data-address
指定要从该芯片上读取的地址,它是一个介于 0x000xFF 之间的整数。如果省略,将读取当前活动的寄存器
mode
如果指定,模式参数是字母 b、w 或 c 之一,分别对应于读字节数据、读字数据或写字节/读字节。
如果省略 mode 参数,i2cget 默认为读取字节数据

读取i2c1总线,设备地址为0x50的设备中地址为0x02的值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cget -y 0x50 0x02
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# i2cget -y 1 0x50 0x02
0x12

[root@rk3288:/]# i2cget -y 1 0x50 0x02 w
0x1312
i2cset

i2cset 用于设置通过 I2C 总线可见的寄存器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cset [-f] [-y] [-m mask] [-r] [-a] i2cbus chip-address data-address [value] ... [mode]
-V
显示版本并退出。
-F
强制访问设备,即使它已经很忙。默认情况下,i2cset 将拒绝访问已经在内核驱动程序控制下的设备。
使用这个标志是危险的,它会严重混淆有问题的内核驱动程序。
它还可能导致 i2cset 静默写入错误的寄存器。因此,仅当您知道自己在做什么时,风险自负。
-y
禁用交互模式。默认情况下,i2cset 会在处理 I2C 总线之前等待用户的确认。
使用此标志时,将直接执行操作。这主要是为了在脚本中使用。
-m 掩码
掩码参数(如果指定)描述值的哪些位将实际写入数据地址。
掩码中设置为 1 的位取自值,而设置为 0 的位将从数据地址中读取并因此由操作保留。
请注意,此参数假定指定模式的读写操作对于您正在访问的设备是对称的。
这可能是也可能不是,因为 I2C 和 SMBus 都不能保证这一点。
-r
写入后立即读回值,并将结果与​​写入的值进行比较。这曾经是默认行为。与选项 -m 的限制相同。
-a
允许使用 0x00 - 0x070x78 - 0x7f 之间的地址。不建议。
i2cbus 
指定i2c总线,整数,1即代表i2c1
chip-address
指定该总线上芯片的地址,是一个介于 0x080x77 之间的整数。
data-address
指定要向写入该芯片的地址,它是一个介于 0x000xFF 之间的整数。
value
如果指定则代表需要写入芯片data-address的值。
如果省略此参数,则发出短写。 对于大多数芯片,它只是设置一个指向目标位置的内部指针,但实际上并不写入该位置。 
但是对于少数芯片,特别是具有单个寄存器的简单芯片,这种简短的写入是实际写入。 
如果 mode 参数是 s 或 i,则可以指定多个值。
mode
如果指定,字母 b、w、s 或 i 之一,分别对应于单个字节、16 位字、SMBus 块写入或 I2C 块写入的写入大小。 
对于 SMBus 和 I2C 块写入,写入大小由value参数的数量决定。
如果省略 mode 参数,i2cset 默认为不带 PEC 的字节模式。提供的值必须在指定数据类型的范围内(字节和块写入为 0x00-0xFF,字为 0x0000-0xFFFF)。 
另一种可能的模式是 c,它不写入任何值(所谓的短写)。您通常不必指定此模式,因为它是未提供值时的默认值,除非您还想启用 PEC

i2c1总线设备地址为0x50的设备中,地址为0x02的位置写入0x98

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cset -y 1 0x50 0x02 0x98
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# i2cset -y 1 0x50 0x02 0x98
[root@rk3288:/]# i2cget -y 1 0x50 0x02
0x98

i2c1总线设备地址为0x50的设备中,地址为0x02的位置写入16 bit数据 0xAABB

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cset -y 1 0x50 0x02 0xAABB w
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# i2cset -y 1 0x50 0x02 0xAABB w
[root@rk3288:/]# i2cget -y 1 0x50 0x02 w
0xaabb
i2cdump

i2cdump 用于检查通过 I2C 总线可见的寄存器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cdump [-f] [-r first-last] [-y] [-a] i2cbus address [mode [bank [bankreg]]]
-V
显示版本并退出。
-f
强制访问设备,即使它已经很忙。 默认情况下,i2cdump 将拒绝访问已经在内核驱动程序控制下的设备。 
使用这个标志是危险的,它会严重混淆有问题的内核驱动程序。 
它还可能导致 i2cdump 返回无效结果。 因此,仅当您知道自己在做什么时,风险自负。
-r first-last
限制被访问的寄存器范围。 
此选项仅适用于模式 b、w、c 和 W。对于模式 W,first 必须是偶数,last 必须是奇数。
-y
禁用交互模式。 默认情况下,i2cdump 会在处理 I2C 总线之前等待用户的确认。 
使用此标志时,将直接执行操作。 这主要是为了在脚本中使用。
-a
允许使用 0x00-0x070x78-0x7f 之间的地址。不建议。
i2cbus 
指定i2c总线,整数,1即代表i2c1
address 
指定该总线上芯片的地址,是一个介于 0x080x77 之间的整数。
mode 
如果指定,字母 b、w、s 或 i 之一,分别对应于单个字节、16 位字、SMBus 块、I2C 块的读取大小。 
c 模式有点不同,它连续读取所有字节,对于具有地址自动递增功能的芯片很有用,例如 EEPROMW 模式也比较特殊,与 w 类似,只是读命令只会在偶数寄存器地址上发出; 这再次主要用于 EEPROM。
如果省略,默认以字节模式读取。
bank  bankreg
bank 和 bankreg 参数在 W83781D 和类似芯片上很有用(在撰写本文时,所有 Winbond 和 Asus 芯片)。 
bank 是 07 之间的整数,bankreg 是 0x000xFF 之间的整数(默认值:0x4E)。 
W83781D datasheet提供了有关bank选择的更多信息。

读取i2c1总线,设备地址为0x50的设备中地址从0x00~0xFF的值.。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
i2cdump -y 1 0x50
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# i2cdump -y 1 0x50
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: 10 11 bb aa 04 05 06 07 08 09 00 01 02 03 04 05    ??????????.?????
10: 10 11 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 0a 0b    ????????????????
20: ff ff ff ff 10 11 12 13 ff ff ff ff ff ff ff ff    ....????........
30: 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c    ???.????????????
40: 10 10 10 10 11 12 13 13 13 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: 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c    ???.????????????
80: 0f 00 01 10 11 12 13 06 07 08 09 0a 0b 0c 0d 0e    ?.??????????????
90: 02 03 04 05 06 07 0f 00 00 00 01 00 01 02 00 01    ???????...?.??.?
a0: 12 13 09 08 09 0a 08 09 0a 0b 0c 0d 0e 0f 10 11    ????????????????
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: 05 06 07 ff ff ff ff ff 00 01 02 00 01 02 03 04    ???......??.????
d0: 08 09 0a 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 ff    ???????????????.
e0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09    ??????.?????????
f0: 00 01 02 03 04 05 10 11 12 13 0a 0b 0c 0d 0e 0f    .???????????????

读取i2c1总线,设备地址为0x50的设备中地址从0x00~0x7F的值.。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@rk3288:/]# i2cdump -y -r 0x00-0x7f 1 0x50 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 10 11 bb aa 04 05 06 07 08 09 00 01 02 03 04 05    ??????????.?????
10: 10 11 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 0a 0b    ????????????????
20: ff ff ff ff 10 11 12 13 ff ff ff ff ff ff ff ff    ....????........
30: 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c    ???.????????????
40: 10 10 10 10 11 12 13 13 13 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: 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c    ???.????????????

参考

  1. Manpages of i2c-tools in Debian unstable
  2. I2C Tools Wiki
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
「SF-LC」14 ImpCEvalFun
Step-Indexed Evaluator …Copied from 12-imp.md: Chapter ImpCEvalFun provide some workarounds to make functional evalution works: step-indexed evaluator, i.e. limit the recursion depth. (think about Depth-Limited Search). return option to tell if it’s a norm
零式的天空
2022/03/14
4730
「SF-LC」6 Logic
The equality operator = is also a function that returns a Prop. (property: equality)
零式的天空
2022/03/14
6000
「SF-PLF」5 Smallstep
not just input state get mapped to output state. but also intermediate state (which could be observed by concurrent code!)
零式的天空
2022/03/02
5980
「SF-LC」1 Basics
The .v code is a gorgeous example of literal programming and the compiled .html website is full-fledged. So this note is intended to be NOT self-contained and only focus on things I found essential or interesting. This note is intended to be very personal and potentially mix English with Chinese (You can Lol) So yeah. Don’t expect it to be well organized and well written. I posted it on blog mainly for my own references purpose. The quotes could either come from the book or saying from someone (even including me).
零式的天空
2022/03/14
4060
「SF-LC」13 ImpParser
basically, parser combinator (But 非常麻烦 in Coq)
零式的天空
2022/03/14
3750
「SF-LC」3 List
Pair of Numbers Q: Why name inductive? A: Inductive means building things bottom-up, it doesn’t have
零式的天空
2022/03/14
4290
「SF-LC」4 Poly
Until today, We were living in the monomorphic world of Coq. So if we want a list, we have to define it for each type:
零式的天空
2022/03/14
1.3K0
「SF-PLF」1 Equiv
Some module (e.g.Map) not found either maunally make map.vo or proof general can solve that.
零式的天空
2022/03/02
4960
「SF-LC」15 Extraction
如果不做任何处理的话…生成的 ml 里的 nat 则都会是 Church Numeral…
零式的天空
2022/03/14
5300
「SF-LC」7 Ind Prop
we can write an Inductive definition of the even property!
零式的天空
2022/03/14
6660
「SF-LC」16 Auto
Ltac - automated forward reasoning (hypothesis matching machinery)
零式的天空
2022/03/14
3680
「SF-LC」9 ProofObjects
So the book material is designed to be gradually reveal the facts that
零式的天空
2022/03/14
5600
「SF-LC」10 IndPrinciples
P only need to fullfill l : the_type but not n:nat since we are proving property of the_type.
零式的天空
2022/03/14
7730
「SF-LC」2 Induction
Whether or not it can be just simpl. depending on the definition of orb.
零式的天空
2022/03/14
4330
「SF-PLF」7 Stlc
“Base Types”, only Bool for now. — 基类型 …again, exactly following TAPL.
零式的天空
2022/03/02
3690
「SF-LC」5 Tactics
It also works with conditional hypotheses:
零式的天空
2022/03/14
5350
「SF-LC」8 Maps
From now on, importing from std lib. (but should not notice much difference)
零式的天空
2022/03/14
3460
「SF-PLF」6 Types
The toy lang from SmallStep is too “safe” to demonstrate any runtime (or dynamic) type errors. — 运行时类型错误 So that’s add some operations (common church numeral ones), and bool type.
零式的天空
2022/03/02
4510
「SF-PLF」11. TypeChecking
首先我们需要 check equality for types. 这里非常简单,如果是 SystemF 会麻烦很多,对 ∀ 要做 local nameless 或者 alpha renaming:
零式的天空
2022/03/02
2810
「SF-LC」11 Rel
I have been long confused with Unary Relations vs. Binary Relation on the Same Set (homogeneous relation) I thought they were same…but turns out they are totally different!
零式的天空
2022/03/14
3960
相关推荐
「SF-LC」14 ImpCEvalFun
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 一、i2c_tool
    • 下载 & 编译
    • 编译 & 安装
  • 二、开发板调试
    • i2cdetect
    • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档