for(int x = 0; x < (sizeof(message) / sizeof(message[0])); x++){
30
Serial.print(message[x]);
31
Serial.print(",");
32
}
33
Serial.println("ended");
34
35
}
Leider sehe Ich im seriellen Monitor wenn das Programm läuft nur "setup"
aber nicht "loop". Wenn Ich jetzt aber changeNavMode(7);
herauskommentiere kommt wie erwartet loop in Dauerschleife. Wie kann es
sein dass das Serial.println("loop"); von dem darauffolgenden Aufruf
beeinflusst wird? Ich denke der Fehler liegt am Compiler und nicht mir
oder?
Ich probiere das ganze mit der Arduino IDE 1.8.2
Danke schonmal!
Danke! Ich hatte da einen Wert, habe ihn aber weil er zu klein war
weggemacht und habe dann völlig vergessen wieder etwas reinzuschreiben.
Warum sagt das der Compiler nicht? Und warum stoppt dann sie
Programmausführung nicht erst an der Stelle? Jetzt habe Ich den
richtigen Wert reingeschrieben und es geht aber es wäre besser wenn der
Compiler sowas meldet
Also mein Ziel ist es ein GPS-Modul über das UBX-Protokoll anzusprechen.
Das Array message wird dann über die Serielle Schnittstelle an das
GPS-Modul gesendet. Laut Datasheet hat die Nachricht die ich senden will
eine länge von 38 byte (mit checksum 40). Wie würdest du das denn
machen? Ich wollte jetzt die Nachrichten-ID hardcoden (das ist wie
message im code steht) und dann den wert der geändert werden soll
(targetMode) anhängen, dann den Rest der Nachricht mit Nullen auffüllen
(Ist ja sowieso maskiert) und dann die Prüfsumme ausrechnen und
anhängen.
Math schrieb:> Ich denke der Fehler liegt am Compiler und nicht mir> oder?
Was verleitet Dich zu solch maßloser Selbstüberschätzung? 400 Jahre
Erfahrung in C?
Derartige Fehler zu finden ist nicht Aufgabe des Compilers. Das kann man
mit anderen Analysewerkzeugen wie valgrind oder cppcheck anstellen.
cppcheck ist auch für Windows verfügbar und dürfte zu Deinem Code
einiges anzumerken haben.
http://cppcheck.sourceforge.net/
Math schrieb:> aber nicht "loop". Wenn Ich jetzt aber changeNavMode(7);> herauskommentiere kommt wie erwartet loop in Dauerschleife.
Das erste "loop" hängt wohl noch in einem Zwischenspeicher, da die
Herausgabe Zeit beansprucht. Dann hängt sich das Programm wegen dem
changeNavMode-Murks auf und nichts mehr tut sich.
Rufus Τ. F. schrieb:> cppcheck ist auch für Windows verfügbar und dürfte zu Deinem Code> einiges anzumerken haben.
Komisch, irgendwie sagt es gerade "Keine Fehler gefunden" (Ich habe die
.ino datei zu einer .cpp -Datei umbenannt und gescannt).
Jobst Q. schrieb:> changeNavMode-Murks
Was soll Ich denn ändern? Mir fällt kein eleganterer Weg ein.
Math schrieb:> Rufus Τ. F. schrieb:>> cppcheck ist auch für Windows verfügbar und dürfte zu Deinem Code>> einiges anzumerken haben.>> Komisch, irgendwie sagt es gerade "Keine Fehler gefunden" (Ich habe die> .ino datei zu einer .cpp -Datei umbenannt und gescannt).>> Jobst Q. schrieb:>> changeNavMode-Murks>> Was soll Ich denn ändern? Mir fällt kein eleganterer Weg ein.
Auf jeden Fall muss der Puffer (message) groß genug sein für die
folgenden Aktionen. Sonst wird der Stack überschrieben und beim return
ist die Rücksprungadresse nicht mehr da.
Math schrieb:> Danke! Ich hatte da einen Wert, habe ihn aber weil er zu klein war> weggemacht und habe dann völlig vergessen wieder etwas reinzuschreiben.> Warum sagt das der Compiler nicht? Und warum stoppt dann sie> Programmausführung nicht erst an der Stelle? Jetzt habe Ich den> richtigen Wert reingeschrieben und es geht aber es wäre besser wenn der> Compiler sowas meldet
Du hast es also schon erledigt.
Jobst Q. schrieb:> Du hast es also schon erledigt.
Ja, aber es funktioniert immernoch nicht.
Das Programm läuft jetzt und es kommen Daten raus aber das GPS-Modul
reagiert noch nicht.
Wenn Ich das ganze mit dem Logic Analyzer anschaue sieht es gut aus, nur
die Prüfsumme habe ich noch nicht nachgerechnet. Ich denke also daran
liegts... Danke an alle für die Hilfe!
Math schrieb:> Komisch, irgendwie sagt es gerade "Keine Fehler gefunden" (Ich habe die> .ino datei zu einer .cpp -Datei umbenannt und gescannt).
Mit deinem Code oben kommt bei mir in Cppcheck V. 1.83 genau das raus,
was die anderen hier auch schon erwähnt haben.
- Array 'message[6]' accessed at index 6, which is out of bounds.
- Array 'message[6]' accessed at index 37, which is out of bounds.
Math schrieb:> Ich denke der Fehler liegt am Compiler und nicht mir> oder?
Out of range Zugriffe sind undefined behaviour. Der Compiler kann also
machen, was er will und hat immer recht. Es darf sogar jeder Compiler
etwas anderes machen.
Ja, Ich habe mit cppcheck auch meinen verbesserten Code getestet und da
sind anscheinend keine Fehler. Ich habe jetzt auch die Nachricht die Das
PC-Programm an das Modul sendet 1zu1 kopiert und es funktioniert, jetzt
probiere ich mal nach und nach die variablen einzuführen. Das der Code
nicht nacheinander abgegangen wird wusste ich aber nicht. Ich dachte
wenn es ein Pronlem gibt wird zuerst der Code bis zum Fehler ausgeführt
und dann passiert etwas unerwartetes. Danke nochmal, ihr habt mir echt
geholfen!
Math schrieb:> Das der Code> nicht nacheinander abgegangen wird wusste ich aber nicht.
Der Code wird schon nacheinander abgegangen. Der Code ist aber viel
schneller als die serielle Schnittstelle.
Serial.println() wartet wohl nicht bis der Text am anderen Ende
vollständig angekommen ist, sondern speichert ihn in einem FIFO-Puffer,
aus dem er dann relativ langsam Bit für Bit gesendet wird.
Math schrieb:> Ja, Ich habe mit cppcheck auch meinen verbesserten Code getestet und da> sind anscheinend keine Fehler.
Zeigen bitte. Alles andere ist Spekulation.
Man kann mit Leichtigkeit in C Bufferoverflows erzeugen, die von keiner
Maschine der Welt durch Quelltextanalyse erkannt werden - erst zur
Laufzeit, wenn es knallt.
Simples Beispiel:
Zugriff über einen Index auf ein Array, wobei der Index erst zur
Laufzeit bekannt wird, z.B. wenn er über die aktuelle Zimmertemperatur
ausgerechnet wird. Knallt die Sonne mal auf Dein Modul, wunderst Du
Dich, warum das Programm nicht mehr das macht, was es soll.
Jobst Q. schrieb:> Serial.println() wartet wohl nicht bis der Text am anderen Ende> vollständig angekommen ist, sondern speichert ihn in einem FIFO-Puffer,> aus dem er dann relativ langsam Bit für Bit gesendet wird.
Jepp. Dafür gibt es Serial.flush().