Dieser Thread war jetzt mal Anlaß, ein kurzes How-To zu schreiben zu i2c-EEPROM's. Da der dortige TO ja keine Antworten wünscht, hab ich mal hier meine Basteleien zusammengefasst.
Für verschiedene Typen von i2c-EEPROM's gibt es bei Linux den Kernel-Treiber at24. Im Folgenden ein Beispiel mit einem AT24C32, wie man i2c-EEPROM's auf dem Raspberry Pi verwenden kann.
Getestet mit folgendem System:
Raspberry Pi 2 Model B Rev 1.1 mit aktuellem Archlinuxarm und einem EEPROM Atmel AT24C32, der als Beigabe auf einem RTC-Uhrenmodul verbaut ist. Anschluß des Moduls an i2c1 (Pin3, GPIO8, SDA und Pin5, GPIO9, SCL). Der EEPROM hat die i2c Adresse 0x50.
Zuerst ein DT-Overlay erstellen:
$cat at24c32-overlay.dts
/*
* DT-Overlay für I2C-EEPROM AT24C32
*/
/dts-v1/;
/plugin/;
/{
compatible = "brcm,bcm2835";
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
at24: at24@50 {
compatible = "atmel,24c32";
reg = <0x50>;
size = <4096>;
pagesize = <32>;
status = "okay";
};
};
};
};
Display More
In eine .dtbo-Datei umwandeln mit:
$dtc -@ -Hepapr -I dts -O dtb -o at24c32.dtbo at24c32-overlay.dts
und ins Overlay-Verzeichnis kopieren:
#cp at24c32.dtbo /boot/overlays/at24c32.dtbo
Eintrag in die /boot/config.txt
dtoverlay=at24c32
und den RasPi neu starten.
Danach kann man prüfen, ob der Treiber geladen, sieht bei mir so aus:
Der Speicher liegt dann unter /sys/bus/i2c/devices/1-0050/eeprom für die von mir verwendeten Einstellung Bus i2c1 und Adresse 0x50.
Jetzt man kann den EEPROM löschen z.B.
#dd if=/dev/zero of=/sys/bus/i2c/devices/1-0050/eeprom bs=4
oder mit Zufallszahlen beschreiben
#dd if=/dev/random of=/sys/bus/i2c/devices/1-0050/eeprom bs=4
und sich anzeigen lassen z.B. mit:
hexdump -C eeprom | more
kurzes Demo-Programm in C zur Verwendung des EEPROM für eigene Projekte:
/*
* Demo i2c-EEPROM schreiben und lesen
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#define EEPROM "/sys/bus/i2c/devices/1-0050/eeprom"
#define BUFFSIZE 32
int main(int argc, char* argv[]) {
char *text;
char *write_buff[BUFFSIZE] = {0};
char *read_buff[BUFFSIZE] = {0};
uint16_t offset;
int fd;
int ret;
int len;
char buff[32];
time_t now = time(NULL);
fd = open(EEPROM, O_RDWR);
offset = 0x100;
text = "Hallo Welt, Hallo EEPROM";
len = strlen(text) + 1;
memcpy(write_buff, text, len);
ret = pwrite(fd, (void *) write_buff, len, offset);
offset = 0x200;
sprintf(buff, "%s\n", ctime(&now));
len = strlen(buff) +1;
memcpy(write_buff, buff, len);
ret = pwrite(fd, (void *) write_buff, len, offset);
offset = 0x100;
ret = pread(fd, read_buff, BUFFSIZE ,offset);
printf("EEPROM gelesen von Offset: 0x%X, Anz. Bytes: %d\n", offset, ret);
printf("gelesener Text - %s\n", read_buff);
offset = 0x200;
ret = pread(fd, read_buff, BUFFSIZE ,offset);
printf("EEPROM gelesen an Offset: 0x%X, Anz. Bytes %d\n", offset, ret);
printf("gelesener Text - %s\n", read_buff);
close(fd);
return 0;
}
Display More
Das Programm ist sicherlich nicht schön
, ohne jegliche Fehlerbehandlung etc., und soll nur das Prinzip verdeutlichen.
Wer mag, kann das auch mit Python versuchen, lt. Internet gibt es für Python unter Linux z.B. auch die Funktionen os.preadv() und os.pwritev(). Mit Python kenne ich mich aber überhaupt nicht aus.![]()
Wichtig
: bitte alles euren örtlichen Gegebenheiten anpassen, insbesondere den Typ des verwendeten EEPROM's, die i2c-Adresse, den verwendeten i2c-Bus und alle Pfade (u.a. /boot/config.txt und /boot/overlays/ vs. /boot/firmware/config.txt und /boot/firmware/overlays
einige Links zum Weiterlesen:
Quelltext at24.c: https://github.com/raspberrypi/li…c/eeprom/at24.c
DT Bindings für Linux z.B. hier: https://elixir.bootlin.com/linux/latest/s…eprom/at24.yaml
Offizielle RasPi Dokumentation zu Overlays: https://www.raspberrypi.com/documentation/…tion.html#part2
anderes Projekt mit dem AT24C256: https://lektiondestages.art.blog/2020/03/20/usi…evice-overlays/, ist aber evtl. nicht mehr top-aktuell.
Fehlerkorrekturen und Ergänzungen zum How-To sind willkommen, allgemeine Anfragen bei Problemen bitte besser in einem eigenen Thema in einen entsprechende Unterforum stellen.
Allen Foristen viel Spaß bei euren Projekten.
Gruß Martin