Forum: Mikrocontroller und Digitale Elektronik AVR, Störung des EEPROMs!?


von torsten (Gast)


Lesenswert?

Hallo.

Ich bin eigentlich C++-Programmierer und hab auch damit ein paar AVRs 
programmiert. Soweit so gut, bis jetzt hab ich das noch nciht bereut. 
Allerdings passiert gerade bei einem Programm folgendes:
Wenn bestimmte Teile im Programm drin sind -z.B. Instanzierungen von 
einer bestimmten Klasse- wird ein Teil der Daten aus dem EEPROM nicht 
richtig ausgelesen.
Wenn ich zwischen der Ausgabe des Inhalts des EEPROMs und der 
Instanzierung der "einen" Klasse eine Verzögerung von 100ms stecke, 
kommt der korrekte Inhalt des EEPROMs beim Rchner an. Er wurde in der 
Zwischenzeit nicht noch mal neubeschrieben.
Könnte die stark ausgedehnte Ressourcenbedarf des Programms (in Bezug 
auf C) dazu geführt haben, dass das Management der Ressourcen iwie 
leicht gestört ist? Für mich ist das alles etwas (mehr) 
zusammenhangslos, da mir nicht in den Kopf will, dass selbst im Falle 
von überfülltem Arbeisstpeicher nichts mit dem EEPROM passiert.
Was meint Ihr, habt Ihr damit Erfahrung oder eine Ahnung, was es damit 
auf sich hat?
Code wollte ich nciht posten, ich denk mal, es reicht, wenn das 
"Problem" grob beschrieben wird.
Und ja, dass C++ vielleicht nicht das geschickteste ist um µC zu 
programmieren ist mir schon bewusst, war aber zu faul, das in C zu 
machen, man hat einfach weniger Aufwand ;-)

freundliche Grüße, Torsten

von Daniel -. (root)


Lesenswert?

torsten schrieb:
> Code wollte ich nciht posten, ich denk mal, es reicht, wenn das
> "Problem" grob beschrieben wird.

sorry, alles andere is sinnlos
du kannst ja soweit abstrahieren, dass dein Code nur das Problem
demonstriert.

> Und ja, dass C++ vielleicht nicht das geschickteste ist um µC zu
> programmieren ist mir schon bewusst, war aber zu faul, das in C zu
> machen, man hat einfach weniger Aufwand ;-)

auch in C++ kann man sehr schlank programmieren
ich sehe darin nicht die Ursache für dein Problem
C++ ohne Klassen ist beinahe C

von Daniel -. (root)


Lesenswert?

torsten schrieb:
> Wenn ich zwischen der Ausgabe des Inhalts des EEPROMs und der
> Instanzierung der "einen" Klasse eine Verzögerung von 100ms stecke,
> kommt der korrekte Inhalt des EEPROMs beim Rchner an. Er wurde in der
> Zwischenzeit nicht noch mal neubeschrieben.

wie gesagt, es wäre wichtig zu wissen, was du im Konstruktor
veranstalltest. Eventuell sind da Zugriffe auf EEPROM Controlregister

von torsten (Gast)


Lesenswert?

Also, bin mir jetzt nicht sicher, welchen Konstruktor du meinst, aber 
ich poste mal beide:

so ist das dann in der main():
1
//Ein Uart-Objekt um Inhalt des EEPROMs auszugeben
2
Uart_IO uart;
3
4
//Weichen-Objekte erzeugen (MAX_WEICHEN = 4)
5
//
6
Weiche* weiche[MAX_WEICHEN];
7
8
weiche[0] = new Weiche(PC5, PC4, PC3, C, 1);
9
weiche[1] = new Weiche(PC2, PC1, PC0, C, 2);
10
weiche[2] = new Weiche(PB5, PB4, PB3, B, 3);
11
weiche[3] = new Weiche(PB2, PB1, PB0, B, 4);
12
//
13
//Inhalt ausgeben (wenn die Verzögerung nicht mit drin ist, wird er falsch gesendet, obwohl er richtig im EEPROM erthalten ist)
14
uart.putch(weiche[0]->get_Nr());
15
uart.putch(weiche[1]->get_Nr());
16
uart.putch(weiche[2]->get_Nr());
17
uart.putch(weiche[3]->get_Nr());
18
//
19
uart.putch(weiche[0]->get_grund());
20
uart.putch(weiche[1]->get_grund());
21
uart.putch(weiche[2]->get_grund());
22
uart.putch(weiche[3]->get_grund());
23
24
//angesprochene Verzögerung
25
_delay_ms(100);
26
  
27
//Datenpaket (angesprochene Instanz)
28
// 
29
Data_packet* packet_in = new Data_packet();
30
Feldelement* pWeiche = packet_in->recieve();
31
delete(packet_in);

Konstruktor der Klasse 'Weiche'
1
Weiche(uint8_t W0, uint8_t W1, uint8_t Wr, IO_register W_r, uint8_t _lok_Nr) : Weiche_0(W0), Weiche_1(W1), Weiche_r(Wr), Weichen_register(W_r), lok_Nr(_lok_Nr)
2
{
3
  //Daten aus EEPROM einlesen 
4
  //
5
  //Grundstellung  
6
  //
7
  grund = (Stellrichtung)eeprom_read_byte(&eeSR_grund[lok_Nr-1]);
8
  
9
  //globale Nummer
10
  //
11
  glob_Nr = eeprom_read_byte(&eeNr[lok_Nr-1]);
12
    
13
}
Wenn der Konstruktor der Klasse 'Data_packet' auch noch benötigt werden 
soll, poste ich den natürlich auch noch..

Eine kurze Anmerkung zum Code: Es handelt sich um einen Weichendecoder, 
bzw. es soll einer werden. Es soll, wie eigentlich gut aus dem Code 
hervorgeht, insgesamt 4 Objekte der Klasse Weiche geben. Jedes Objekt 
liest dann anhand der lokalen Nummer, die es bekommt, die Stelle aus dem 
uint8_t-array im EEPROM aus, welche einmal die Nr der Weiche und die 
Grundstellung der Weiche speichern.
So, ich hoffe, Ihr könnt mir anhand des Materials weiterhelfen? :-)
dfreundliche Grüße, torsten

von Roland H. (batchman)


Lesenswert?

torsten schrieb:
> wird ein Teil der Daten aus dem EEPROM nicht
> richtig ausgelesen.

Was heisst das: Falsche Werte oder gar nichts?

Wie sieht uart.putch() aus?

Welcher AVR?

torsten schrieb:
> Wenn der Konstruktor der Klasse 'Data_packet' auch noch benötigt werden
> soll, poste ich den natürlich auch noch..

Ja, wäre nicht schlecht.

von torsten (Gast)


Lesenswert?

uart.putch() sieht so aus:
1
void putch (const unsigned char c)
2
{
3
  //Warten bis UART bereit ist für Senden
4
  while (!(UCSRA & (1<<UDRE)));  
5
     
6
   //Zeichen senden
7
  UDR = c;  
8
}

Der Konstruktor (verwendete) Konstruktor von Data_packet ist nicht so 
sonderlich spektakulär:
1
//Konstruktor für eingehende Pakete
2
Data_packet()
3
{
4
  uart = new Uart_IO;
5
}

Falls erforlderlich kann ich noch den Code von Data_packet::revieve() 
nachliefern..

Der Fehler liegt wirklich beim Senden, den aus dem empfangenen geht 
hervor, dass der Controller die richtigen Daten verwendet.
Also, könnt Ihr mir helfen?
freundliche GRüße, torsten

von Roland H. (batchman)


Lesenswert?

torsten schrieb:
> nicht so
> sonderlich spektakulär:

Für mich schon. Denn der Inhalt hat mit der Klasse nichts zu tun. Aber 
es wird munter weiter Speicher auf dem Heap belegt. Auf dem weiterhin 
unbekannten AVR mit deshalb unbekannter Größe des RAMs. Vielleicht stört 
das erneute Initialisieren des UARTs die Ausgabe.

torsten schrieb:
> Der Fehler liegt wirklich beim Senden

Das wage ich zu bezweifeln.

Ich tippe darauf, dass Dir der Heap in den Stack wächst. Alternativ: Im 
unbekannten Construktor für Uart_IO wird der UART erneut initialisiert, 
vielleicht mit Interrupts.

Wirf alle "new"-Aufrufe raus. Das ist in diesem Fall angebracht, da ich 
hier nichts dynamisches erkennen kann (dynamisch im Sinne von: Zur 
Compile-Zeit nicht bekannt).

Aus Deinen Schnippseln wird man nicht schlau; Bitte komplettes Programm 
mit Makefile. Auch die ISRs.

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.