当前位置: 首页 > news >正文

Android硬件调试踩坑记:手把手教你编译i2c-tools并搞定16位地址读写

Android硬件调试实战:从源码编译i2c-tools到16位地址读写全解析

当你在调试一块Android开发板上的I2C设备时,是否遇到过这样的困境:系统自带的i2c-tools缺少关键功能,或者从网上下载的预编译二进制文件根本无法执行?这几乎是每个嵌入式Android开发者都会遇到的典型场景。本文将带你从问题根源出发,一步步构建完整的解决方案。

1. 为什么需要自己编译i2c-tools

在Android硬件开发中,I2C总线调试是基本功。标准的i2c-tools包含i2cdetect、i2cget、i2cset等工具,但当你面对以下情况时,系统自带的版本往往力不从心:

  • 16位寄存器地址读写需求:现代传感器芯片(如高精度陀螺仪、环境传感器)普遍采用16位地址空间,而标准i2cget/i2cset仅支持8位地址
  • 预编译二进制兼容性问题:直接从Linux移植的二进制文件常因架构不匹配导致"not executable: 64-bit ELF file"错误
  • 功能残缺:很多Android系统镜像中的i2c-tools缺少关键工具如i2ctransfer

实际案例:某型号触摸屏IC的配置寄存器位于0x2145,使用i2cget读取时始终返回错误,这正是因为标准工具无法处理16位地址。

2. 搭建Android交叉编译环境

编译适用于Android设备的i2c-tools需要准备以下环境:

2.1 基础环境配置

# 安装必要的编译工具链 sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \ lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev \ libgl1-mesa-dev libxml2-utils xsltproc unzip

2.2 获取Android源码(或至少NDK)

对于完整编译,建议下载AOSP源码:

repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r48 repo sync -c -j4

若只需NDK:

wget https://dl.google.com/android/repository/android-ndk-r23b-linux-x86_64.zip unzip android-ndk-r23b-linux-x86_64.zip

3. 编译i2c-tools全流程

3.1 获取i2c-tools源码

推荐从kernel官方仓库获取最新版本:

git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git cd i2c-tools

3.2 编写Android.mk

在i2c-tools根目录创建Android.mk文件,内容如下:

LOCAL_PATH:= $(call my-dir) ################### i2c-tools ######################### include $(CLEAR_VARS) LOCAL_MODULE := i2c-tools LOCAL_SRC_FILES := \ tools/i2cbusses.c \ tools/util.c \ lib/smbus.c LOCAL_C_INCLUDES += \ $(LOCAL_PATH) \ $(LOCAL_PATH)/include include $(BUILD_STATIC_LIBRARY) ################### i2ctransfer ####################### include $(CLEAR_VARS) LOCAL_MODULE:=i2ctransfer LOCAL_SRC_FILES:= \ tools/i2ctransfer.c LOCAL_C_INCLUDES += \ $(LOCAL_PATH) \ $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES:= \ libc LOCAL_STATIC_LIBRARIES := \ i2c-tools LOCAL_CPPFLAGS += -DANDROID include $(BUILD_EXECUTABLE) # 类似地添加i2cdetect、i2cget、i2cset、i2cdump的模块定义

3.3 执行编译

在AOSP环境下:

source build/envsetup.sh lunch # 选择对应设备 mmm external/i2c-tools/

使用NDK独立编译:

export NDK=/path/to/your/ndk $NDK/ndk-build APP_ABI=armeabi-v7a,arm64-v8a

4. 部署与验证

编译生成的二进制文件位于:

  • AOSP:out/target/product/[device]/system/bin/
  • NDK:libs/[arch]/

推送至设备:

adb root adb remount adb push i2ctransfer /system/bin/ adb shell chmod 755 /system/bin/i2ctransfer

验证工具可用性:

adb shell i2ctransfer -h

5. 16位地址读写实战技巧

5.1 基本读写操作

读取16位地址寄存器(示例:设备地址0x36,寄存器0x5081):

i2ctransfer -f -y 1 w2@0x36 0x50 0x81 r3
  • w2:写入2字节(地址高位0x50和低位0x81)
  • r3:读取3个连续寄存器的值

写入16位地址寄存器(示例:向0x0971写入0xAA):

i2ctransfer -f -y 1 w3@0x36 0x09 0x71 0xAA

5.2 常见问题排查

错误现象可能原因解决方案
Permission denied缺少root权限adb root后重试
Remote I/O error设备未上电/地址错误检查设备供电和I2C地址
Device busy其他进程占用总线排查冲突驱动
Invalid parameter命令格式错误检查字节数匹配

5.3 高级用法:批量读写

连续读取多个16位地址寄存器:

i2ctransfer -f -y 1 w2@0x36 0x50 0x81 r3 w2@0x36 0x60 0x00 r4

混合读写操作:

i2ctransfer -f -y 1 w3@0x36 0x09 0x71 0xAA w2@0x36 0x10 0x20 r2

6. 调试技巧与最佳实践

  1. 总线扫描优先:使用i2cdetect确认设备地址是否正确响应

    i2cdetect -y 1
  2. 权限管理:在非root环境下,可配置udev规则或SELinux策略

  3. 脚本化调试:将常用操作封装为shell脚本提高效率

    #!/system/bin/sh for addr in $(seq 0x10 0x20); do i2ctransfer -f -y 1 w2@0x36 $((addr>>8)) $((addr&0xFF)) r1 done
  4. 逻辑分析仪辅助:当软件调试无果时,用硬件工具抓取实际总线信号

  5. 电源管理注意:某些I2C设备在低功耗模式下会不应答,确保电源状态正确

7. 性能优化与稳定性保障

在长时间或高频次I2C操作时,需注意:

  • 总线速度配置:根据设备能力调整I2C时钟频率

    echo 100000 > /sys/bus/i2c/devices/i2c-1/clock-frequency
  • 错误重试机制:在脚本中添加自动重试逻辑

    retries=3 while [ $retries -gt 0 ]; do i2ctransfer ... && break retries=$((retries-1)) sleep 0.1 done
  • 温度影响:极端温度下I2C时序可能漂移,必要时降低总线速度

  • 信号质量检查:用示波器测量SCL/SDA的上升沿时间,确保符合规范

经过完整的编译、部署和调试流程后,你将获得一套完全适配目标设备的i2c-tools,能够自如应对各种复杂的I2C设备调试场景。记得在关键操作前备份重要寄存器,一个看似简单的写操作可能导致设备进入不可预期的状态。

http://www.jsqmd.com/news/673288/

相关文章:

  • 告别龟速!3分钟掌握城通网盘高速下载秘籍:ctfileGet完全指南
  • 告别臃肿备份!手把手教你用DISM命令+配置文件,精准排除Windows系统垃圾文件
  • 告别Sprite Packer!Unity 2020+新版Sprite Atlas保姆级配置指南(含2D Sprite包导入)
  • 白宫顶着禁令部署Anthropic新模型Mythos,前沿大模型成美国网络安全新焦点
  • 2026年论文摘要AI率超高专项处理攻略:摘要部分降AI完整方案
  • 别只装双系统!用Surface Pro 7打造移动安全工作站:Kali渗透测试环境配置全记录
  • 告别TTTTTT:深入理解U-Boot NFS协议兼容性与Ubuntu内核版本的关联
  • DeepSeek总结的令人惊叹的客户端 Markdown:markdeep
  • 3分钟掌握文件秒传工具:免安装网页版文件分享解决方案
  • STM32F429 SPI读写W25Q128 Flash实战:从引脚配置到数据存储的完整流程
  • 如何用bili2text快速将B站视频转换为文字稿
  • 别再被Git的‘无法快进’卡住了!手把手教你用rebase和merge --no-ff搞定分支合并冲突
  • 别再硬编码了!用Activiti TaskListener实现动态任务指派与自动抄送(Spring Boot实战)
  • 海外短剧平台搭建 - 多支付多语言短剧系统 - 包 Google Play/App Store 上架
  • 别再死磕协议文档了!用MIPI M-PHY和UniPro的视角,重新理解UFS2.2的‘挡位’与‘车道’
  • 构建繁体中文手写识别系统的终极数据解决方案
  • 2026年怎么搭建OpenClaw?京东云1分钟萌新教程含大模型API与Skill配置
  • Git提交历史一团糟?试试用IDEA的Rebase功能来‘整理桌面’,让主线清晰如丝
  • 别再让ES报错‘Native controller process has stopped’了!Linux下非root用户启动的完整避坑指南
  • AI收费告别“单一Token时代”:计费单位裂变,价值分层重构企业预算语言
  • 如何快速掌握网站离线下载:Python网站下载器完整指南
  • 从‘命令行过长’报错,聊聊Windows、Linux和Mac下Spring Boot启动命令的长度限制与应对
  • 告别野路子!用STM32CubeMX HAL库点亮LED,这才是新手该学的标准流程
  • 如何用7款免费开源思源宋体CN彻底解决你的中文排版难题?
  • 从PCB自动布线到算法面试:动态规划解决‘最大不相交子集’问题的两种实战场景
  • TVS管选型避坑指南:为什么你的高速USB/HDMI接口保护总失效?可能是结电容没选对
  • SketchUp选择工具全解析:从点选到反选,6种技巧提升建模效率
  • STM32F030 IAP实战:手把手教你搞定Cortex-M0中断向量表重映射(附完整代码)
  • 2026年4月大件运输物流公司推荐,南京大件物流/跨省运输/超重货物运输物流公司,专业可靠之选 - 品牌推荐用户报道者
  • Modelsim新手避坑指南:手把手教你用.vt和.v文件搞定Verilog仿真(附Quartus II 13.1工程)