RK平台使用i2c-tools调试

i2ctool是嵌入式开发中的重要调试工具,包括i2cdetect、i2cdump、i2cset和i2cget等命令。本文介绍了如何在RK平台的SDK中编译和使用这些工具,以及通过i2cdetect检测I2C总线和设备,i2cdump查看设备寄存器值,i2cget和i2cset读写设备寄存器的操作示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

i2ctool是嵌入式开发过程中调试i2c设备常用的工具包,其中比较常用的有:i2cdetect、i2cdump、i2cset、i2cget。

编译

RK平台的SDK大部分默认都会带这个工具,如果没有编译进去或者找不到的情况下可以自己从网上下载编译进去:

  • 下载: https://www.kernel.org/pub/software/utils/i2c-tools
  • 编译:
修改交叉编译工具链:
#CC     ?= gcc
#CC     := arm-linux-gnueabihf-gcc
CC      := aarch64-linux-gnu-gcc

用静态库:
BUILD_DYNAMIC_LIB ?= 0
USE_STATIC_LIB ?= 0

make
生成:
i2ctransfer i2cget i2cset i2cdump i2cdetect

i2cdetect

检测有几组i2c总线在系统上:

[root@rk3399:/]# i2cdetect -l
i2c-0   i2c             rk3x-i2c                                I2C adapter
i2c-1   i2c             rk3x-i2c                                I2C adapter
i2c-4   i2c             rk3x-i2c                                I2C adapter
i2c-9   i2c             DP-AUX                                  I2C adapter
i2c-10  i2c             DesignWare HDMI                         I2C adapter
i2c-11  i2c             DP-AUX                                  I2C adapter

检测挂载在i2c总线上的设备(i2c0):

[root@rk3399:/]# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: UU -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- 
20: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

i2cdump

查看i2c设备所有寄存器的值(i2c-0总线,i2c地址为0x20):

[root@rk3399:/]# i2cdump -f -y 0 0x20
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: 17 40 07 21 04 21 03 00 00 00 01 01 00 80 02 00    ?@?!?!?...??.??.
10: 00 00 03 00 00 00 00 06 c8 00 00 00 00 00 00 00    ..?....??.......
20: 00 00 00 ff ff 00 00 70 00 66 00 00 00 00 00 0f    .......p.f.....?
30: 04 00 00 00 a5 00 00 00 20 ff ff 00 00 e0 0f 09    ?...?... ....???
40: 69 4c 04 58 2d 0c a5 00 00 00 00 17 00 00 17 00    iL?X-??....?..?.
50: fc 00 01 00 01 b0 04 8e 06 d0 a5 18 a5 24 01 fd    ?.?.?????????$??
60: ff ef ff 00 00 00 00 00 00 00 00 a5 ee 01 30 00    .?.........???0.
70: 03 1e 6a 88 03 1e 7c 78 a5 18 01 fd 00 f6 dc 05    ??j???|x????.???
80: 8b 25 03 6e 43 f0 00 00 00 00 00 00 00 00 00 02    ?%?nC?.........?
90: 45 7f 1f 7f f2 df b8 81 1e ff 58 1b 00 c4 09 00    E????????.X?.??.
a0: c4 09 00 00 ff 00 00 00 00 00 00 00 00 00 00 00    ??..............
b0: 00 0f 0f 0f 0f bf ef ff ff 00 64 20 20 64 1a 20    .??????...d  d? 
c0: 64 00 00 64 62 62 64 ff ff ff ff ff 0c 0c 30 30    d..dbbd.....??00
d0: 0c 0c 30 30 24 30 24 24 60 60 6c 6c 6c 6c 0b 36    ??00$0$$``llll?6
e0: 00 00 00 55 a2 c8 c5 40 00 ff 22 03 0a 80 94 0c    ...U???@.."?????
f0: c0 8c a0 40 00 40 00 86 00 dc 00 fc 00 ff 60 00    ???@.@.?.?.?..`.

i2cget

查看设备单个寄存器的值(i2c-0总线,i2c地址为0x20,寄存器地址为0xa):

[root@rk3399:/]# i2cget -f -y 0 0x20 0xa
0x01

i2cset

设置设备寄存器的值(i2c-0总线,i2c地址为0x20,寄存器地址为0xa,写值0x02):

[root@rk3399:/]# i2cget -f -y 0 0x20 0xa
0x01
[root@rk3399:/]# i2cset -f -y 0 0x20 0xa 0x02
[root@rk3399:/]# i2cget -f -y 0 0x20 0xa
0x02

使用示例

目标

该示例主要实现通过操作电源管理芯片的寄存器,关闭一路电源输出,本示例以RK3399板子上RK809的SWITCH_REG1为例。

查寄存器手册

在这里插入图片描述
在这里插入图片描述
通过RK809的芯片手册的《Chapter 5 Register Description》章节可以知道,操作SW1_EN的偏移址PMIC_POWER_EN3为0x00b4。bit[6]为写允许位,bit[2]为SW1_EN,因此,写的值为:0x44。指令为:

i2cset -f -y 0 0x20 0xb4 0x44

操作

[root@rk3399:/]# i2cget -f -y 0 0x20 0xb4 #读出当前状态
0x0f
[root@rk3399:/]# i2cset -f -y 0 0x20 0xb4 0x40 #关闭sw1
[root@rk3399:/]# i2cget -f -y 0 0x20 0xb4 #读出当前状态
0x0b

出错解决

有些i2c-tools在操作中会报错,如下:

# i2cset -f 4 0x22 0xc 0x01                                        
i2cset: mode too long (see "i2cset --help")

应该在最后加显示模式:

# i2cset --help                                                      
usage: i2cset [-fy] BUS CHIP ADDR VALUE... MODE


Write an i2c register. MODE is b for byte, w for 16-bit word, i for I2C block.


-f      Force access to busy devices
-y      Answer "yes" to confirmation prompts (for script use)


# i2cset -f -y 4 0x22 0xc 0x1 b
### RK3x I2C Timeout 问题分析与解决方案 在RK3x平台上,I2C设备出现`timeout`问题可能由多种因素引起。根据提供的引用内容[^1]、[^2]、[^3]、[^4],结合I2C协议特性以及硬件配置,以下是针对`ff180000.i2c`设备上出现`timeout`问题(`ipd`值为`0x11`)的分析与解决方法。 #### 1. 背景信息 - **I2C总线特性**:I2C是一种两线制串行通信协议,包括数据线(SDA)和时钟线(SCL)。其性能受频率设置、负载电容、信号完整性等因素影响。 - **IPD寄存器**:`ipd`值反映了I2C控制器的状态。`ipd=0x11`通常表示传输过程中出现了错误状态,可能是由于时钟拉伸、应答错误或超时等引起的。 - **Timeout原因**:`timeout`通常发生在主机未收到从设备的应答信号,或者从设备未能在规定时间内完成操作。 #### 2. 解决方案 ##### (1)降低I2C时钟频率 高频I2C通信可能导致信号完整性问题,尤其是在长距离布线或高负载电容的情况下。根据引用[^4],将时钟频率从400kHz降低到100kHz可以有效减少`timeout`问题。可以通过修改设备树中的配置实现: ```dts i2c@ff180000 { clock-frequency = <100000>; // 设置为100kHz }; ``` ##### (2)检查引脚配置 确保I2C引脚配置正确。如果使用了非默认的引脚组合(如`I2C6_SDA_M1`或`I2C6_SDA_M3`),需要更新设备树中的`pinctrl`配置[^2]。例如: ```dts i2c6: i2c@ff180000 { pinctrl-names = "default"; pinctrl-0 = <&i2c6m1_xfer>; // 修改为正确的引脚组 }; ``` ##### (3)优化信号完整性 - 检查PCB设计中I2C线路的走线长度和负载电容。过长的走线或过高的负载电容会导致信号衰减,增加`timeout`风险。 - 在必要时添加上拉电阻(通常为4.7kΩ),以增强信号强度。 ##### (4)调试工具验证 使用`i2c-tools`进行调试,验证通信是否正常。例如: ```bash # 读取寄存器值 [root@rk3399:/]# i2cget -f -y 0 0x20 0xa # 写入寄存器值 [root@rk3399:/]# i2cset -f -y 0 0x20 0xa 0x02 ``` 通过上述命令测试通信是否成功[^1]。 ##### (5)驱动程序优化 如果问题仍然存在,可以尝试优化I2C驱动程序。例如,在`i2c-rockchip.c`中调整`scl_rate`参数[^3]: ```c struct i2c_msg xfer_msg; xfer_msg[0].addr = client->addr; xfer_msg[0].len = num; xfer_msg[0].flags = client->flags; xfer_msg[0].buf = buf; xfer_msg[0].scl_rate = 100 * 1000; // 设置为100kHz ``` #### 3. 注意事项 - 在修改设备树或驱动程序后,需重新编译内核并刷写固件。 - 如果问题涉及特定硬件模块(如RTC芯片),需参考对应芯片的数据手册,确保I2C地址和寄存器配置正确。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值