You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于iMX8MP的嵌入式设备Linux用户空间EEPROM读取异常求助

排查iMX8MP Linux用户空间读取I2C EEPROM失败的思路

核心问题分析

你的代码使用I2C_SMBUS_WORD_DATA方式读取EEPROM,但大多数I2C EEPROM(如AT24C系列)的访问时序要求先写入起始地址,再连续读取数据,SMBus的单步读操作不符合这个时序,这是导致读取错误的主要原因。

具体排查步骤

1. 验证用户空间基础访问能力

先通过系统工具确认硬件和内核层面的I2C连通性:

  • 执行i2cdetect -y 0(需root权限),查看0x50地址的状态:
    • 若显示UU:说明内核的EEPROM驱动(如at24)已占用该地址,需先卸载驱动:rmmod at24,再测试。
    • 若显示数字(如50):说明地址可被用户空间直接访问。
  • 执行i2cdump -y 0 0x50,查看输出是否与U-boot中i2c md的结果一致:
    • 一致:硬件和内核配置正常,问题出在代码逻辑。
    • 不一致:检查设备树中i2c-0的引脚复用、时钟频率是否匹配EEPROM规格,或硬件接线是否松动。

2. 修正代码的I2C操作逻辑

替换原有的SMBus方式,改用I2C_RDWR ioctl实现符合EEPROM时序的组合读写操作,示例代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#define I2C_ADDRESS 0x50
#define I2C_BUS "/dev/i2c-0"

int main(void)
{
    int file;
    int res;
    unsigned char data[16];
    unsigned char start_addr = 0x00; // 单字节起始地址,适配小容量EEPROM(如AT24C02)

    struct i2c_rdwr_ioctl_data msgset;
    struct i2c_msg msgs[2];

    file = open(I2C_BUS, O_RDWR);
    if (file < 0) {
        perror("open");
        exit(1);
    }

    // 第一步:向EEPROM写入起始读取地址
    msgs[0].addr = I2C_ADDRESS;
    msgs[0].flags = 0; // 写操作
    msgs[0].len = sizeof(start_addr);
    msgs[0].buf = &start_addr;

    // 第二步:连续读取16字节数据
    msgs[1].addr = I2C_ADDRESS;
    msgs[1].flags = I2C_M_RD; // 读操作
    msgs[1].len = sizeof(data);
    msgs[1].buf = data;

    msgset.msgs = msgs;
    msgset.nmsgs = 2;

    res = ioctl(file, I2C_RDWR, &msgset);
    if (res < 0) {
        perror("ioctl I2C_RDWR");
        exit(1);
    }

    printf("Data read: ");
    for (int i = 0; i < sizeof(data); i++) {
        printf("%02x ", data[i]);
    }
    printf("\n");

    close(file);
    return 0;
}

注意:如果是大容量EEPROM(如AT24C16及以上),需要使用双字节地址,将start_addr改为数组unsigned char start_addr[2] = {0x00, 0x00};,并设置msgs[0].len = 2。

3. 检查内核I2C配置

  • 确认设备树中i2c-0的节点配置正确:引脚复用、时钟频率(如clock-frequency = <400000>)需与EEPROM规格匹配。
  • 若不需要内核管理EEPROM,可在设备树中禁用at24驱动的自动探测,或编译内核时移除该驱动模块。

内容的提问来源于stack exchange,提问作者void_brain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:07:02