www.mikrocontroller.net

Forum: GCC Variablen im EEProm ablegen


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Jörg B. (joerg-sh)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ich möchte mit meinem STM32 diverse verschiedene Variablen im EEProm 
ablegen.
Schreiben und Lesen funktioniert schon.

Wie gestalte ich das am besten. Zu jeder Variablen brauche ich ja die 
Adresse im EEProm. Wie organisiert man so etwas am besten in C?


Grüße

Jörg

Autor: Proteino (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Kommt darauf an aus wie vielen Funktionen und Modulen du auf EEProm 
zugreifen willst.

am einfachsten ist mit #define
// ein Struct was das und das macht
#define PLACE_STRUCT_1   0
#define SIZE_STRUCT_1    (sizeof(struct1))

// noch so ein tolles
#define PLACE_STRUCT_2   (PLACE_STRUCT_1 + SIZE_STRUCT_1)
#define SIZE_STRUCT_2    (sizeof(struct2))

//mal ein Array
#define PLACE_ARRAY_1    (PLACE_STRUCT_2 + SIZE_STRUCT_2)
#define SIZE_ARRAY_1     ( 2 * NUMBER_OF_ELEMENTS)

Autor: Noname (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
>Ich möchte mit meinem STM32 diverse verschiedene Variablen im EEProm
ablegen.

Also diverse Variablen wären ja kein Problem gewesen.
Verschiedene auch nicht.
Aber was zur H... sind diverse verschiedene Variablen.
Sind die schon tot?
Naja. Muss ich nicht wissen. ;-)

Autor: A. K. (prx)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jörg B. schrieb:

> Wie gestalte ich das am besten. Zu jeder Variablen brauche ich ja die
> Adresse im EEProm. Wie organisiert man so etwas am besten in C?

(1) Man kann den Compiler&Linker dazu überreden, eine bestimmte Section 
ins EEPROM zu legen. Muss man aber erst einmal rauskriegen wie das geht 
und wenn man Pech hat werden Adressen irgendwann bei Neuübersetzung neu 
gemischt.

(2) Man kann eine Struct definieren, die alle EEPROM Variablen enthält. 
Ob man die dann geschlossen da reinschmeisst, oder komponentenweise, das 
kann man sich aussuchen. Übersichtlich, gut reproduzierbar und man kann 
die Struct ins RAM legen. Leider nicht sonderlich modular, weil sehr 
zentral. Eignet sich nur dann auch für Flash, wenn die Anzahl Änderungen 
überschaubar bleibt.

(3) Man den Inhalt als einen Datenstrom aus getaggten Daten betrachtet. 
D.h. eine Variable besteht aus ID, Länge und Inhalt. Neue und geänderte 
werden überschrieben (EEPROM) oder angehängt (Flash). Bisschen 
umständlich, funktioniert aber insbesondere bei Flash als persistentem 
Speicher recht gut. Viele Controller haben kein EEPROM, unterstützen 
aber Flash als Variablenspeicher, natürlich mit gewissen Einschränkungen 
im Umgang.

Autor: Jörg B. (joerg-sh)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
@ noname

int, float, char usw. halt.


@ Proteino danke schon mal für deine Hilfe.

mein bisheriger Code sieht ja so aus
  /* First write in the memory followed by a read of the written data --------*/
    /* Write on I2C EEPROM from sEE_WRITE_ADDRESS1 */
    sEE_WriteBuffer(Tx1_Buffer, sEE_WRITE_ADDRESS1, BUFFER_SIZE1);

    /* Wait for EEPROM standby state */
    sEE_WaitEepromStandbyState();

    /* Set the Number of data to be read */
    NumDataRead = BUFFER_SIZE1;

    /* Read from I2C EEPROM from sEE_READ_ADDRESS1 */
    sEE_ReadBuffer(Rx1_Buffer, sEE_READ_ADDRESS1, (uint16_t *)(&NumDataRead));


Wie kann ich denn jetzt mit dem Struct mal so als Beispiel eine Int und 
eine Float Variable speichern.

Autor: Proteino (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
> (2) Man kann eine Struct definieren, die alle EEPROM Variablen enthält.
> Ob man die dann geschlossen da reinschmeisst, oder komponentenweise, das
> kann man sich aussuchen.

> (1) Man kann den Compiler&Linker dazu überreden, eine bestimmte Section
> ins EEPROM zu legen.

EEPROMs sind idR. langsam, ziehen ordentlich Strom (viele interne 
EEPROMs sind aus diesem Grund manchmal garnicht zu gebrauchen) und 
verkraften nur eine endliche Anzahl an Schreibzyklen.

Gerade dein erster Vorschlag ist deswegen für Anfänger nicht zu 
empfehlen da die idR. nicht wissen was sie tun ;)

Jörg B. schrieb:
> mein bisheriger Code sieht ja so aus
>...

Ich kenne nicht die Prototypen deiner Funktionen aber das
(uint16_t *)(&NumDataRead)
in dem Funktionsaufruf
sEE_ReadBuffer(Rx1_Buffer, sEE_READ_ADDRESS1, (uint16_t 
*)(&NumDataRead));
sieht komisch aus.

ansonsten:
typedef struct
{
    uint8_t  stunde
    uint8_t  minute
    uint8_t  sekunde
}ST_UHRZEIT

#define POS_UHRZEIT_START  0
#define SIZE_UHRZEIT_START sizeof(ST_UHRZEIT)

#define POS_UHRZEIT_ENDE   (POS_UHRZEIT_START + SIZE_UHRZEIT_START)
#define SIZE_UHRZEIT_ENDE  sizeof(ST_UHRZEIT)

ST_UHRZEIT aktuelle_uhrzeit;
get_time(&aktuelle_uhrzeit);

...

if(irgendwas)
{
    sEE_WriteBuffer( (char*)&aktuelle_uhrzeit, POS_UHRZEIT_ENDE, SIZE_UHRZEIT_ENDE);
...
}

möglicherweise geht auch
sEE_WriteBuffer( &aktuelle_uhrzeit, POS_UHRZEIT_ENDE, SIZE_UHRZEIT_ENDE);

Autor: Jörg B. (joerg-sh)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Prototype der Funktion:
void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)

Ich denke ich habe es jetzt prinzipiell verstanden.

Werde es morgen mal versuchen umzusetzen.

In der Typedef kann ich sicher auch unterschiedliche Typen verwenden.

Hinter uint8_t* pBuffer versteckt sich ein Zeiger oder? Ich glaube 
darüber schon mal etwas gelesen zu haben.

Autor: A. K. (prx)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Proteino schrieb:

> Gerade dein erster Vorschlag ist deswegen für Anfänger nicht zu
> empfehlen da die idR. nicht wissen was sie tun ;)

Vorschlag (1) dient nur der Adresszuordnung. Unter den mir bekannten 
Controller ist sowieso keiner, der es erlaubt, direkt per adressiertem 
Schreibbefehl ins EEPROM zu schreiben.

Autor: dude (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
hi,

such mal bei ST nach eeprom emulation für den STM32. Da gibts ne 
Application note und ne lib. Dann schreibst du dir deinen Flash auch 
nicht so schnell kaputt..

gruß

Autor: Jörg B. (joerg-sh)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
@dude,
ist mir bekannt. Es geht ja auch nicht ums schreiben sondern adressieren 
der Daten...

Autor: Proteino (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jörg B. schrieb:
> Prototype der Funktion:
>
> void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t
> NumByteToWrite)
> 
>
> Ich denke ich habe es jetzt prinzipiell verstanden.
>
> Werde es morgen mal versuchen umzusetzen.
>
> In der Typedef kann ich sicher auch unterschiedliche Typen verwenden.
>
> Hinter uint8_t* pBuffer versteckt sich ein Zeiger oder? Ich glaube
> darüber schon mal etwas gelesen zu haben.

Ja. du musst also die Daten die du schreiben willst auf einen uint8_t* 
casten.

z.B. hast du ein Array aus uint16:
uint16_t array[5];

sind also insgesamt 10 Byte.
Zuerst holst du dir jetzt die Adresse des Arrays mit "&array[0]" oder 
"array".
Dannach behauptest du noch, es wären 8Bit unsigned int die sich hinter 
dem Zeiger verbergen mit:
"(uint8_t*)&array[0]" oder
"(uint8_t*)array"
damit deine eeprom-Funktion diese schreiben kann:
sEE_WriteBuffer( (uint8_t*)array, POSITION, 10);

Bei Enums, Structs und Unions funktioniert das im Prinzip dann genau so.

Autor: Proteino (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Nachtrag:

Jörg B. schrieb:
> (uint16_t *)(&NumDataRead)

Das ist tatsächlich Quatsch und müsste eigentlich zu einem Fehler oder 
zumindest einer Warnung bei Compilieren führen.

Mit dem Code übergibst du nämlich einen Zeiger und nicht die Zahl die an 
der Position hinterlegt ist. Lass das (uint16_t *)(& ) weg.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net