Hallo zusammen, ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei Schrittmotoren, ein Display und ein paar Taster angesteuert werden. Geschrieben ist alles in C++ mit Atmel Studio Jetzt ist das Programm soweit fertig und ich bin ausgiebig am Testen. Dabei ist mir aufgefallen, dass manchmal einfach irgendein Programmteil ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und plötzlich wird die programmierte Referenzfahrt durchgeführt. Es schein mir so als wenn der Speicherbereich von Steuervariablen überschrieben wird. Aber nie reproduzierbar. Das ganze Programm ist mit einer Vielzahl von Zustandsautomaten programmiert. Was ich schon gemacht habe: Alles mehrfach kontrolliert und Fehler gesucht. Die Compiler Optimierung abgeschaltet. Es passiert zwar seltener aber immer noch hin und wieder. Neuen Controller verbaut, aber gleiche Problematik. Hat jemand von euch eine Idee woran es liegen könnte oder einen Tipp, wo ich nochmal schauen könnte? Ich wünsche euch allen einen schönen sonnigen Nachmittag. Beste Grüße Patrick
Patrick A. schrieb: > Hat jemand von euch eine Idee woran es liegen könnte An einem Fehler in Deinem Programm oder einem Problem mit Deiner Schaltung. Der µC selbst hat keinen Fehler, jedenfalls keinen, der solch ein Verhalten hervorrufen könnte.
Motoren führen gerne entweder zu EMV-Problemen oder zu Problemen mit der Spannungsversorgung. Kannst du die Störungen provozieren? Wie ist der Aufbau? Ist das Layout ausreichend gut? Wie erfolgt die Spannungsversorgung?
Patrick A. schrieb: > ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei > Schrittmotoren, ein Display und ein paar Taster angesteuert werden. > Geschrieben ist alles in C++ mit Atmel Studio Wahrscheinlich eher C, aber das ist nebensächlich. > Jetzt ist das Programm soweit fertig und ich bin ausgiebig am Testen. > Dabei ist mir aufgefallen, dass manchmal einfach irgendein Programmteil > ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und > plötzlich wird die programmierte Referenzfahrt durchgeführt. > Es schein mir so als wenn der Speicherbereich von Steuervariablen > überschrieben wird. Aber nie reproduzierbar. Klingt nach Stacküberlauf. Wieviel RAM ist noch frei?
Patrick A. schrieb: > Hat jemand von euch eine Idee woran es liegen könnte oder einen Tipp, wo > ich nochmal schauen könnte? Das Problem liegt an und in deiner Software, oder es ist ein Problem mit der Hardware, oder auch beides. Danach solltest du dann mal schauen. Viel mehr lässt sich aus deiner Fehlerberschreibung "macht nicht, was es soll" nicht herauslesen. Oliver
Patrick A. schrieb: > Hat jemand von euch eine Idee woran es liegen könnte Mit allergrößter Wahrscheinlichkeit an der Software. Oder an der Hardware. > oder einen Tipp, wo ich nochmal schauen könnte? du solltest versuchen, den Fehler systematisch zu suchen. Ist die Versorgung immer stabil? Passiert die Effekte nur, wenn die Motoren laufen? Oder reicht es aus, wenn du nur lange genug wartest? > wo ich nochmal schauen könnte? Du solltest schauen, ob du einen amoklaufenden Pointer hast. Z.B. das übliche Array, das 1 Element zu klein ist. Oder die serielle Schnitte, die geradeaus weiter in den Speicher schreibt.
:
Bearbeitet durch Moderator
Was passiert, wenn nur 1 Motor angesteuert wird? Was passiert, wenn beide Motoren angesteuert werden, das Display aber nicht? Auf deutsch - versuche, den Fehler systematisch einzugrenzen durch nicht ansteuern von Komponenten Viel Glück
Wenn man gar keinen Schimmer hat, kann man auch versuchen, Teile des Programms auszukommentieren. Man entfernt schrittweise immer mehr Teile, bis es wieder funktioniert. Dann schau man sich nochmal ganz genau den zuletzt entfernten Teil an.
Patrick A. schrieb: > dass manchmal einfach irgendein Programmteil > ausgeführt wird. Zum Beispiel nimmt man eine Einstellung vor und > plötzlich wird die programmierte Referenzfahrt durchgeführt. Sieht aus wie Stacküberlauf. Vermutlich gibt es zu viele verschachtelte Unterprogramme oder zu viele Variablen, die auf dem Stack gesichert werden müssen. Man untersuche auch, ob Interruptroutinen etliche Variablen auf dem Stack sichern müssen. mfg
Patrick A. schrieb: > Hallo zusammen, > > ich habe aktuell ein Projekt, bei dem mit einem ATmega328PB zwei > Schrittmotoren, ein Display und ein paar Taster angesteuert werden. > Geschrieben ist alles in C++ mit Atmel Studio Wird im Programm viel mit der String Klasse gemacht, oder mit "new" Objekte erzeugt und wieder gelöscht? Dann kann auch der Heap Bereich fragmentieren bzw. den Stack überschreiben.
Wenn Verdacht auf Heap-Überlauf bzw Fragmentierung besteht, kann man sich in die Hauptschleife eine Ausgabe des freien Speichers einbauen und dass dann z.B. jede Sekunde machen. Dazu mit malloc() antesten, wie viel Speicher man maximal bekommen kann. Versuche zuerst 4 kB, dann 2 kB, dann 1 kB, dann 1/2 kB, dann 1/4 kB usw. zu belegen. Der erste erfolgreiche Aufruf zeigt dir grob an, wie viel Speicher frei ist. Wenn das im Laufe der Zeit immer wenig wird, hast du wahrscheinlich einen Heap Überlauf. Nicht vergessen, diesen Testblock wieder frei zu geben.
Stefan ⛄ F. schrieb: > Versuche zuerst 4 kB, dann 2 kB, dann 1 kB, dann 1/2 kB, dann 1/4 kB > usw. zu belegen. Bei nur 4 kB RAM insgesamt wird der erste Versuch schiefgehen, denn irgendwo sollte ja auch der Stack liegen. Und wenn Stringkonstanten verwendet werden, belegen die auch gerne Platz im RAM (dank der Harvard-Architektur der AVRs).
Stefan ⛄ F. schrieb: > Wenn Verdacht auf Heap-Überlauf bzw Fragmentierung besteht, kann man > sich in die Hauptschleife eine Ausgabe des freien Speichers einbauen und > dass dann z.B. jede Sekunde machen. https://rn-wissen.de/wiki/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc
Falk B. schrieb: > https://rn-wissen.de/wiki/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc Das ist nett bei so gut wie statischer Belegung des SRams, aber bei intensiverer Nutzung des heaps wenig bis gar nicht hilfreich. Oliver
Oliver S. schrieb: > Das ist nett bei so gut wie statischer Belegung des SRams, aber bei > intensiverer Nutzung des heaps wenig bis gar nicht hilfreich. Einfach mal weiter lesen, Überschrift "Dynamischer RAM-Verbrauch"
Falk B. schrieb: > Einfach mal weiter lesen, Überschrift "Dynamischer RAM-Verbrauch" Eben. Das solltest du mal tun. "Damit der Code den richtigen Wert liefert, darf keine dynamische Speicherallokierung mit malloc() etc. geschehen sein" Oliver
In einem embedded Webserver nutze ich diese Funktion innerhalb des HTTP Request Handlers:
1 | // Show the largest available block of free memory
|
2 | static unsigned short function_freememory(char* buffer) { |
3 | void *p = 0; |
4 | size_t size; |
5 | for (size = RAMEND; size > 1; size -= 10) { |
6 | p = malloc(size); |
7 | if (p != 0) { |
8 | break; |
9 | }
|
10 | }
|
11 | if (p != 0) { |
12 | free(p); |
13 | }
|
14 | else { |
15 | size=0; |
16 | }
|
17 | return sprintf_P(buffer,PSTR("%5u"),size); |
18 | }
|
Die Funktion schreibt die das Ergebnis als Text in den Buffer und liefert die Anzahl der Zeichen zurück. Fragt mich bitte nicht, von wo ich das kopiert habe. Habe ich vergessen. Es könnte dieses Forum gewesen sein. Wenn es ein bisschen schneller gehen soll kann man die Schrittweite von 10 auf 100 ändern. Für meine Zwecke passte das aber so, da ich sie eh manuell (per HTTP Request) aufrufen musste.
Oliver S. schrieb: > Eben. Das solltest du mal tun. > "Damit der Code den richtigen Wert liefert, darf keine dynamische > Speicherallokierung mit malloc() etc. geschehen sein" Und wer sagt, daß der Op dieses verwendet? Bisher herrscht da Schweigen im Walde.
Patrick A. schrieb: > Es schein mir so als wenn der Speicherbereich von Steuervariablen > überschrieben wird. Klingt nach wildem Pointer. Entweder ein Array ist zu klein oder ein 16Bit-Wert wird versucht, auf einen Pointer auf 8Bit zu schreiben. Ein Stackproblem läßt sich schnell ausschließen. Man füllt den Stack z.B. mit 0x77 und schaut sich den RAM-Dump an. Oder eine Routine zählt, wieviel 0x77 noch übrig sind. Es sollten wenigstens noch 16 Byte sein.
Seltsam das auch die erfahrensten Leute hier nicht (jedenfalls nicht öffentlich) darüber nachdenken dass es sich auch einfach um massive Störungen auf der Stromversorgung handeln könnte.
späh kulant schrieb: > dass es sich auch einfach > um massive Störungen auf der Stromversorgung handeln könnte. Sieh mal hier (betreffende Stelle hervorgehoben): DerEinzigeBernd schrieb: > An einem Fehler in Deinem Programm *oder einem Problem mit Deiner* > Schaltung. Das schließt Störungen der Stromversorgung mit ein.
Liest der TO ueberhaupt noch mit, da bislang keinerlei Rueckmeldung kam ...
Heiner schrieb: > Liest der TO ueberhaupt noch mit, da bislang keinerlei Rueckmeldung kam Na wenn hier von Stack und Heap geredet wird und er noch nicht mal weiss was das ist ...... kann man schon mal die Flucht ergreifen.
späh kulant schrieb: > Seltsam das auch die erfahrensten Leute hier nicht (jedenfalls > nicht öffentlich) darüber nachdenken dass es sich auch einfach > um massive Störungen auf der Stromversorgung handeln könnte. Haben sie doch! Seltsam dass manche Leute nicht lesen bevor sie andere kritisieren. Sebastian R. schrieb: > Motoren führen gerne entweder zu EMV-Problemen oder zu Problemen mit der > Spannungsversorgung... Wie erfolgt die Spannungsversorgung? Oliver S. schrieb: > Das Problem liegt an und in deiner Software, oder es ist ein Problem mit > der Hardware, oder auch beides. Danach solltest du dann mal schauen. Heiner schrieb: > Was passiert, wenn nur 1 Motor angesteuert wird? Drei entsprechende Hinweise sollten reichen, oder wie viele Wiederholungen hättest du gerne gehabt?
Patrick A. schrieb: > oder einen Tipp, wo > ich nochmal schauen könnte? vielleicht bei den beliebten Abblockkondensatoren? mfg
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.