PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Array mit for-Schleife beschreiben macht Fehler



Gock
20.01.2009, 17:59
Hi allerseits!
Ganz was merkwürdiges passiert hier gerade...
Ich habe 2 Programme, das eine funktioniert, das andere nicht so ganz. Sie sind ca 3kB groß (weshalb ich sie hier nicht reinstellen will) und laufen auf einem Mega32 (der hat 2kB SRAM).
Bedeutsam ist folgender Code:


#define ArraySize 256 //
uint16_t Werte[ArraySize];
uint16_t WertAdressen[ArraySize]; //Array mit den Adressen zu den Werten in Werte[]

...
ISR (TIMER0_COMP_vect){
aktIndex++; // Index von aktuellem Wert erhöhen
Werte[aktIndex] = TCNT1; // Wert n einlesen und speichern
WertAdressen[aktIndex] = Kanal; // Adresse von Wert speichern
if(TCNT1 >= MaxWert){ // Wert mit MaxWert vergleichen
MaxWert = TCNT1; // wenn größer, Adresse und Wert als Max speichern
MaxAdresse = Kanal;
...
}
}

...

void Start(){
for( uint16_t i = 0; i <= ArraySize; i++){
Werte[i] = 0;
WertAdressen[i] = 0;
}
aktIndex = 0;
MaxWert = 0;
MaxAdresse = 0;
MaxIndex = 0;
DiffIndex = 0;
SweepNr = 1;
}

...der Unterschied ist jedoch nur der Code in der Start-Routine, den es im funktionierenden Programm nicht gibt.
In beiden Programmen wird u a der Analogwert eines Potis eingelesen und per SPI übermittelt. Im nicht funtionierenden Programm bleibt der Analogwert trotz Potiänderung unverändert. Dessen höhe variiert komischerweise auch noch mit der Anzahl der Elemente im Array und mit einer anderen Variablen (?).
Es scheint mit der "for-Schleife" zusammen zu hängen. Was mache ich hier falsch?

Ich habe auch schon unterschiedliche Variationen versucht (i anders deklariert...), nutzte leider nichts.
Aber das erstaunliche ist, dass das Array in keinem anderen Programmteil verwendet wird!
Ich hoffe das ist halbwegs klar und Ihr könnt mir meinen Fehler sagen,
Danke schon mal,
Gruß

McJenso
20.01.2009, 18:25
Hallo,
du reservierst 256 Felder. Zur Erklärung nehmen wir mal 8 Felder.
Das heißt du hast die Felder mit den Indexen 0,1,2,3,4,5,6,7. Das sind 8 Felder. Deine Schleife läuft aber bis i <= 8 ist. Das heist es wird Werte[8] im letzten Durchlauf beschrieben. Das hast du aber nicht mehr reserviert.

Gruß

Jens

Gock
20.01.2009, 19:05
Hi!
Das ist in der Tat ein Fehler und ein Anfängerfehler noch dazu. Aber leider liegt das nur daran, dass ich anscheinend aus einer älteren Version kopiert habe.
Nach vielen Versuchen sah es dann schon wie folgt aus aber geändert hat es alles nichts:

for(uint16_t i = 0; i < FeldGr; i++){
Counts[i] = 0;
// Channel[i] = 0;
}

Danke jedenfallls schonmal.

Gibt es irgendetwas, dass überlaufen kann? Das Datasegment ist nur zu 50% voll, wie ist es mit dem Stackpointer usw.?
Oder ist der Ort der Deklaration des Arrays im oberen Programmteil falsch?
Gruß

McJenso
20.01.2009, 19:57
Hallo,

sicher kann da der Stack in andere Bereiche wachsen. Das lässt sich so aber nicht beurteilen. Schau dir mal diese Seite (https://www.roboternetz.de/wissen/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc) an. Da ist ein Verfahren beschrieben, mit dem du den freien Speicher ermitteln kannst. Selber habe ich das noch nicht ausprobiert.

Weil es es bei mir gerade aktuell war. Hast du mal den Controllertypen für den du kompilierst mit dem eingesetzten verglichen? Hatte gerade erst ein sehr blödes Problem am WE. Mega16 im Projekt und Mega32 in der Schaltung...

Gruß

Jens

Gock
20.01.2009, 20:12
Fehler.......................

Gock
20.01.2009, 20:12
Hi,
ich benutze AVRStudio und WINAVR und die Controllereinstellungen werde ich morgen nochmal genauer prüfen..
Mich wundert besonders die Fehlerart. Das Programm läuft ja und auf Anhieb merkt man garnicht, dass es falsch läuft. Es reagiert auf Tastenkommandos und der ADC arbeitet auch auf einem Kanal richtig, aber ein anderer Wert wird anscheinend nicht eingelesen und der wiederum ist mit einem dritten korrelliert. Das ist so merkwürdig, dass ich an Überlauf dachte.
Vielleicht kommt das wem bekannt vor.
Ich habe Teile des Programms auch schon einzeln simuliert und das geht auch.
Die Speicherverbrauchsseite werde ich mir mal ansehen...
Gruß

Gock
03.02.2009, 15:28
Hi nochmal!
Es war der richtige Controller gewählt, den dynamischen Speicher habe ich "noch" nicht gemessen, denn:
Ich habe den Fehler nun eingrenzen und scheinbar auch beseitigen können.
Er trat immer auf, wenn ich in einer ISR direkt hintereinander in 2 Arrays schreiben wollte. Die ISR ist sehr lange, was zwar nicht gut aber für das Programm kein Problem ist.
Nachdem ich die Indexvariablen "volatile" gemacht habe (macht Sinn, weil sie in der ISR und in main benutzt wurden), trat der Fehler nicht mehr sofort auf, sondern erst nach unterschiedlicher Zeit (20, 30 oder 40s).
Jetzt habe ich die Arrays als "static" deklariert und hatte seit über einer Stunde keine Abstürze mehr.
Ich frage mich jedoch immernoch, was der eigentliche Fehler war und warum "static" ihn zumindest verbessern, vielleicht beheben konnte???
Falls noch jemand ließt,
Gruß Gock

lowtzow
12.10.2009, 20:54
hallo

habs jetzt grad zufällig gelsen weil ich was gesucht habe und eventuell eine idee zu deinem problem habe.

wenn du ein programm hast, welches in der ISR und im hauptprogramm mit deinen variablen arbeitet solltest du diese als volatile definieren. sonst kann es dir passieren, dass sie wegoptimiert werden, in deinem fall würde sie als konstante angesehen werden und eventuell durchgehend auf 0 gesetzt.
mit static ist sie nur beim ersten aufruf 0, ansonsten wird sie erhöht; funktioniert in kombination mit einer lokalen variablen und static - vom prinzip wie eine globale.

versuch mal volatile vor deine arrays zusetzen bzw die optimierung zu deaktivieren und berichte von deinem ergebnis

mfg

Gock
12.10.2009, 21:32
Hi!
Das ist schon so lange her, aber soweit ich mich erinnere hat die Deklaration volatile der Arrays das Problem behoben. Damals war mir nicht klar, dass man das auch mit Arrays machen muss, bei Variablen war es mir klar. Aber das ist natürlich nichts anderes... Hätte aber hier eigentlich jemand drauf kommen können. Naja, Du hast es ja bemerkt, danke.
Mittlerweile läuft die Sache ohne Array in einem externen SRAM gut.
Was static angeht, hatte ich es auch so verstanden, wie Du schreibst. Wenn das der einzige Unterschied ist, alles klar. Aber wann bezeichnet man eigentlich eine Funktion als static?
Gruß Gock