AT24系列EEPROM芯片是Atmel(现为Microchip)推出的常用串行存储器件,通过I2C接口与主控制器通信,具有容量范围广(从1Kb到256Kb)、低功耗、非易失性等特点,广泛应用于工业控制、消费电子等领域,用于存储设备配置、校准参数、序列号等少量关键数据,在Linux系统中,针对AT24芯片的驱动程序为上层应用提供了标准化的访问接口,简化了硬件操作流程。

AT24芯片硬件特性与驱动定位
AT24系列EEPROM的核心硬件特性包括:支持I2C协议(标准模式100kHz,快速模式400kHz),容量从128字节(AT24C01)到32KB(AT24C256)不等,采用页写入机制(每页8-256字节不等,具体型号不同),数据保存时间可达100年,擦写次数达100万次,其I2C设备地址通常由A0、A1、A2引脚电平决定,支持同一总线上挂载多片芯片(最多8片)。
Linux驱动作为硬件与应用层之间的桥梁,主要功能包括:解析设备树或平台数据初始化硬件参数、管理I2C通信事务、处理读写操作的页边界限制、提供统一的字符设备接口或sysfs属性,并确保数据访问的原子性与安全性,驱动位于内核的drivers/misc/eeprom/at24.c文件,属于I2C设备驱动范畴,依赖I2C核心子系统。
Linux驱动架构与核心数据结构
AT24驱动的核心架构围绕I2C设备驱动模型展开,主要涉及以下数据结构:
-
i2c_client结构:内核中用于表示I2C设备的实体,包含设备地址、适配器指针、设备树节点引用等信息,由驱动在probe阶段从设备树或平台数据中解析填充。
-
at24_data结构:驱动的私有数据结构,存储芯片特有参数,包括:页大小(page_size)、总容量(size)、是否支持线性地址(linear)、读写标志位(flags)等,AT24C02的页大小为8字节,容量为256字节,这些参数直接影响读写操作的地址计算与数据对齐。
-
file_operations结构:定义字符设备的操作接口,包括read(读取数据)、write(写入数据)、ioctl(设备控制)等函数,使应用层可通过标准文件操作访问EEPROM。
驱动通过I2C核心提供的i2c_smbus_write_byte_data、i2c_smbus_read_i2c_block_data等函数完成底层通信,这些函数封装了I2C总线的时序细节,驱动无需直接操作硬件寄存器。
驱动初始化与设备注册流程
AT24驱动的初始化始于模块加载或设备树解析,主要流程如下:

-
设备树匹配:驱动通过of_device_id表匹配设备树中的节点,节点需包含compatible属性(如”atmel,24c02″)、reg属性(I2C地址)、pagesize属性(页大小)等关键信息。
eeprom@50 { compatible = "atmel,24c02"; reg = <0x50>; pagesize = <8>; size = <256>; }; -
probe函数执行:当匹配成功后,驱动调用at24_probe函数,完成以下工作:
- 分配at24_data结构体,从设备树或平台数据中读取页大小、容量等参数;
- 初始化I2C客户端,设置设备地址与适配器;
- 注册字符设备(通过register_chrdev_region或device_create),创建/dev/at24设备节点;
- 创建sysfs属性节点(如”size”、”page_size”),方便用户查看设备信息;
- 初始化读写锁(mutex),防止并发访问导致数据错乱。
-
错误处理:若初始化失败(如I2C通信超时、内存分配失败),驱动会执行清理操作,释放已分配的资源,确保系统状态一致。
读写操作实现与页处理机制
AT24芯片的读写操作需严格遵循其硬件规范,尤其是页写入限制:
-
读操作:应用层通过read系统调用触发驱动中的at24_read函数,流程为:
- 计算EEPROM内部地址(需检查是否超出容量范围);
- 分多次读取(若跨页),每次通过I2C总线发送地址+读取命令;
- 将数据拷贝到用户空间缓冲区,处理内存访问异常(如EFAULT)。
-
写操作:write函数实现相对复杂,需处理页边界:
- 计算写入起始地址在页内的偏移量,若当前页剩余空间不足,则分多次写入;
- 每次写入不超过一页数据,通过I2C总线发送地址+数据;
- 写入后需等待芯片内部写入周期完成(可通过读取状态寄存器或延时5ms实现),避免数据覆盖;
- 锁定操作期间,其他进程的写请求将被阻塞,确保数据一致性。
若AT24C02的页大小为8字节,写入地址为6,长度为5字节,则实际写入会从地址6开始,覆盖6-13字节(跨页),驱动需拆分为两次写入(6-7字节和8-13字节)。
驱动配置与应用实践
在实际应用中,AT24驱动的使用需结合硬件设计与系统配置:

-
设备树配置:根据硬件连接设置I2C地址(如A0=0、A1=0、A2=0时地址为0x50),确保与芯片引脚配置一致;明确页大小与容量,避免驱动误判。
-
用户空间访问:应用层可通过标准文件接口操作EEPROM,例如用C语言读取前16字节:
int fd = open("/dev/at24", O_RDONLY); unsigned char buf[16]; read(fd, buf, 16); close(fd);或使用i2c-tools工具(如i2cget、i2cset)直接通过I2C设备节点(如/dev/i2c-1)访问,适用于调试场景。
-
sysfs属性:驱动在/sys/class/at24/at24/目录下暴露size、page_size、name等属性,可通过cat命令查看设备参数,
cat /sys/class/at24/at24/name # 输出: at24, 24c02
注意事项
- 页写入边界:强制写入超过页边界的数据会导致数据覆盖,驱动虽会自动拆分,但应用层需逻辑合理规划写入地址。
- 写入等待时间:EEPROM写入周期较长(约5ms),高频写入场景需注意性能影响,避免阻塞系统调用。
- 多主环境:若I2C总线存在多个主控制器,需通过硬件或软件机制(如I2C总线仲裁)防止冲突。
- 容量适配:不同AT24型号的容量与页大小差异较大,设备树配置需准确,否则可能导致访问越界。
FAQs
Q1:如何通过命令行查看AT24 EEPROM的内容?
A:可使用i2c-tools工具包中的i2cdump命令,例如查看I2C适配器1上地址0x50的AT24C02全部内容:
i2cdump -y 1 0x50
该命令会以十六进制格式显示EEPROM所有地址的数据,适用于快速调试,若需读取指定地址范围,可结合i2cget命令逐字节读取。
Q2:AT24驱动写入数据时,如何确保数据不因掉电丢失?
A:EEPROM本身具有非易失性,写入后数据会自动保存到存储单元,为确保安全,应用层需在写入完成后等待至少5ms(或通过读取状态寄存器确认写入完成),避免在写入过程中掉电,关键数据建议写入后立即校验,通过读取数据与写入数据比对,确保一致性。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/55481.html