Hallo!
ich habe eine Funktion geschrieben um NMEA-Daten zu parsen. Die Funktion
wird mit
1
ParseMessage(nmeastring,stringtype,&NavState);
aufgerufen, wobei die geparsten Daten dann im Struct NavState landen
sollen. ParseMessage() funktioniert soweit perfekt und dekodiert wie
gewünscht. Allerdings tauchen in der main() keine Daten in NavState auf,
obwohl sie in ParseMessage() reingeschrieben werden. Was hab ich denn da
übersehen? Die Daten im Struct scheinen uninitialisiert zu sein.
Dein struct sieht komisch aus. Du benutzt 2x die Bezeichnung
"navstruct".
Schau mal bei http://c-buch.sommergut.de/Kapitel13/Strukturen.shtml wie
das gemacht werden muss. Ich hab mich da auch schon vertan.
Je nachdem ob mit oder ohne typedef steht Objektname oder Instanzname
(falls vorhanden) woanders.
ändert leider nichts an der Sache.
Mit nem volatile struct hatte ich auch keinen Erfolg. Ich hab ein
bisschen den Verdacht dass ich mich da mit dem referenzieren und
dereferenzieren irgendwo vertan hab, aber ich find keinen Fehler...
Nein, das passt schon so, die Funktion ParseField muss den Pointer
pMessage ändern können, deswegen char **. Problem ist dass die Daten,
die ich in ParseMessage in den struct reinschreibe in der main Funktion
nicht ankommen.
Die Verwendung von ParseField entspricht dem Prototyp und die
Strukturdefinitionen sind und waren auch ok.
Bist du sicher daß der RAM nicht ausgeht? Und bei einem der
Funktionsaufrufe mit dem Riesenstring oder bei atof/sprintf ein Teil des
RAMs/Stacks überschrieben wird?
>Nein, das passt schon so, die Funktion ParseField muss den Pointer>pMessage ändern können, deswegen char **. Problem ist dass die Daten,>die ich in ParseMessage in den struct reinschreibe in der main Funktion>nicht ankommen.
ist zwar nicht der Fehler, naber warum muss sie pMessage ändern können
wenn die Änderung nirgends beachtet wird?
Ich mach heut abend mal ein kompilierbares Beispiel. Ich hab mir den
Assembler-Code angeschaut, bin aber daraus auch nicht recht schlau
geworden. Es scheint als ob er das gleiche Register (Z) sowohl für
TempBuff als auch den Struct verwendet. Das wundert mich zwar etwas,
aber grundsätzlich sollte da ja auch nichts dagegensprechen das mit
unterschiedlichen Offsets zu machen.
Walter:
> ... ist zwar nicht der Fehler, naber warum muss sie pMessage ändern> können wenn die Änderung nirgends beachtet wird?
Weil mein Code-Ausschnitt nur fürs Problem relevante Teile enthält, im
vollständigen Programm hat das schon so seine Richtigkeit :-)
Johann:
> Bist du sicher daß der RAM nicht ausgeht? Und bei einem der> Funktionsaufrufe mit dem Riesenstring oder bei atof/sprintf ein Teil des> RAMs/Stacks überschrieben wird?
Eigentlich schon, der Code läuft auf nem Mega328. Aber ich probiers
später mal mit nem kürzeren String.
Stefan:
> Und aus was besteht "..."? Wird da vielleicht auch nach dispbuff> geschrieben?
Nein.
So, hab ein Progrämmchen zum kompilieren aufm PC draus gemacht. Ganz
toll ist natürlich, dass die Sache auf dem PC einwandfrei funktioniert.
Daraufhin hab ich ein bisschen weiterprobiert:
Wenn ich ParseMessage verändere:
dann kommt auch tatsächlich in der Main der gewünschte Wert an. Wenn ich
die Zeile weglasse scheint es dass der Struct wegoptimiert wird. Ein
deklarieren von NavStruct als volatile ändert leider auch nichts an der
Sache. Hat noch jemand Ideen?
Hier ist mal ein lauffähiger Code für den Mega 328. So wie gepostet
funktionierts, Zeile 83 bis 85 auskommentiert gehts nicht mehr. Der Uart
Treiber is von Peter Fleury. Leider kann ich es nicht auf dem PC
demonstrieren, da sich da der Fehler einfach weigert aufzutreten.
TempBuf in ParseMessage ist zu klein. Beim zweiten Feld (190533.920) (*)
landet die terminierende Null daher außerhalb des Arrays.
(*): Und auch beim fünften, wenn du denn so weit Parsen würdest.
PS: Vielleicht möchtest du dir ja mal die Funktion strtok anschauen.
Tatsache, das Feld ist zu kurz... Jetzt gehts. Danke!
Der Tipp mit strtok ist gut, die kannte ich noch nicht. Aber jetzt gehts
ja, d.h. die Funktion wird mal gespeichert und beim nächsten
gleichartigen Problem wieder rausgekramt :-)
Gast schrieb:
> Tatsache, das Feld ist zu kurz... Jetzt gehts. Danke!> Der Tipp mit strtok ist gut, die kannte ich noch nicht. Aber jetzt gehts> ja, d.h. die Funktion wird mal gespeichert und beim nächsten> gleichartigen Problem wieder rausgekramt :-)
Wenn du diese Funktion in deine persönliche Library übernehmen willst,
dann mach sie zuerst richtig:
Wer eine Funktion schreibt, die einen Buffer befüllt und in der
Argumentliste nicht die Buffergröße übergibt (und natürlich auch in der
Funktion überprüft, ob der Buffer nicht überlaufen wird), der sollte
sofort 30 Schläge mit dem nassen Fetzen auf seinen Hinterkopf bekommen.
Karl heinz Buchegger schrieb:
> Wer eine Funktion schreibt, die einen Buffer befüllt und in der> Argumentliste nicht die Buffergröße übergibt (und natürlich auch in der> Funktion überprüft, ob der Buffer nicht überlaufen wird), der sollte> sofort 30 Schläge mit dem nassen Fetzen auf seinen Hinterkopf bekommen.
Hihi, was nämlich passieren kann ist genau das, was du gerade hattest:
Merkwürdige Fehler.