[具身智能-575]:RDK Python i2cdev I2C 读写测试代码完整解读

📅 2026/7/20 11:30:28
[具身智能-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 CTRLC 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 个字节数据再把读到的字节原样写回从设备循环反复执行测试支持CtrlC退出。运行环境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 # 捕获CtrlC直接退出程序 def signal_handler(signal, frame): sys.exit(0)signal注册SIGINT键盘中断按下 CtrlC 直接退出死循环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 CTRLC to exit) # 打印系统全部I2C总线节点 /dev/i2c-0 /dev/i2c-1... os.system(ls /dev/i2c*) # 无限循环反复执行I2C读写测试 while True: i2cdevTest()提前注册 CtrlC 中断回调启动先打印所有可用 I2C 总线while True死循环一次测试完成后再次等待输入总线、地址重复读写。三、完整运行流程示例运行脚本sudo python3 i2c_test.py打印所有/dev/i2c-x总线循环进入测试函数输入总线号如1执行i2cdetect -y -r 1打印总线挂载的 I2C 地址表格输入设备十六进制地址如51打开 I2C 总线 1从机地址 0x51读取 1 字节数据打印数值把读到的字节写回 0x51 设备关闭 I2C立刻回到循环开头等待下一次输入按下 CtrlC触发 signal_handler 直接退出程序。四、代码存在缺陷与风险无任何异常捕获总线不存在、设备地址无应答、输入非数字、非法十六进制字符程序直接崩溃I2C 读写失败无重试、无错误提示。eval存在安全风险 用户恶意输入字符会触发代码执行漏洞生产代码应改用int(device, 16)替代 evalpython运行dev_addr int(device, 16)死循环无退出机制 只能靠 CtrlC 强制终止无法通过输入命令正常跳出循环。缺少资源容错 若 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)