gpt4 book ai didi

c - 使用 Linux 通过 I2C 读写 EEPROM

转载 作者:IT王子 更新时间:2023-10-29 00:49:31 27 4
gpt4 key购买 nike

我正在尝试读写 Atmel 24C256 EEPROM使用基于 I2C 的 Raspberry Pi B+,但我无法使其正常工作。

这是我目前的代码:

#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("%s\n", strerror(errno));
exit(1);
}
if(ioctl(file_desc, I2C_SLAVE, DEVICE_ADDR) < 0)
{
printf("%s\n", 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(): %s\n", strerror(errno));
return -1;
}

return 0;

}

int read_from_device(char addr_hi, char addr_lo, char * buf, 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 work\n");
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,I2C_RDWR,&msg_rdwr)<0)
{
printf("read_from_device(): %s\n", 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, 0x00, newbuf, PAGE_SIZE)>0)
{
printf("%s\n", newbuf);
}


teardownI2C(); //cleanup
return EXIT_SUCCESS;
}

write_to_device(0x01, 0x00, buffer, PAGE_SIZE); 这样的行写入设备不会产生任何错误,但是当我尝试从设备读取时,我必须写一个根据规范表“虚拟”字节,然后尝试从设备读取,但由于某种原因写入虚拟字节会导致错误“输入/输出错误”。我不知道这是怎么回事。我正在使用两个资源来指导我,Linux I2C-Dev documentation和来自 similar EEPROM device. 的示例我有点被困在这里,不知道该尝试什么。非常感谢任何建议或指示!

最佳答案

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

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

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

对于您的设备,您将指定 compatible = "at,24c256";

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

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

关于c - 使用 Linux 通过 I2C 读写 EEPROM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29932003/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com