Lesen und schreiben von EEPROM via I2C mit Linux
Ich versuche zu Lesen und zu schreiben ein Atmel 24C256 EEPROM mit einem Raspberry Pi B+ über I2C, aber ich habe Mühe, es allen richtig zu arbeiten.
Hier ist der code, den ich bisher:
#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;
}
Schreiben, um das Gerät wie in der Zeile write_to_device(0x01, 0x00, buffer, PAGE_SIZE);
erzeugt keine Fehler, aber wenn ich versuche aus dem Gerät gelesen, ich habe zum schreiben eines "dummy" - byte nach dem Datenblatt, und dann versuchen, aus dem Gerät gelesen, aber aus irgendeinem Grund schreiben der dummy-byte führt zu einem Fehler "Input/output error". Ich kann nicht herausfinden, wie das funktioniert. Ich bin mit zwei Ressourcen, die mich leiten, die Linux-I2C-Dev-Dokumentation und ein Beispiel aus einem ähnlich wie EEPROM-Gerät. bin ich irgendwie hier hängengeblieben und weiß nicht, was zu versuchen. Irgendwelche Vorschläge oder Hinweise sind wir sehr dankbar!
InformationsquelleAutor Jacob Calvert | 2015-04-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alternativ, Sie können es über den kernel -
at24.c
- Treiber, wenn Sie in der Lage zu kompilieren und zu installieren, einen anderen kernel device tree für Ihren Raspberry Pi.Den kernel-Geräte-Baum braucht, um zu geben Sie die EEPROM-Typ und-Adresse, und die I2C-bus angeschlossen. Ich bin mir nicht sicher über Raspberry Pi, aber für den BeagleBone Black EEPROM geht es so:
Für Ihr Gerät, das Sie spezifizieren
compatible = "at,24c256";
Sicher der kernel-config gibt
CONFIG_EEPROM_AT24=y
(oder=m
).Dann sollten Sie in der Lage sein, um Zugriff auf den EEPROM-Speicher aus dem userspace an so etwas wie
/sys/bus/i2c/devices/0-0050/eeprom
oder/sys/bus/i2c/drivers/at24/0-0050/eeprom
.InformationsquelleAutor Craig McQueen
vielleicht dies hier helfen könnte. http://www.richud.com/wiki/Rasberry_Pi_I2C_EEPROM_Program da es behandelt offenbar das Gerät, das Sie versuchen zu Programm und erklärt auch einige Vorbehalte zu adressieren, 24c256
InformationsquelleAutor JD_GRINDER
Mein code:
Ich traf das gleiche problem. Ich fand, es wäre erfolgreich geschrieben werden, wenn die Länge kleiner als 16 bytes. Also habe ich ein makro gemacht ONE_PAGE gleich 16 und machte eine Schleife um die Daten zu schreiben 16 bytes 16 bytes.Ich fand auch 5000us sein sollte, warten Sie nach jeden 16 bytes schreiben.Ich habe versucht 1000us aber fehlgeschlagen ist, wird nur ein Teil der Daten geschrieben.
In der Tat, schreiben, scheitern nichts zu tun hat mit 16 bytes,es wäre erfolgreich geschrieben werden, wenn die Länge mehr oder weniger als 16 bytes.
Hängt vor allem mit der Schreibprozess muss warten
EEPROM schreibt, nehmen Sie zwischen 1 und 5mS. Ich in der Regel warten 5000mS, um sicher zu sein.
InformationsquelleAutor Hong Ji
Kleines und einfaches Programm zu verstehen, das die einfache Verwaltung der ein eeprom
InformationsquelleAutor Zili