Hi Zusammen Ich versuche gerade eine Projeckt mithilfe eines Echtzeitbetriebssystems auf die Beine zu stellen, mit mäsigem Erfolg. Anfangs lief es wirklich gut und ich kam schneller vorran als erhofft aber um so komplexer das Programm wird um so häufier kommen Bugs die ich absolut nicht nachvollziehen kann. Simulieren fällt leider weg, das AVR Studio packt das mit dem Betriebssystem nicht mehr. Im Augenblick habe ich eine ganz konkretes Problem und hoffe ihr habt eine Idee woran das liegt. Folgendes, das Programm läuft nahezu feherfrei bis ich auf die unverschämte Idee komme eine einzige zusätzliche int Variable zu deklarieren. Ich poste nur mal den einen Auszug, das gesammte Programm ist viel zu Groß. So Funktioniert noch alles weitgehend: ... void display (void) // Display anzeige Task { char text_buffer[21]; char stat; int i =0; ... Und so hängt sich das Programm bei der eingabe einer Taste sofort auf: void display (void) // Display anzeige Task { char text_buffer[21]; char stat; int i =0; int e; Die Variable e wird nirgens verwendet und wird mit Sicherheit an dieser Stelle zum ersten mal deklariert. Ich hätte nun die Vermutung das ein Speicher oder Stacküberlauf der Grund sein könnte nur wie finde ich das raus? Wie gesagt, Simulieren ist nicht...soll ich das von "Hand" ausrechnen oder wie könnte ich den Fehler ergründen? Danke für eure Ideen! Gruß
Anscheinend machst du das ganze ja mit AVRs. Ich weiß zwar nicht welchen Compiler du benutzt, aber falls du WinAVR verwendest, da gibts ein Programm namens avr-size.exe. Das zeigt die Code und Speicher-Göße an bzw wie viel noch frei ist. Bei google gibts noch etwas namens avr-sizex.exe, das gibt das ganze dann schön als Prozentsatz der noch frei is an. Geht aber nur mit WinAVR, bzw avr-gcc. mfg Michael
Ich benutze eigentlich immer ein LCD zum debuggen. Du kannst Dir z.B. ab und zu den Stackpointer ausgeben lassen. Allerdings wollen die Zeitpunkte dieser Ausgaben wohl überlegt sein, sonst macht der uC nichts anderes mehr. Prinzipiell sollte man aber vorher einschätzen, wie tief die Rekursion in einem Programm ist.
hi, wär schon angenehmer wenn Du Deinen Namen posten würdest !! Aber mach mal was "Ordentliches": http:\\www.e-lab.de Was erwartest Du denn von dem Chaos, das ein C-Compiler zuläßt ??? <dito> Gruß
@Michael: Ich benutze CodeVisionAVR zum compilieren. Ich habe mir schon die informationen nach dem compiliervorgang nagekucjt aber nichts auffälliges gefunden. Villeicht seht ihr da etwas das nicht passt: 6030 line(s) compiled No errors 1 warning(s) Bit variables area: 2h to 2h Bit variables size: 1 byte(s) Data Stack area: 100h to 4FFh Data Stack size: 1024 byte(s) Estimated Data Stack usage: 68 byte(s) Global variables area: 500h to 71Eh Global variables size: 543 byte(s) Hardware Stack area: 71Fh to 10FFh Hardware Stack size: 2529 byte(s) @wolli "Prinzipiell sollte man aber vorher einschätzen, wie tief die Rekursion in einem Programm ist." Theoretisch schon richtig, aber mit einem Betriebssystem ist das nicht so einfach nach zu vollziehen was es wann auf den Stack legt.
@genauso namenlos: "wär schon angenehmer wenn Du Deinen Namen posten würdest !!" Markus Kempf - fühlst du dich jetzt besser? "Aber mach mal was "Ordentliches": http:\\www.e-lab.de" Also bevor ich fast 500 für noch mehr verbugte Software ausgebe kauf ich mir lieber ein JTAG ICE debugger. Wobei ich im Augenblick nicht wüsste wo ich als armer Technikerschüler soviel Geld hernehmen sollte. "Was erwartest Du denn von dem Chaos, das ein C-Compiler zuläßt ???" Natürlich ist mir klar das jeder Compiler unötiges und unsauberes Produziert aber was ist die alternative? Alles in Assembler zu proggen? Assembler ist auch kein allerheilmittel gegen Bugs, das haben wir erst diesen Dienstag wieder festgestellt als wir in Automatisierungstechnik ne einfache RS232 kommunikation Programmiert haben und 2 Stunden nach Fehlern suchten. Ach noch was...Weisheiten bringen mich nun gar nicht weiter, trotzdem danke!
Hallo, Um welches Betriebssystem handelt es sich denn ? Pack das ganze Projekt (inkl. hex und map files) doch mal in den Anhang, sonst können wir nur raten ... Gruß Fiffi
Also irgendwie hab ich in erinnerung das ein Betriebssystem normalerweise für jeden Task seinen eigenen Stack anlegt, also sollte die Stackgröße min. so groß sein wie für den einzelnen Task notwendig. Bei einem Taskwechsel werden zusätzlich noch die Register mit auf den Stack gelegt, aber mehr sollte da eigentlich nicht passieren. Also wenn du deinen Task wie eine selbständige main-Routine betrachtest, solltest du auch abschätzen können wie groß der Stack sein sollte. Aber das kann ja bei deinem OS alles ganz anders sein, also schau mal in die Doku, ob sich jemand darüber auslässt....... Gruß Peter
Ich schreibe ans Stackende eine Sequenz, die ich dann im Timer-IR regelmässig teste. Läuft der Stack über, ist die Sequenz überschrieben, und ich kann entsprechend reagieren: während der Entwicklung mit einer Warnmeldung, im fertigen Produkt mit einem Watchdog-Reset. Ich habe auch den JTAG-Debugger und kann den nur empfehlen. Es gibt auch Nachbauprojekte, die preislich sehr günstig kommen (habe ich aber noch nicht probiert). Welches Betriebssystem verwendest Du? Stefan
Hall Leute, ich hätte da mal ne ziemlich DUMME FRAGE: Wenn der Fehler erst nach der Deklaration der Variablen "e" aufgekommen ist und das Programm vorher stabil lief, warum stellt Ihr die Leistung des Compilers in Frage???? Kann es nicht vielmehr sein, das die Variable "e" vom Betriebsystem für die Funktion "e hoch x" als Konstante (2,71828.....) vordefiniert ist und das System durch die erneute Deklaration ins "trudeln" kommt?????? GRUSS INGO
Wie schon oben gesagt wurde, muß ja ein Multitaskingsystem extrem verschwenderisch mit Speicher umgehen, da es ja jeden Prozeß vollständig sichern muß, bevor es auf einen anderen umschalten kann. Beim Main-Loop Prinzip laufen die Programmteile echt nacheinander, d.h. es wird nur soviel Speicher benötigt, wie ihn der größte Prozeß benötigt. Beim Multitasking läuft zwar auch alles hintereinander ab, aber vom Compiler aus gesehen gleichtzeitig, da die Taskumschaltung ja völlig willkürlich erfolgt. Deshalb muß er notgedrungen "maximalen Speicherverbrauch einer Task" * "Anzahl der Tasks" reservieren also Unmengen mehr. Und in Deinem Fall wird warscheinlich für jede Task eine maximale Speicherbelastung von 24 Byte reserviert. Und beim 25 Byte krachts dann eben. Da MCs aber relativ wenig Speicher haben und die Taskumschaltung auch einen erheblichen Anteil an Rechenzeit benötigt, wird Multitasking auf MC sehr selten verwendet. Eher bei kleinen Aufgaben, wo insgesamt nicht viel Speicher gebraucht wird, der MC-Typ also reichlich überdimensioniert ist. Der Nachteil der Main-Loop Methode ist ja, daß die einzelnen Prozesse laufzeitfreundlich geschrieben werden müssen, d.h. nicht in einer riesen Delay-Loop verhungern dürfen, sondern bei ungenutzer Rechenzeit selber zum main() zurückkehren müssen. Wenn man sich aber erstmal daran gewöhnt hat, so zu programmieren, sind die Programme sogar echtzeitiger (schneller) als ein Echtzeit-OS. Peter
Hallo Peter, könntest Du mal genauer erklären, mit welchem Multitasking-System Du persönlich so schlechte Erfahrungen hast? Oder kann es sein, dass Du das alles nur vom Hörensagen kennst? Stefan
Ok, danke für eure beteiligung an meinem Problem aber ich hab es soeben gelöst. Es lag wirklich am Stackspeicher. Ich habe heute morgen nocheinmal konzentriert die gesammte Doku des PR_RTX der Firma Progressive Resources LLC durchgeshen und eine Möglichkeit gefunden die Stackgröse für jeden Task anzupassen. Ich habe dann die Stackgröse für den Task mit der zusätzlichen Variable "e" um einige bytes erhöht und das Problem war behoben. Ich entschuldige mich für meinen übereilten Post aber ich war nach einem langen Programmiertag einfach etwas frustriert und musste das irgendwo loswerden. Gruß Markus.
@Stefan "könntest Du mal genauer erklären, mit welchem Multitasking-System Du persönlich so schlechte Erfahrungen hast?" Ich hab doch nirgends was von schlechten Erfahrungen gesagt. Es gib ja einen Haufen verschiedene OS. Wenn jenes, welches Markus verwendet, die Vergrößerung des Speichers für jeden Task einzeln gestattet, dann stimmt in diesem konkreten Fall meine obige Formel natürlich nicht mehr. Das ändert aber grundsätzlich nichts an der Tatsache, daß wesentlich mehr Speicher benötigt wird. Und das macht dann auch die Programmierung nicht gerade einfacher, wenn man sowas machen muß, um ein Progamm wieder zum Laufen zu bringen. Peter
Hi @all, >Wie schon oben gesagt wurde, muß ja ein Multitaskingsystem extrem >verschwenderisch mit Speicher umgehen, da es ja jeden Prozeß >vollständig sichern muß, bevor es auf einen anderen umschalten kann >Beim Main-Loop Prinzip ... da muß ich auch mal eine Lanze für den o.a. AVRco brechen: der unterscheidet zw. Prozessen und Tasks. Ein Task ist das, was Peter als "Main-Loop"-Programm bezeichnet. Es gibt also für ALLE Tasks nur eine Umgebung. Der Task muß natürlich sicherstellen, daß er innerhalb seiner erlaubten Zeit (einstellbar mittels Prioritäten) fertig wird. Sonst wird er abgebrochen. Jeder Prozess läuft "immer im Kreis rum". D.h. für JEDEN Prozeß wird beim Unterbrechen die gesamte Umgebung gesichert und -wenn der Prozeß wieder dran ist- die Umgebung wieder hergestellt und er wird dort fortgesetzt wo er unterbrochen wurde. Man kann sich -je nach Teilaufgabe- das geeignete Konzept wählen. Das finde ich optimal. @Markus: zieh Dir von E-Lab mal das Tutorial. Da ist gleich am Anfang der Verweis auf ein Beispiel, das mit der freien (eingeschränkten) Version erstellt wurde. Alleine schon damit kann man sehr viel machen. Außerdem gibt es auch noch eine Spezialversion für den Mega8 für (IIRC) EUR 25,-. Bislang hat die für meine Projekte immer mehr als genügt. Und unschätzbar wertvoll ist m.E. der Support im Forum. Bei Problemen (auch bei Verständnis-Schwierigkeiten) hilft Dir der Chef-Programmierer persönlich. Und - wenn Du mal einen Bug entdeckst: Du bekommst ein paar Stunden später per Mail eine korrigierte Version des Compilers und am nächsten Morgen steht diese für alle zum Down- load bereit. Für Stack-Probleme gibt es übrigens einen Simulator. Da kannst Du alle möglichen Kombinationen testen und Dir dann eine Statistik anschauen, die für jeden Task/ Prozess div. Werte anzeigt(Rechenzeit / max. Stack Verbrauch etc.). Bevor jetzt falsche Vermutungen aufkommen: ich werde NICHT von E-Lab bezahlt. ;-) Ich bin nur von dem AVRco und dem Support restlos begeistert. Deshalb auch nochmal der Link: www.E-Lab.de Schöne Grüße Gunter
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.