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
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
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
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.