加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

使用Linux通过I2C读写EEPROM

发布时间:2020-12-13 23:57:36 所属栏目:Linux 来源:网络整理
导读:我尝试通过I2C读取和写入带有Raspberry Pi B的 Atmel 24C256 EEPROM,但是我无法正常工作. 这是我到目前为止的代码: #include stdio.h#include stdlib.h#include linux/i2c-dev.h#include fcntl.h#include string.h#include sys/ioctl.h#include sys/types.h
我尝试通过I2C读取和写入带有Raspberry Pi B的 Atmel 24C256 EEPROM,但是我无法正常工作.

这是我到目前为止的代码:

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <linux/i2c.h>

#define DEVICE_PATH "/dev/i2c-1"

#define PAGE_SIZE 64

#define DEVICE_ADDR 0x50 // 0b1010xxxx


int file_desc;
char buffer[PAGE_SIZE + 2]; // 64 bytes + 2 for the address

void teardownI2C()
{
    int result = close(file_desc);
}

void setupI2C()
{
    file_desc = open(DEVICE_PATH,O_RDWR);
    if(file_desc < 0)
    {
    printf("%sn",strerror(errno));
    exit(1);
    }
    if(ioctl(file_desc,I2C_SLAVE,DEVICE_ADDR) < 0)
    {
    printf("%sn",strerror(errno));
    teardownI2C();
    exit(1);

    }
}

int write_to_device(char addr_hi,char addr_lo,char * buf,int len)
{
     struct i2c_rdwr_ioctl_data msg_rdwr;
     struct i2c_msg i2cmsg;
     char my_buf[PAGE_SIZE + 2];
     if(len > PAGE_SIZE + 2)
     {
     printf("Can't write more than %d bytes at a time.n",PAGE_SIZE);
     return -1;
     }
     int i;
     my_buf[0] = addr_hi;
     my_buf[1] = addr_lo;

     for(i= 0; i < len; i++)
     {
     my_buf[2+i] = buf[i];
     }
     msg_rdwr.msgs = &i2cmsg;
     msg_rdwr.nmsgs = 1;
     i2cmsg.addr  = DEVICE_ADDR;
     i2cmsg.flags = 0;
     i2cmsg.len   = 2+len;
     i2cmsg.buf   = my_buf;

    if(ioctl(file_desc,I2C_RDWR,&msg_rdwr)<0)
    {
    printf("write_to_device(): %sn",strerror(errno));
    return -1;
    }

    return 0;

}

int read_from_device(char addr_hi,int len)
{
    struct i2c_rdwr_ioctl_data msg_rdwr;
    struct i2c_msg             i2cmsg;



    if(write_to_device(addr_hi,addr_lo,NULL,0)<0)
    {
    printf("read_from_device(): address reset did not workn");
    return -1;
    }

    msg_rdwr.msgs = &i2cmsg;
    msg_rdwr.nmsgs = 1;

    i2cmsg.addr  = DEVICE_ADDR;
    i2cmsg.flags = I2C_M_RD;
    i2cmsg.len   = len;
    i2cmsg.buf   = buf;

    if(ioctl(file_desc,&msg_rdwr)<0)
    {
    printf("read_from_device(): %sn",strerror(errno));
    return -1;
    }


    return 0;
}

void fill_buffer(char *buf)
{
    int i = 0;
    while(i < PAGE_SIZE && *buf)
    {
    buffer[i+2] = *buf++;
    }
    while(i++ < PAGE_SIZE-1)
    {
    buffer[i+2] = '*'; // fill the buffer with something
    }
}


int main()
{

    setupI2C(); //setup

    fill_buffer("Here are some words.");
    write_to_device(0x01,0x00,buffer,PAGE_SIZE);
    char newbuf[PAGE_SIZE];

    if(read_from_device(0x01,newbuf,PAGE_SIZE)>0)
    {
    printf("%sn",newbuf);
    }


    teardownI2C(); //cleanup
    return EXIT_SUCCESS;
}

写入设备,如行write_to_device(0x01,PAGE_SIZE);不会产生任何错误但是当我尝试从设备读取时,我必须根据规格表写一个“虚拟”字节,然后尝试从设备读取但由于某种原因写入虚拟字节会导致错误“输入/输出错误”.我无法弄清楚它是如何工作的.我正在使用两个资源来指导我,Linux I2C-Dev documentation和similar EEPROM device.的一个例子我有点卡在这里,不知道该尝试什么.任何建议或指针都非常感谢!

解决方法

或者,如果您能够为Raspberry Pi编译和安装不同的内核设备树,则可以通过内核at24.c驱动程序访问它.

内核设备树需要指定EEPROM的类型和地址,以及它连接的I2C总线.我不确定Raspberry Pi,但对于BeagleBone Black EEPROM,它是这样的:

&i2c0 {
    eeprom: eeprom@50 {
        compatible = "at,24c32";
        reg = <0x50>;
    };
};

对于您的设备,您需要指定compatible =“at,24c256”;

确保内核配置指定CONFIG_EEPROM_AT24 = y(或= m).

然后,您应该能够从/ sys / bus / i2c / devices / 0-0050 / eeprom或/ sys / bus / i2c / drivers / at24 / 0-0050 / eeprom等用户空间访问EEPROM存储器.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读