1. I2C驱动在Uboot中的重要性
I2C总线在嵌入式系统中扮演着神经末梢的角色,它连接着各种传感器、EEPROM、PMIC等关键外设。在Uboot启动阶段,I2C驱动的重要性尤为突出——它负责初始化硬件配置、读取关键设备信息、配置电源管理芯片等关键操作。想象一下,如果没有可靠的I2C驱动,就像一个人失去了触觉和温觉,无法感知外部环境。
在Uboot的发展历程中,I2C驱动的实现方式经历了从传统模式到设备树驱动模型(DM)的演进。这两种模式各有特点:传统模式直接了当,适合简单场景;DM模式则更加结构化,适合复杂系统。这就好比从手工打造零件到标准化流水线的转变,前者灵活但难以规模化,后者规范但需要更多前期设计。
2. 传统SYS_I2C驱动模式详解
2.1 配置与初始化
要启用传统I2C模式,需要在配置文件中定义CONFIG_SYS_I2C宏。这个宏就像是打开传统模式的开关,告诉Uboot:"我要使用老式的I2C驱动了"。具体到代码中,你会在类似include/configs/xxx.h的文件中找到这样的定义:
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_SYS_I2C_SLAVE 0x7F
初始化过程通常发生在board_init_f阶段,系统会调用i2c_init函数来设置I2C控制器。这里有个实际项目中的经验:我曾经遇到过I2C初始化失败的情况,最后发现是board_init_f调用太早,GPIO控制器还没准备好。解决方法是在board_init_r阶段重新初始化I2C。
2.2 核心API接口
传统模式提供了一套直白的API,就像给你的工具箱里放了几把趁手的扳手:
/* 设置当前使用的I2C总线 */
int i2c_set_bus_num(unsigned int bus);
/* 基础读写函数 */
int i2c_read(uint8_t chip, unsigned int addr, int alen, uint8_t *buffer, int len);
int i2c_write(uint8_t chip, unsigned int addr, int alen, uint8_t *buffer, int len);
/* 寄存器级快捷操作 */
uint8_t i2c_reg_read(uint8_t addr, uint8_t reg);
void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val);
这些函数都实现在drivers/i2c/i2c_core.c文件中。在实际使用中,我发现i2c_reg_read/write这对函数特别方便,它们封装了常见的寄存器操作模式。比如读取温度传感器LM75的数据:


2391

被折叠的 条评论
为什么被折叠?



