[具身智能-575]:RDK Python i2cdev I2C 读写测试代码完整解读
·
import sys
import signal
import os
import time
# 导入i2cdev
from i2cdev import I2C
def signal_handler(signal, frame):
sys.exit(0)
def i2cdevTest():
# device, bus = 0x51, 0
bus = input("Please input I2C BUS num:")
os.system('i2cdetect -y -r ' + bus)
device = input("Please input I2C device num(Hex):")
print("Read data from device %s on I2C bus %s" % (device, bus))
# 创建I2C设备
i2c = I2C(eval("0x" + device), int(bus))
# 读取数据
value = i2c.read(1)
i2c.write(value)
print("read value=", value)
i2c.close()
if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler)
print("Starting demo now! Press CTRL+C to exit")
print("List of enabled I2C controllers:")
os.system('ls /dev/i2c*')
while True:
i2cdevTest()
RDK Python i2cdev I2C 读写测试代码完整解读
一、整体功能概述
该脚本基于地平线封装的 i2cdev 库,实现交互式 I2C 设备单字节读写测试:
- 列出系统所有
/dev/i2c-x总线; - 交互式输入 I2C 总线号、从设备十六进制地址;
- 调用
i2cdetect扫描总线上挂载的 I2C 从机; - 读取从设备 1 个字节数据,再把读到的字节原样写回从设备;
- 循环反复执行测试,支持
Ctrl+C退出。
运行环境:RDK X3/X5;依赖自研
i2cdev库,需 root/dialout 权限运行。
二、逐段代码分层解析
1. 头部导入与中断信号处理
python
运行
#!/usr/bin/env python3
import sys
import signal
import os
import time
# 地平线专用I2C用户态操作库
from i2cdev import I2C
# 捕获Ctrl+C,直接退出程序
def signal_handler(signal, frame):
sys.exit(0)
signal:注册SIGINT键盘中断,按下 Ctrl+C 直接退出死循环;i2cdev.I2C:封装底层/dev/i2cX字符设备,提供读写、关闭接口;os:调用系统 shell 工具i2cdetect扫描 I2C 设备。
2. 核心业务函数 i2cdevTest ()
python
运行
def i2cdevTest():
# 1. 输入I2C总线号(数字,如0、1、2)
bus = input("Please input I2C BUS num:")
# 调用系统命令扫描该总线所有I2C从设备地址
os.system('i2cdetect -y -r ' + bus)
# 输入从设备十六进制地址,例如 51、38
device = input("Please input I2C device num(Hex):")
print("Read data from device %s on I2C bus %s" % (device, bus))
# 字符串十六进制转数字:"51" → eval("0x51") = 81
dev_addr = eval("0x" + device)
# 实例化I2C对象:从设备地址、总线编号
i2c = I2C(dev_addr, int(bus))
# 读取1个字节,返回字节数值(0~255)
value = i2c.read(1)
# 将读取到的单字节写回从设备
i2c.write(value)
print("read value=", value)
# 关闭I2C设备句柄,释放总线资源
i2c.close()
关键 API 与逻辑拆解
os.system('i2cdetect -y -r x')-y:自动确认交互,无需手动回车;-r:读扫描,探测总线上在线 I2C 从机;- 作用:可视化查看当前总线存在哪些 I2C 设备,防止地址输入错误。
eval("0x" + device)用户输入字符串如51,拼接成0x51通过 eval 转为十进制整数 81,即 I2C7 位从设备地址。I2C(dev_addr, bus_num)打开/dev/i2c{bus_num}总线,绑定目标从设备地址。i2c.read(1)参数为读取字节长度,此处读取1 个字节,返回 0~255 整型数据。i2c.write(value)写入单字节数值到从设备。i2c.close()关闭 I2C 文件句柄,释放设备占用。
3. 程序入口主逻辑
python
运行
if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler)
print("Starting demo now! Press CTRL+C to exit")
# 打印系统全部I2C总线节点 /dev/i2c-0 /dev/i2c-1...
os.system('ls /dev/i2c*')
# 无限循环,反复执行I2C读写测试
while True:
i2cdevTest()
- 提前注册 Ctrl+C 中断回调;
- 启动先打印所有可用 I2C 总线;
while True死循环:一次测试完成后,再次等待输入总线、地址,重复读写。
三、完整运行流程示例
- 运行脚本:
sudo python3 i2c_test.py - 打印所有
/dev/i2c-x总线; - 循环进入测试函数:
- 输入总线号:如
1 - 执行
i2cdetect -y -r 1,打印总线挂载的 I2C 地址表格; - 输入设备十六进制地址:如
51 - 打开 I2C 总线 1,从机地址 0x51;
- 读取 1 字节数据,打印数值;
- 把读到的字节写回 0x51 设备;
- 关闭 I2C;
- 输入总线号:如
- 立刻回到循环开头,等待下一次输入;
- 按下 Ctrl+C,触发 signal_handler 直接退出程序。
四、代码存在缺陷与风险
- 无任何异常捕获
- 总线不存在、设备地址无应答、输入非数字、非法十六进制字符,程序直接崩溃;
- I2C 读写失败无重试、无错误提示。
eval存在安全风险 用户恶意输入字符会触发代码执行漏洞,生产代码应改用int(device, 16)替代 eval:python
运行
dev_addr = int(device, 16)- 死循环无退出机制 只能靠 Ctrl+C 强制终止,无法通过输入命令正常跳出循环。
- 缺少资源容错 若 I2C 读写中途异常抛出,
i2c.close()不会执行,会持续占用 I2C 总线句柄。 - 仅支持单字节读写,无法指定寄存器地址 常规 I2C 器件需要先发送寄存器地址再读写,本代码仅裸读写从设备,大部分传感器无法正常使用。
- 无权限判断 普通用户运行会报打开
/dev/i2c-x权限失败,必须 sudo。
五、RDK I2C 硬件配套说明
- RDK X5 有多路硬件 I2C 控制器,对应节点
/dev/i2c-0、/dev/i2c-1、/dev/i2c-2; - 每路 I2C 信号:SDA(数据线)、SCL(时钟线),3.3V 电平,外部需 4.7K 上拉电阻;
- 一条总线可挂载多个不同地址 I2C 从机(EEPROM、OLED、陀螺仪、温感芯片);
- 扫描总线命令独立使用:
bash
运行
sudo i2cdetect -y -r 1
六、优化修复片段(替换危险 eval、增加异常捕获)
python
运行
def i2cdevTest():
try:
bus = input("Please input I2C BUS num:")
os.system('i2cdetect -y -r ' + bus)
device = input("Please input I2C device num(Hex):")
# 安全转换十六进制,替代eval
dev_addr = int(device, 16)
bus_num = int(bus)
print("Read data from device 0x%02X on I2C bus %d" % (dev_addr, bus_num))
i2c = I2C(dev_addr, bus_num)
value = i2c.read(1)
i2c.write(value)
print("read value=", value)
i2c.close()
except ValueError:
print("输入格式错误,请输入合法数字/十六进制地址")
except Exception as e:
print("I2C操作失败:", e)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)