以下是对您提供的博文内容进行深度润色与结构重构后的技术文章。全文已彻底去除AI生成痕迹,采用真实嵌入式工程师口吻撰写,逻辑更自然、节奏更紧凑、语言更精炼,并强化了实战指导性与教学感;同时严格遵循您提出的全部格式与风格要求(如禁用模板化标题、不设“总结”段、无参考文献、无Mermaid图代码、结尾顺势收束等):
I2C EEPROM在Linux设备树下的“活”法:从焊点到读写,一气呵成
你有没有遇到过这样的现场?
板子上明明焊着一颗AT24C02,U-Boot里i2cdetect -y 1却扫不到0x50;
或者好不容易看到设备节点出现在/sys/bus/i2c/devices/下,一写数据就卡住,再读出来全是0xFF;
又或者驱动加载成功了,但dd if=/dev/urandom of=/sys/.../eeprom bs=1 count=16之后,断电重启发现啥都没存住……
这不是芯片坏了,也不是代码写错了——而是设备树没说清楚,内核没听明白,应用没踩对点。
今天我们就把这件事掰开揉碎,不讲虚的,只讲你在调试桌上真正会碰到的每一个环节:从那颗小小的EEPROM焊在PCB哪个位置开始,到最终用几行C代码把它读出来、写进去,中间所有容易被忽略的细节、文档里没明说的潜规则、甚至数据手册字缝里的提示,全都摊开来讲。
设备树不是配置文件,是“硬件说明书”
很多人把.dts当成一个可有可无的配置项,改完编译烧进去,行就行,不行就再试一次。但其实,设备树是SoC启动时,内核唯一能“看懂”的硬件说明书。它不负责初始化寄存器,但它决定了“谁该被初始化”、“按什么规格初始化”。
以I2C控制器为例,比如i.MX6ULL上的i2c1,它的DTS节点不能只写个status = "okay"就完事。你得告诉内核三件事:
- 这条总线跑多快?→
clock-frequency = <400000> - SDA/SCL接到哪几个GPIO?电气特性怎么设?→
pinctrl-0 = <&pinctrl_i2c1> - 它下面挂了啥?地址多少?型号是啥?→ 子节点
eeprom@50
这三点缺一不可。漏掉pinctrl,信号根本不出脚;clock-frequency设太高,示波器一看SCL就是一堆振铃;而如果eeprom@50里忘了compatible,哪怕地址对、