i2c除錯工具分享

嵌入式與Linux那些事發表於2022-04-19

i2c-tools簡介

在嵌入式開發仲,有時候需要確認硬體是否正常連線,裝置是否正常工作,裝置的地址是多少等等,這裡我們就需要使用一個用於測試I2C匯流排的工具——i2c-tools。

i2c-tools工具是一個專門除錯i2c的,開源,可獲取掛載的裝置及裝置地址,還可以讀寫I2C裝置暫存器。

下面我們就對這個工具的安裝和使用做個簡單介紹。

i2c-tools安裝

下載地址:https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/。本文使用的是4.3版本。

解壓

下載完成後,放到linux環境下解壓。

 tar -zxvf i2c-tools-4.3.tar.gz 
 cd i2c-tools-4.3

編譯

使用以下命令進行編譯

make CC=arm-linux-gnueabihf-gcc   USE_STATIC_LIB=1

USE_STATIC_LIB 的意思是使用靜態編譯。編譯完成後,會在tools目錄下產生i2cdetect,i2cdump,i2cget,i2cset,i2ctransfer五個產物。將這些可執行檔案拷貝到裝置上。

不加 USE_STATIC_LIB 編譯選項,會使用動態連結的方式編譯。編譯完成後需要拷貝i2c-tools-4.3/lib 目錄下的libi2c.so.0動態庫到裝置上的/usr/bin 目錄下。

i2c-tools使用方法

i2cdetect

i2cdetect用來列舉I2C bus和上面所有的裝置,可接受的引數有

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.

-V:輸出當前版本號

debian@npi:/mnt/mnt$ ./i2cdetect -V
i2cdetect version 4.3

-l:輸出所有 i2c 匯流排,如下匯流排編號有twi1和twi2,或者1和2

debian@npi:/mnt/mnt$ ./i2cdetect -l
i2c-0   unknown         21a0000.i2c                             N/A
i2c-1   unknown         21a4000.i2c                             N/A
debian@npi:/mnt/mnt$ ls -l /dev/i2c-*
crw------- 1 root root 89, 0 Mar 19 09:42 /dev/i2c-0
crw------- 1 root root 89, 1 Mar 19 09:42 /dev/i2c-1

I2CBUS:i2c匯流排編號
-F:此 i2c 支援的功能

root@npi:/mnt/mnt# ./i2cdetect -F 1
Functionalities implemented by /dev/i2c-1:
I2C                              yes
SMBus Quick Command              yes
SMBus Send Byte                  yes
SMBus Receive Byte               yes
SMBus Write Byte                 yes
SMBus Read Byte                  yes
SMBus Write Word                 yes
SMBus Read Word                  yes
SMBus Process Call               yes
SMBus Block Write                yes
SMBus Block Read                 yes
SMBus Block Process Call         no
SMBus PEC                        yes
I2C Block Write                  yes
I2C Block Read                   yes
root@npi:/mnt/mnt# 

-y:指令執行自動yes,否則會提示確認執行Continue? [Y/n] Y,不加引數y會有很多執行提示,可以幫助判斷

-a:輸出匯流排上所有地址(00-7f),沒有 -a,只顯示 08-77,UU 表示該裝置在驅動中已使用。

如下0x1a,0x39的地址正在被使用。

root@npi:/mnt/mnt# ./i2cdetect -a 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x00-0x7f.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
root@npi:/mnt/mnt# ./i2cdetect -y -a 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
root@npi:/mnt/mnt# 

i2cdump

i2cdump讀取裝置上所有暫存器的值,可接受的引數有

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

-V:輸出當前版本號

-f:強制使用此裝置地址,即使此裝置地址已經被使用;若不新增此引數,地址可能寫失敗

-y:指令執行自動 yes,否則會提示確認執行Continue? [Y/n] Y,不加引數y會有很多執行提示,可以幫助判斷

-r:讀取從 first-last 之間的暫存器值

-a:讀取0x00-0xff範圍的地址

I2CBUS:i2c匯流排編號

ADDRESS:裝置地址,建議使用十六進位制

MODE:資料長度型別

root@npi:/mnt/mnt# ./i2cdump -f -y -a 1 0x39
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 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00    ........p.......
10: 00 00 00 00 00 00 00 00 00 00 10 b0 02 03 02 00    ..........?????.
20: 95 00 00 00 00 00 40 00 00 00 00 fb ff dd c4 00    ?.....@....?.??.
30: 00 00 00 00 00 00 90 22 a0 00 00 00 01 10 00 00    ......?"?...??..
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 04 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ??..............
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00    .............?..
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 77 14 76 01 00 01 00    .........w?v?.?.
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

# 只讀取0x50-0x7f暫存器範圍的值
root@npi:/mnt/mnt# ./i2cdump -f -y -r 0x50-0x7f 1 0x39
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 04 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ??..............
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00    .............?..
root@npi:/mnt/mnt# 

通過讀取i2c裝置暫存器的值與晶片手冊的值進行比對,確認我們配置的是否正確。

i2cget

i2cget讀取裝置上暫存器的值,可接受的引數有

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

I2CBUS:i2c匯流排編號

CHIP-ADDRESS:裝置地址

DATA-ADDRESS:要讀取的暫存器地址

MODE:資料長度型別

# 0x39裝置地址,0x04要讀取的暫存器
root@npi:/mnt/mnt# ./i2cget -f -y 1 0x39 0x04
0x03

i2cset

i2cset設定裝置上暫存器的值,可接受的引數有

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

I2CBUS:i2c匯流排編號

CHIP-ADDRESS:裝置地址

DATA-ADDRESS:要寫入的暫存器地址

VALUE:要寫入的值

MODE:資料長度型別

root@npi:/mnt/mnt# ./i2cset -f -m 0xff -r 1 0x39 0x04 0x03
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-1, chip address 0x39,
data address 0x04, data 0x03 (masked), mode byte.
Continue? [Y/n] y
Old value 0x00, write mask 0xff, will write 0x03
Continue? [Y/n] y
Value 0x03 written, readback matched
root@npi:/mnt/mnt# 

把寫入暫存器的值讀出來。確認與我們寫入的值相同。

root@npi:/mnt/mnt# ./i2cdump -f -y -r 0x00-0x0f 1 0x39
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 00 00 00 03 00 00 00 70 00 00 00 00 00 00 00    ....?...p.......
root@npi:/mnt/mnt# 

i2ctransfer

i2ctransfer通過一次傳輸傳送使用者定義的I2C訊息,用於建立I2C訊息並將其作為一次傳輸合併傳送。

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)

Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):
  # i2ctransfer 0 w1@0x50 0x64 r8
Example (same EEPROM, at offset 0x42 write 0xff 0xfe ... 0xf0):
  # i2ctransfer 0 w17@0x50 0x42 0xff-

I2CBUS:i2c匯流排編號

DESC:{r | w}<訊息長度>[@裝置地址]

  • {r | w}指定訊息是讀還是寫

  • <訊息長度>指定在此訊息中讀取或寫入的位元組數。它被解析為一個無符號的16位整數

  • [@裝置地址]指定此訊息要訪問的晶片的7位地址,並且是整數。

#引數2為i2c2,w2表示寫兩個位元組,@0x39為i2c裝置(注意要7位地址),0x02 0xd3 為高低位地址,r1為讀取的資料是一個byte。
root@npi:/mnt/mnt# ./i2ctransfer  -f -y 1 w2@0x60 0x02 0xd3 r1
0x00

總結

本文只是拋磚引玉,i2c-tools還有更多的使用方法,需要大家在實際工作中去探索。

相關文章