Forum: Mikrocontroller und Digitale Elektronik Globale Variablen zur laufzeit erstellen.


von Thomas P. (Firma: privat) (memo)


Lesenswert?

Hallo Leuts und Forenleser,

Nun muss ich mich nach knapp einem Jahr doch mal dem Forum widmen.
Wie die Überschrift schon aussagt, geht es mir um dieses Thema.

Ich habe eine Platine, welche 2 Modi beherschen soll. 1. Modi
über UART EEprom beschreiben, 2. Modi EEprom auslesen. Controller ist 
der Mega8..

Der Wechsel zwischen den Modi erfolgt durch Reset bzw. entfernen der 
Betriebsspannung.
1
if (PIND & (1 << PD0)) {
2
    /*If High Signal from the level converter
3
     * */
4
    PORTC |= (1 << PC3); // Red LED on, UART-Modus
5
    setup_uart();
6
7
}

Damit wird ermittelt, ob an dem UArt-Pin RXD ein Pegelwandler bzw. ein 
SerialAdaper steckt.

Nun sollen im "Uart"-Modus enpfangene Daten im EEProm geschrieben 
werdem.
Das erledige ich mit
1
uint8_t  coor_m[32][8][2]; //"quellblock" aus dem Sram, von Uart Empfangen
2
uint8_t coor[32][8][2] EEMEM; // "Destination EEProm"
3
eeprom_write_block(coor_m, &coor, sizeof(coor_m));

Für jedes empfangende Zeichen über UART wird eine Funktion uart_rec(char 
s)  aufgerufen.
1
uint8_t  coor_m[16][8][2]; //global
2
uart_rec(char UDRr){
3
 ...weise coor_m[][][] Werte zu...
4
....weiterer Algorhytmus
5
}

Wenn nun der EEProm erfolgreich beschrieben wurde, möchte ich in den 2. 
Modi wechseln.

Die Routinen arbeiten aber dann nicht mehr, weil coor_m[16][8][2] so gut 
wie den kompletten Sram frisst.

Ist es irgendwie möglich die Initialisierung von globalen Variable 
coor_m[16][8][2] durch einer if,else Anweisung zu steuern. Diese 
Variable wird im 2. Modi niemals gebraucht.

Ich finde es nachteilig, das der EEProm nur durch die identische Größe 
aus dem SRAM Copiert werden kann.

von Karl H. (kbuchegg)


Lesenswert?

Thomas P. schrieb:

> Ist es irgendwie möglich die Initialisierung von globalen Variable
> coor_m[16][8][2] durch einer if,else Anweisung zu steuern.

Die Initialisierung hilft dir nichts. Denn auch uninitialisiert ist die 
Variable ja trotzdem vorhanden.

Schreib halt die Daten ins EEPROM so wie du sie empfängst mit minimalem 
Zwischenspeichern.

> Ich finde es nachteilig, das der EEProm nur durch die identische Größe
> aus dem SRAM Copiert werden kann.

Ähm.
Wie bitte?
Du kannst das EEPROM byteweise beschreiben wie du lustig bist. Auch ein 
eeprom_write_block macht letzten Endes nichts anderes als Byte für Byte 
ins EEPROM zu schreiben. Sieh diese Funktion als Komfortfunktion an, die 
du benutzen kannst, aber nicht benutzen musst.

von Peter II (Gast)


Lesenswert?

Thomas P. schrieb:
> Ich finde es nachteilig, das der EEProm nur durch die identische Größe
> aus dem SRAM Copiert werden kann.

warum sollte das so sein? Mann kann auch jedes byte einzeln speichern.

von Thomas P. (Firma: privat) (memo)


Lesenswert?

Danke erstmal für die Antworten..

Mein Problem ist,  dennoch das ich auf diese weise:
(code nicht vollständig)
1
char puffer[3];
2
3
uart_rec(char UDRr){
4
5
puffer[pindex] = UDRr; // char from Uart 
6
pindex++;
7
puffer_result = atoi(puffer);
8
eeprom_write_byte ((uint8_t*) &coor[dimension1][dimension2][dimension3],puffer_result); 
9
}

Nichts in den EEprom bekomme, bzw. möglicherweise schon, aber dann hätte 
ich das problem beim auslesen mit den index-Schlüssel.

Ein equivalentes Auslesen alsa:
1
eeprom_read_byte((uint8_t*) &coor[dimension1][dimension2][dimension3]);

führt auch nicht zum Erfolg.

Für eine genauere Hilfestellung währe ich wirklich dankbar.

von (prx) A. K. (prx)


Lesenswert?

Vielleicht meinst du sowas:
1
union {
2
  struct {
3
    ...;
4
  } mode1;
5
  struct {
6
    ...;
7
  } mode2;
8
} u;
Eine automatische Initialisierung beim Start auf Wert != 0 ist natürlich 
problemtisch.

von Oliver S. (oliverso)


Lesenswert?

Auch wenn die Frage mal wieder die falsche ist (denn dein Problem sind 
nicht "Wie globale Varablen zur Laufzeit?", sondern "Wie speichere ich 
Variablen im EEPROM?")

gibt es in C dynamische Speicher-Allokierung mit malloc und free. Die 
kann man zur Beantwortung deiner Frage nutzen, aber nicht zur Lösung 
deines Problems (was ja ein ganz anderes ist).

Um den von malloc gelieferten "eindimensionalen" Block als 
mehrdimensionales Array nutzen zu können, könnte man (neben einem 
einfachen cast) auch die mehrdimensionalen Arrayindizes in einen 
eindimensionalen Index umrechnen.

http://www.peacesoftware.de/ckurs8.html

Nur, wenn man das schon macht, kann man damit auch gleich auf die 
passende EEPROM-Adresse zugreifen, und den SRAM-Block weglassen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Direkter_Zugriff_auf_EEPROM-Adressen

Oliver

von Thomas P. (Firma: privat) (memo)


Lesenswert?

@Oliver S. (oliverso)

Auch wenn die Frage mal wieder die falsche ist (denn dein Problem sind
nicht "Wie globale Varablen zur Laufzeit?", sondern "Wie speichere ich
Variablen im EEPROM?")

Das hängt davon ab, entweder ich kann mein großen "Quellblock" nutzen, 
aber dann habe ich das Global-Variablen-Speicher Problem, oder ich kann 
Byteweise ein 3-dimensionales Array in den EEprom schreiben.

1 von beiden schafft Abhilfe!!!

von Peter D. (peda)


Lesenswert?

Nimm einfach lokale Variablen.

Die erste Funktion legt sich ein Array auf dem Stack an, speichert darin 
die UART-Daten und schreibt sie in den EEPROM. Nach dem Ende ist der 
Stack wieder frei.

Die 2. Funktion legt sich dann ihre Variablen auf dem Stack an.
Sind es viele Variablen und sollen sie global zugreifbar sein, definiere 
sie als Struct und lege global einen Zeiger auf die Struct an.


Peter

von Thomas P. (Firma: privat) (memo)


Lesenswert?

Nochmal danke für die vielen Antworten.

Habe das Problem gelöst!!!

@ kbuchegg ,

Ja, der EEProm lässt sich Byteweise beschreiben, das funktioniert 
tadellos...Das Problem war, das ich keine "Flusskontrolle" von der UART 
hatte.

Die Daten sind über UARt ohne Rücksicht auf Verluste  in den µC 
"hineingeprescht"...

Das Schreiben in den EEProm war wohl um einiges langsamer.

Habe jetzt so eine Art Protokoll zwischen Platine und der Clientsoftware 
entwickelt. Vor jedem Zeichen wird gefragt, ob das vorangegangene 
vollständig verarbeiet wurde.

Nun klappt das wunderbar...

Danke nochamals alles für die Mühe..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.