Hallo!
Ich brauche mal wieder eure Hilfe. Ich bin bald am Verzweifeln:
Ich habe einen Ringbuffer implementiert. Dieser besteht aus einer
struct, welche ein int-Array für die Daten und zwei ints (welche Start
und Ende der Daten beschreiben) enthält.
Diese Strukt übergebe ich als Pointer an eine Funktion. Diese Funktion
liest nur aus dem Buffer, ändert nichts daran (auch am Pointer nichts).
Nur zeigt sie ein ganz komisches Verhalten: wenn ich mit dem Debugger
Schritt für Schritt durch die Funktion gehe, dann kann ich immer schön
sehen, dass der Buffer noch in Ordnung ist. Am Ende der Funktion (beim
return) drücke ich noch einmal F11 für einen Einzelschritt. Und was
kommt raus: Nur Müll. Es sind auch andere Speicherstellen völlig
verändert. Das Programm arbeitet aber normal weiter...
Ich benutze HiTOP5 als IDE und einen ARM STR9. Wenn das eine Rolle
spielen könnte.
Eigentlich könnte es ja der Stack sein, der beschädigt wird, aber das
kommt eigentlich nur ganz selten in meinen ASM Projekten vor. Bei C
hatte ich noch nie sowas...
Also ihr dürft raten, an was könnte es liegen? Am Code selber scheint es
tatsächlich nicht zu liegen, hab mal eine Version auf dem PC mit erfolg
laufen gelassen...
Im Anhang ein Bild mit den beiden Zuständen vorher (oberes Bild
(Pointer)) unteres Bild ein Einzelschritt weiter.
Vielen Dank für eure Kreativität und Hilfe
>Also ihr dürft raten, an was könnte es liegen?
Nö, tun wir nicht.
> Am Code selber scheint es>tatsächlich nicht zu liegen, hab mal eine Version auf dem PC mit erfolg>laufen gelassen.
Dann lass das Proggi doch einfach auf dem PC laufen.
Hallo!
Auf dem PC habe ich wie oben geschrieben das Ding erfolgreich
getestet...
Dass es am Code liegt ist unwahrscheinlich. Zumal beim beschriebenen
Rücksprung nichts mit dem Pointer gemacht wird! Ich krieg die Krise.
Nach einem Einzelschritt, welcher nichts mit dem Buffer zu tun hat ist
alles verändert. Sogar Variablen, die dar nichts mit der aufgerufenen
Funktion zu tun haben...
Schon mal darüber nachgedacht, dass der Speicher auf einem µC
wesentlich kleiner ist, als auf einem PC? Für mich sieht das nach
einem Stack-Problem aus. Dazu passt auch, dass es beim Aufruf einer
Funktion passiert. Hast Du viele lokale Variablen in der Funktion
benutzt?
Code, code, code, code, code ... was ist daran so schwierig?
Wie Matthias schon sagte, Zeile 42!
http://de.wikipedia.org/wiki/42_%28Antwort%29>Eigentlich könnte es ja der Stack sein, der beschädigt wird, aber das>kommt eigentlich nur ganz selten in meinen ASM Projekten vor.selten ist immer noch mehr als nie>Ich benutze HiTOP5 als IDE und einen ARM STR9. Wenn das eine Rolle>spielen könnte.Könnte - da der Stack auf dem PC um ein paar Kubikbytes größer ist.
Hallo!
Das mit dem Stack könnte sein, ich verwende nicht viele Lokale Variablen
in der Funktion. Aber müsset wenn es sich um ein Stackproblem handelt
nicht eher beim Aufruf der Funktion ein Problem auftauchen?
Ich bins nochmal. Hab festgestellt, dass in der Funktion welche Probleme
macht zei weitere Funktionen aufgerufen werden, welche schon ein
"bisschen" Speicher benötigen. Es sind jeweils ca. 1.6 kBytes. Also
eigentlich weit entfernt von den knapp 100kByte, aber wäre es möglich,
dass er die irgendwie ungeschickt alloziert und so anderen Speicher
überschreibt?
Der Gesamtspeicherbedarf des Programms beläuft sich auf ca. 50 kBytes,
also auch noch weit von der Grenze entfernt (OK, der Stack braucht auch
noch, aber wohl nicht den ganzen Rest). Der Speicherbedarf kann nicht
(erheblich) gesenkt werden.
Wie kann ich die RAM organisation anschauen? Oder beeinflussen? Wäre
eine Möglichkeit, den verwendeten Speicher statisch oder global oder so
zu definieren, dass schon zu kompilierzeiten bekannt ist, welcher
Speicher gebraucht wird?
Sorry, den Code kann ich hier nicht reinstellen. Dies aus zwei Gründen:
1. Er erstreckt sich über ca. 4 Files (die zeit reicht leider auch
nnicht mehr für ein Minimalbeispiel zu destillieren)
2. Studienarbeit
Aber wie kann ich herausfinden ob es denn an der Speicherverwaltung
liegt. Wie kann ich zum Beispiel die Stackgrösse herausfinden? Oder wie
kann ich sehen wo er welche Daten bei einem Funktionsaufruf anlegt?
jetzt folgt unqualifiziertes Geblubber:
Du könntest dir testweise vor jedem Funktionsaufruf mal den aktuellen
Stackpointer ausgeben lassen und vielleicht auch ein paar Bytes "über"
dem Stackpointer - "über" in Richtung des Stackwachstums.
Und dann halt händisch oder per Debugger angucken, ob da vielleicht was
wichtiges dem Stack im Weg liegt.
Eventuell könnte es auch erfolgversprechend sein, dir den Moment des
returns aus der Funktion mal anzugucken und z.B. die Rücksprungadresse
mit der auf dem Stack vergleichen.
- Speicherverbrauch testweise reduzieren (Variablen in global Scope,
Buffer verkleinern)
- Speicherverbrauch testweise erhöhen und schauen, ob/wie sich das
Fehlerbild ändert
Damit kann man das schonmal ein wenig eingrenzen.
>Sorry, den Code kann ich hier nicht reinstellen. Dies aus zwei Gründen:>1. Er erstreckt sich über ca. 4 Files (die zeit reicht leider auch>nnicht mehr für ein Minimalbeispiel zu destillieren)>2. Studienarbeit
Diese Information zu Beginn wäre nicht schlecht gewesen.
So, habe nochmals ein bisschen getestet. Folgende interessante
Beobachtung:
Nach dem die Funktion zurückgegeben hat und die Variablen scheinbar alle
verändert sind kann ich einen Reset durchführen (ohne
Spannungsversorgung zu trennen). Dann sind in die Inhalte wieder so wie
vor dem Funktionsaufruf. Den Ringbuffer konnte ich nun mal im Speicher
finden (im Debugger kann man das ganze Ram anschauen) Dort wird nichts
verändert nach der Rückgabe. Es ist also irgendwie nur der Pointer der
verändert wird.
Das Fehlerbild ändert sich tatsächlich ein wenig wenn ich die
Speichergrösse des Ringbuffers ändere, allerdings nicht so, dass ich
daraus schlüsse ziehen kann. Variablen die Nichts mit der Funktion zu
tuna haben sind nach dem Funktionsaufruf manchmal alle 0, manchmal nur
einige...
Komischkomisch
Der Ringbuffer funktioniert übrigens, den habe ich auch unter anderen
Bedingungen schon erfolgreich im Einsatz....
Ich setze mal voraus, dass solche Konstrukte wie "goto" nicht in Deinem
Code vorkommen...
Am Stack-Pointer oder an sonstigen System-Pointern schraubst Du nicht
herum?
Interrupts?
Sieht ziemlich übel aus. Wie schonmal von Kai Giebeler vorgeschlagen:
Wirf alles in global definierte Variablen (nicht schön, aber hilft bei
der Fehlersuche). Idealerweise außerhalb der main() definiert.
So, ich möchte nochmal berichten:
In der betreffenden Funktion hatte ich ein Array zu kurz initialisiert,
weil ich in der Konstante welche die länge des Array angibt einen
Tippfehler drin hatte. Dann kan es vor, dass es in diesem Array über das
Ende hinaus geschrieben hat, wahrscheinlich genau in die Variablen bzw.
Pointer, welche dann ein merkwürdiges Verhalten gezeigt haben.
Was ich daraus gelernt habe:
- Konstanten und Variablen sollten sich in der Namensgebung deutlicher
unterscheiden
- Glaube nie einem Debugger (der hat wie bereits beschrieben die
betreffenden Variablen erst nach dem Funktionsrücksprung aktualisiert,
so dass ich natürlich am falschen Ort gesucht habe)
Vielen Dank für eure Tipps und Geduld!
Schönes Wochenende