Hallo Leute, ich bastel momentan an meinem Tricopter Regler mit dem µc XMega128A1. Entwickelt wird unter Ubuntu Linux 10.04 (32bit) mit dem Eclipse Plugin. Die Treiber für die Sensoren laufen mittlerweile schon, aber leider nur "einzeln". Beide Sensoren hängen über TWI an PORTE und PORTF (also TWIE und TWIF). Lasse ich nur den Beschleunigungssensor auslesen kappts. Wenn ich nur das Gyro auslese klappts auch. Werden beide Sensoren ausgelesen (alles interruptbasiert) bleibt der µC einfach stehen. Und das in Codeblöcken, in denen eigentlich nichts großes passiert, ausser ein paar Berechnungen. Folgendes konnte ich schon in Erfahrung bringen, bzw. ausschliessen: * Main wird nicht mehr durchlaufen * While Schleifen werden überwacht * In einem Interrupt hängt er auch nicht fest * Main wird nicht verlassen So langsam gehen mir wirklich die Ideen aus und ich wäre über einen Tipp wirklich sehr sehr dankbar, wo ich noch suchen kann bzw. was die Ursache sein könnte .... Grüße, Michael
Gast
#1989818
definitiv in zeite 42 ... da haste nen fehler
Gast
#1989826
Zeile 23 würd ich sowieso prüfen...
Hallo gascht, Peterp, :) ich hab schon verstanden, aber Projekt ist wirklich nicht klein! Mir gehts mehr darum, ob jemand sowas schon mal hatte und evtl. eine Lösung bzw. eine Strategie hat um den Fehler zu lokalisieren. Ich kann mir nicht vorstelle, dass sich jemand durch den Sourcecode wühlen will (rund 25 Dateien, ich hab ihn trotzdem mal angehängt ...) Grüße, Michael
Hallo ich nochmal, jetzt wirds spannend: Hab grad mal unter Windows gebootet und die aktuellen Sourcen ausgecheckt (svn) und unter Win kompiliert und geflasht ... und es läuft!? Was ich festgestellt habe, ist eine unterschiedliche Kompilerversion: Windows: avr-gcc 4.3.3 (WINAVR 20100110) Linux: avr-gcc 4.3.4 bitte jetzt keine Ratschläge ala "na dann prog halt unter Windows" .... Grüße, Michael
Also. Debuggen, dh den Fehler finden ist Teil der Entwicklung, und sollte schon zu Begin eingeplant werden. Dh die Leiterplatte sollte die passenden Testpunkte enthalten. Der Code sollte hinreichend modular sein, um die Funktionalitaet einer jeden Komponente pruefen zu koennen. Dann beginnt man mit dem Laufenlaassen einer jeden Komponente. Ich bevorzuge das UART, denn damit kann man zur Laufzeit Variablen anschauen. Ich hatt auch schon Designs, da hatt ich einen 8x 8 bit DAC auf einem gesteckten Adapter, damit konnte man dann zum Debuggen ein paar schnelle Variablen aufm Scope anschauen.
Hallo hacky, danke für Deine Antwort. Genau was Du beschreibst habe ich heute den ganzen Tag getrieben. Der Aufbau ist noch verkabelt und noch nicht auf einer Platine. Der Proz ist auf einem Headerboard von Alvidi und die Sensoren sind per Stiftleisten und mit angelöteten Kabeln verbunden. Stromversorgung und TWI Pegel sind mit Oszi und LA geprüft und da passt auch alles! Komischerweise läuft der Code ja, wenn unter Windows kompiliert ohne Probleme, was ich vorhin rausgefunden habe. Unter Linux treten seltsame Dinge auf, wie dass der Proz an manchen Stellen einfach eben stehen bleibt. Und das leider auch nicht reproduzierbar, sondern immer an einer anderen Stelle. Sogar innerhalb von Funktionen, wo eigentlich nichts ist, wo er stehen bleiben könnte. Ich hab sogar zwischen den Berechnungen in der Datei fc.c entsprechende Debug Ausgaben produzieren lassen und plötzlich geht nix mehr. Die Interrupts haben ALLE auch eine Debug Ausgabe, d.h. ich würde es mitbekommen, wenn da irgendwas schief läuft .... Speicher bzw. Stack kanns eigentlich auch nicht sein. Das schreibt der Kompiler: AVR Memory Usage ---------------- Device: atxmega128a1 Program: 12752 bytes (9.2% Full) (.text + .data + .bootloader) Data: 137 bytes (1.7% Full) (.data + .bss + .noinit) Build succeeded with 0 Warnings... Wirklich sehr suspekt. Ideen ?? Grüße, Michael
-Vergleich mal die Hexfiles produziert unter Windows und von unter Linux. Sie sollten eigentlich identisch sein. Falls unterschiede ausserhalb des Codes zu finden sind : -Die Pfade zu den Libraries kontrollieren. -Kann es sein, dass ein nicht expizit initialisierter Pin beim Einen auf Input steht, beim anderen auf Output ?
Hallo Hacky, ich hab die Hexfiles mal verglichen. Die Dateigröße ist identisch, aber der offenbart einige Unterschiede (ist nur der Anfang ...): diff Linux/Flightcontrol.hex Windows/Flightcontrol.hex 11,12c11,12 < :1000A0000C94390A0C94390A0C94390A0C94E41013 < :1000B0000C94390A0C94390A0C940F130C94390AD5 --- > :1000A0000C94390A0C94390A0C94390A0C947A0C81 > :1000B0000C94390A0C94390A0C94A50E0C94390A44 27,28c27,28 < :1001A0000C94390A0C94390A0C94390A0C947B1576 < :1001B0000C94B9130C94390A0C94390A0C94390A2A --- > :1001A0000C94390A0C94390A0C94390A0C941111E4 > :1001B0000C944F0F0C94390A0C94390A0C94390A98 Lib Pfade sind bei beiden OS in Ordnung und die Dateien sind definitiv identisch (beide aus dem gleichen SVN ausgecheckt). Wenn ich mich recht erinnere, stehen bei den XMegas nicht initialisierte IOs immer auf Eingang, wenn nicht explizit als Ausgang definiert. Da beide Sensoren ja an den TWIs hängen, wird die "DIR" Konfiguration ja vom TWI Modul überschrieben ... Das komische ist ja, dass beide Sensortreiber wunderbar laufen, wenn jeweils nur einer aktiviert ist. Sind beide aktiv, also sollen Daten von beiden Sensoren abgefragt werden, so tritt der Effekt mit dem "Freeze" auf, aber eben nur, wenn unter Linux kompiliert wurde. Echt strange .... Grüße, Michael
Hi, hier noch mal die beiden Hexfiles. Grüße, Michael
Gast
#1990113
Hmm. Es müsste, denke ich, geklärt werden ob der Unterschied in Deinem Code liegt oder innerhalb einer der Libraries. Vergleich doch mal die Assemblerlistings. Da siehst Du die Adresse und ob der fragliche Code Dein eigener ist oder nicht.
Gast
#1990122
Du schreibst, das Du identlsche Libraries verwendet hast, aber mit zwei verschiedenen Versionen des Compilers. Theoretisch sollte also Dein Code und der Code der Libraries im Listing bzw. Hex-File identisch sein. Dennoch gibt es einen Unterschied. Jetzt ist die Frage was genau der Unterschied ist. Das wird evtl. nicht unmittelbar zur Problemlösung führen, aber unter Umständen einen Ansatzpunkt liefern. Es wäre auch interessant mal die Beschreibung der Releases anzuschauen, ob sich da ein Anhaltspunkt ergibt bzw. ob und wie die Neuerung bei dem späteren Release mit dem Unterschied im Listingfile korreliert. Alles ein wenig mühsam und nicht einfach aber das ist der Weg, denke ich.
Gast
#1990133
Hallo, ich hatte mal das Problem, dass Objektdateien nicht neu gebaut wurden und deshalb alte Objektdateien gelinkt wurden. Lösche diese mal manuell und baue das Projekt neu. Denn dies ist vermutlich passiert, beim Auschecken unter Windows...
@Huch: Der Code stammt von mir und liegt auch in einem eigenen SVN Repos. Die Lib-Versionen sollten gleich sein, aber prüfe ich gleich noch mal und schau' ob da Unterschiede sind. Wie genau komme ich denn an die Assembler Listings?? Unter AVR Studio kannte ich, dass man beim Simulieren sich den ASM Code anzeigen lassen kann ... weißt Du wie das unter Linux geht?? @Wat: Beide OS Varianten wurden frisch kompiliert, also vorher "gecleaned" und dann gebaut ... Danke für die Anregungen!! Ich halte Euch auf dem Laufenden! Grüße, Michael
Gast
#1990180
>@Huch: Der Code stammt von mir und liegt auch in einem eigenen SVN
Repos.
Mir ist gerade nicht klar, was Du damit sagen willst.
Ich wollte darauf hinaus, dass es Code gibt den Du (oder wer auch immer)
geschrieben hast und solchen der aus den Libraries stammt.
Wesentlich daran, ist folgendes: Liegt der Unterschied im resultierenden
Hex-File in dem Bereich des Library-Codes so bedeutet das etwas anderes
als wenn der Unterschied in "Deinem" Code liegt.
Was das Listing File mit gcc unter Linux betrifft muss man da eine
Option hinzufügen, denke ich. Bin gerade zu faul selbst nachzusehen.
Mach Du das bitte selbst.
Ah, verstehe. Ich hab grad nochmal die Libversionen gecheckt und die sind identisch (Linux sagt: avr-lib 1:1.6.7-1ubuntu2, WINAVR V.20100110 sagt im WINAVR-User-Manual.txt unter Punkt 2.1 Manifest: 3. avr-libc 1.6.7cvs). Fragt sich nur, ob gleiche Version = gleicher Code !? Der Quellcode ist definitiv identisch .... hab die Dateien mal auf nen Stick gezogen und gedifft. Kein Unterschied. Ich installier grad das Linux in einer VM um nicht dauern umbooten zu müssen. Dann checke ich mal die Listing Unterschiede. Wusste nicht, dass der gcc, respektive der avr-gcc direkt so ein Listing erzeugen kann... DANKE! Grüße, Michael
Gast
#1990196
>Fragt sich nur, ob gleiche Version = gleicher Code !? >Der Quellcode ist definitiv identisch .... hab die Dateien mal auf nen >Stick gezogen und gedifft. Kein Unterschied. Also der Quellcode der Libraries ist identisch? Das wäre schon mal eine Information.
Gast
#1990204
Wo wir schon über Optionen reden könntest Du auch mal die Optionen beim Bau mit der alten Compilerversion mit denen beim Bau mit der neuen Version vergleichen.
Was ich geprüft habe ist der Quellcode von meinem Code, nicht den der Libraries. Die liegen ja als .a vor und sind schon kompiliert ;-) Ausser ich zieh mir die sourcen .... ich teste jetzt mal mit den Kompileroptionen ... -g -Wa,-adhlns=file.lst klingt schon vielversprechend ...
Gast
#1990224
>Was ich geprüft habe ist der Quellcode von meinem Code, nicht den der Libraries. Ach so. Ich habe in den Sätzen: >Ich hab grad nochmal die Libversionen gecheckt und die >sind identisch (Linux sagt: avr-lib 1:1.6.7-1ubuntu2, WINAVR V.20100110 >sagt im WINAVR-User-Manual.txt unter Punkt 2.1 Manifest: 3. avr-libc >1.6.7cvs). Fragt sich nur, ob gleiche Version = gleicher Code !? >Der Quellcode ist definitiv identisch .... hab die Dateien mal auf nen >Stick gezogen und gedifft. Kein Unterschied. die Frage "ob gleiche Version = gleicher Code" als rethorisch verstanden, denn in dem nachfolgenden "Der Quellcode ist definitiv identisch..." wurde das Satzsubjekt nicht vollständig neu spezifiziert, so das sich "Quellcode" auf den Quellcode der Library zu beziehen schien. Ich denke den Vergleich der Quellcodes der Library brauchst Du jetzt nicht zu durchzuführen. Das wesentliche ist erstmal, anhand des Listing-Files erstmal festzustellen wo der Unterschied liegt und zu welcher Quellcode-Zeile der Unterschied gehört. Dann kann man weiter sehen.
Gast
#1990319
Als Ansatz:
1 | |
2 | |
So sieht als Beispiel ein make target für das Listing aus. Grüße
@alibaba: Vielen Dank! Habs auch schon gefunden ;-) Anbei die beiden Listings .... ich hab die beiden auch mal gedifft und es gibt einige Unterschiede (mit Notepad++ über Erweiterungen->Compare->Compare). Ich verstehe nur leider noch nicht ganz wonach ich suchen soll ...?? Und asm verstehe ich auch nur in den Grundzügen ... ich hoffe Ihr könnt daraus mehr lesen als ich!! Grüße, Michael PS: In dem Linux listing sind anscheinend keine Debug Informationen drin ... Ich versuch da mal welche reinzubekommen ....
Aus dem Unterscheid der Hexfiles kann man die Adresse herausziehen. Siehe Aufhau von Hex-files. Dann im ASM Listing die Zeilennummer suchen.
So der Vollständigkeit anbei noch das Linux Listing mit debug Informationen. @hacky: Die Hexfiles unterscheiden sich ja schon in der ersten Zeile! Könntest Du bitte kurz ausführen, wonach ich suchen muss? Auch die Speicheraufteilung scheint zwischen Win und Lin unterschiedlich zu sein ... Am Anfang stehen die Strings, die im Flash abgelegt worden sind. Da ist z.B. die Reihenfolge schon gänzlich anders .... Grüße, Michael
Gast
#1990585
@ Michael K.
Kriegst Du das erste Listing (Linux) auch so hin, dass die
C-Source-Zeilen mit in dem File stehen. Das wäre viel einfacher.
>Ich verstehe nur leider noch nicht ganz wonach ich suchen soll ...??
Das kann ich im voraus leider auch nicht genau sagen. Man sollte mal die
C-Zeilen angucken bei denen im Assembler-Code ein Unterschied besteht.
Eine Vermutung wäre, das Du ein C-Statement etwas unglücklich formuliert
hast. Es funktioniert zwar aber vielleicht aber nicht wenn ein Bug
beseitigt wurde. Da gibt es viele Möglichkeiten C-Befehle zwar
syntaktisch korrekt zu formulieren aber so, das es nur unter bestimmten
Bedingungen geht, die im C-Standard als "implementierungsabhängig"
gekennzeichnet sind.
@Huch: Meinst Du das Listing? (Beitrag "Re: XMega bleibt "hängen"?") In diesem sind die C-Source-Zeilen mit drin ... Grüße, Michael
Gast
#1991168
>In diesem sind die C-Source-Zeilen mit drin ...
Oops. Habe ich nicht gesehen.
Ist es möglich, dass es zu einem Stack Overflow kommt? Es könnte z.B. sein, dass unter Windows in den Compileroptionen Optimierungen an sind, die den Code beschleunigen, so dass es nicht zum Stack Overflow kommt. Ein Debugger hast du nicht, wenn ich das geschriebene richtig interpretiere?
Gast
#1991190
Hallo.. Sagt mal, den einfachsten aller Fälle, einen Programmierfehler, hat hier noch keiner angenommen? (Die Frage, warum er unter Win geht und unter Lin nicht, wäre mir zunächst egal, ich würde den Fehler suchen. Bestimmt nicht in den Libs, eher in meinem Code...) Stichworte wie "atomar" sollten da hellhörig machen.. Gruss, T. PS: If stack full, erase stack.
Gast
#1991235
>Die Dateigröße ist identisch, aber der offenbart einige Unterschiede Also, ich habe mir "einige" Unterschiede anders vorgestellt. So drei bis 20-40. Aber das hier ist doch eine etwas andere Dimension. Deine sprachlichen Äusserungen darf man wohl nicht ganz ernst nehmen. Ist nicht böse gemeint, aber es ist natürlich wichtig zu wissen wie präzise Du Dich ausdrückst. Ich habe ehrlich gesagt keine Lust die Unterschiede selbst zu suchen und würde ansgesichts der Menge doch erstmal versuchen den Fehler mittels Debugging einzugrenzen. Du hast nun folgende Möglichkeiten, denke ich: 1. Suche die Unterschiede selbst heraus und präsentiert sie hier. Es geht um die C-Codezeilen, der zugehörigen Assemblerzeilen die unterschiedlich sind. Jedoch sind reine Unterschiede in den Sprungzielen dabei irrelevant. - Ganz ehrlich, habe ich das Gefühl, das Du damit überfordert sein könntest. 2. Versuche den Fehler auf der Ebene des C-Codes zu finden. Das scheint mir eher erfolgversprechend. -------------------------------------- Solltest Du Alternative 2. wählen, dann erkläre doch mal folgendes aus Deinem ersten Posting. Ich kann damit wenig anfangen. >* Main wird nicht mehr durchlaufen Wie stellst Du das fest? Was meinst Du damit? >* While Schleifen werden überwacht Wie stellst Du das fest und was heisst hier "überwacht"? Von wem, mit welchen Mitteln, und welchen Ergebnissen? >* In einem Interrupt hängt er auch nicht fest Wie stellst Du das fest? Das ist ein Widerspruch zum ersten Punkt: Wenn der uC main nicht ausführt und keinen Interrupt, was macht er dann? >* Main wird nicht verlassen Das sollte so sein bei einem uC-Programm, was erscheint Dir daran bemerkenswert? ----------------------------------------------------------------- Ich hoffe Du hast Verständnis dafür, dass ich Dich auf die besondere Bedeutung einer möglichst korrekten Beschreibung der Fakten hinweise. Falls Du Anfänger bist, haben wir durchaus Verständnis für unkorrekte Ausdrucksweise. Ein Beispiel ist: " bleibt der µC einfach stehen." Der uC bleibt nur dann stehen, wenn der Takt wegbleibt oder er abbrennt oder jemand drauftritt. Sonst läuft er immer weiter. Es ist ihm unmöglich "stehenbleiben". Das geht garnicht. Was also meinst Du damit? In diesem Fall wäre zusätzlich die Angabe nützlich, auf welche Weise und anhand welcher Kriterien Du denn feststellst, das er "stehenbleibst". Daraus können wir uns dann wieder in passende Begriffe 'übersetzen' was Du damit meinst. Aus den Reaktionen kannst Du auch lernen wie man sich in dem Thema korrekt ausdrückt. Evtl. stellen wir aber auch fest, das Deine Kriterien oder die Verfahren verbessert werden können. Auch interessant.
Hallo zusammen, @Benni L.: * Stackoverflow: keine Ahnung ... wie könnte ich das feststellen? * Debugger ist vorhanden (Atmel JTAG MKII). Als die Software unter Linux immer "stehen blieb" (dazu später mehr) wollte ich unter Windows debuggen (unter Linux geht debugging (noch) nicht). Da hab ich dann eben festgestellt, dass der, unter Win kompilierte Code druchläuft. * Compileroptionen sind identisch und überprüft Was ich als nächstes machen werde, ist den Code von Linux unter Windows flashen und vor allem debuggen ... vllt. sieht man dann wo er "hängen bleibt". @T.O.: * Programmierfehler schließe ich natürlich nicht aus! Ich hab schon wirklich "megabyteweise" debug Informationen über die USART rausgelassen und zudem mit dem LA Pinwakler gecheckt. @Huch: > Also, ich habe mir "einige" Unterschiede anders vorgestellt. So drei bis > 20-40. Aber das hier ist doch eine etwas andere Dimension. * stimmt ...leider! > Deine sprachlichen Äusserungen darf man wohl nicht ganz ernst nehmen. > Ist nicht böse gemeint, aber es ist natürlich wichtig zu wissen wie > präzise Du Dich ausdrückst. * Ich versuche daran zu arbeiten! > Ich habe ehrlich gesagt keine Lust die Unterschiede selbst zu suchen und > würde ansgesichts der Menge doch erstmal versuchen den Fehler mittels > Debugging einzugrenzen. Das erwarte ich auch gar nicht!! Ich will den Fehler schon selber finden! Bzgl. debugging: s.o. > Du hast nun folgende Möglichkeiten, denke ich: > > 1. Suche die Unterschiede selbst heraus und präsentiert sie hier. Es > geht um die C-Codezeilen, der zugehörigen Assemblerzeilen die > unterschiedlich sind. Jedoch sind reine Unterschiede in den Sprungzielen > dabei irrelevant. > - Ganz ehrlich, habe ich das Gefühl, das Du damit überfordert sein > könntest. * Überfordert bin ich noch nicht ... ist halt viel Arbeit da Unterschiede zu finden und vor allem dauert es eifach ... > 2. Versuche den Fehler auf der Ebene des C-Codes zu finden. > Das scheint mir eher erfolgversprechend. Bin dabei. > -------------------------------------- > > Solltest Du Alternative 2. wählen, dann erkläre doch mal folgendes aus > Deinem ersten Posting. Ich kann damit wenig anfangen. > >>* Main wird nicht mehr durchlaufen > Wie stellst Du das fest? Was meinst Du damit? Ich hab in der main nen USART output drin gehabt, ala Debug_Str ("."); Wenn der µC "stehen" bleibt, dann kam über UART kein "." mehr. Meine Vermutung war dann, dass der µC in entweder ein Schleife hängt, oder ein Interrupt permanent auslöst wird und er darin "festhängt". >>* While Schleifen werden überwacht > Wie stellst Du das fest und was heisst hier "überwacht"? Von wem, mit > welchen Mitteln, und welchen Ergebnissen? Alle while - Schleifen haben eine Debug Ausgabe drin (gehabt). In keiner der Schleifen hing der µC länger als erwartet. >>* In einem Interrupt hängt er auch nicht fest > Wie stellst Du das fest? Das ist ein Widerspruch zum ersten Punkt: Wenn > der uC main nicht ausführt und keinen Interrupt, was macht er dann? Debug - Ausgaben am Anfang und am Ende der ISR. >>* Main wird nicht verlassen > Das sollte so sein bei einem uC-Programm, was erscheint Dir daran > bemerkenswert? Das ist eine der Möglichkeiten, wie der µC "stehen" bleiben kann ;-). Macht man im main ein return, ist Schluss mit "arbeiten" .... > ----------------------------------------------------------------- > > Ich hoffe Du hast Verständnis dafür, dass ich Dich auf die besondere > Bedeutung einer möglichst korrekten Beschreibung der Fakten hinweise. > Falls Du Anfänger bist, haben wir durchaus Verständnis für unkorrekte > Ausdrucksweise. Anfänger bin ich nicht mehr, ich hoffe das sieht man auch ein wenig am Code, aber Profi bin ich auch nicht. Ich programmiere hauptberuflich, aber eben nur auf PCs unter Linux. Wenn ich mich unkorrekt ausgedrückt habe, dann möchte ich mich dafür entschuldigen! Ich arbeite dran! > Ein Beispiel ist: " bleibt der µC einfach stehen." > Der uC bleibt nur dann stehen, wenn der Takt wegbleibt oder er abbrennt > oder jemand drauftritt. Sonst läuft er immer weiter. Es ist ihm > unmöglich "stehenbleiben". Das geht garnicht. Was also meinst Du damit? Es kommen keine Debug Ausgaben über UART mehr. PC seitige Probleme kann ich dabei ausschließen. Zudem zeigt der LA keine Aktivität mehr an "Toggelpins" und die angeschlossene LED (die blinken sollte) bleibt entweder statisch an oder aus. > In diesem Fall wäre zusätzlich die Angabe nützlich, auf welche Weise und > anhand welcher Kriterien Du denn feststellst, das er "stehenbleibst". > Daraus können wir uns dann wieder in passende Begriffe 'übersetzen' was > Du damit meinst. Aus den Reaktionen kannst Du auch lernen wie man sich > in dem Thema korrekt ausdrückt. Evtl. stellen wir aber auch fest, das > Deine Kriterien oder die Verfahren verbessert werden können. Auch > interessant. s.o. Grüße, Michael
Gast
#1992090
>* Ich versuche daran zu arbeiten! > Anfänger bin ich nicht mehr, ich hoffe das sieht man auch ein wenig am > Code, aber Profi bin ich auch nicht. Ich programmiere hauptberuflich, > aber eben nur auf PCs unter Linux. Gut. Ich werde das berücksichtigen. Aber vorerst werde ich Deine Antworten weiter hinterfragen. >Wenn ich mich unkorrekt ausgedrückt habe, dann möchte ich mich dafür >entschuldigen! Das ist wirklich und absolut unnötig. Ich mache Dir keine Vorwürfe, erwarte keine Zerknirschung, kein Bedauern, keine Unterwerfung oder Wiedergutmachung. Wenn ich darüber schreibe, dann allein deswegen weil diese sprachlichen "Eigenheiten" den Analyseprozess entstellend beeinflussen. Ich will trotzdem versuchen Dir mit dem was ich weiss zu helfen. Gehe Dir mit dem sprachlichen Zeug wahrscheinlich ein paarmal auf die Nerven. Das mit dem Debuggen der Windows-Variante unter Linux scheint mir ein guter Ansatz zu sein. Denke daran, das das ausbleiben der Debug-Ausgabe kein "Anhalten" bedeutet sondern nur, dass der durchlaufene Code keine Ausgaben erzeugt. Genauso der Zustand in dem keine Änderungen an der LED oder den Ports mehr erfolgen. Eine weiter Möglichkeit wäre die Debug-Ausgaben weiter zu differenzieren. Gib eine Kombination aus einem Buchstaben für die Funktion und einer Zahl für einen Schritt in der Funktion aus. (Nicht zu fein gliedern). Was mir auffällt, ist das Du im Text von Debug-Ausgaben innerhalb des Interrupts sprichst. An sich ist das absolut tödlich, wenn etwa Ausgaben selbst auch über Ints laufen. Wenn Du das nicht komplett aus den ISRs entfernen willst dann kommentiere es mal aus. Eine durchaus reale Möglichkeit, das hier was knackt. Ehrlich gesagt halte ich die Möglichkeit des Stacküberlaufs für wahrscheinlich. Um das zu erkennen kannst Du den Speicher mal mit einem Muster vollschreiben und hinterher sehen ob das Muster noch da ist. Gab hier gerade vor ein paar Tagen eine Diskussion dazu. Suche einfach danach. Falls es tatsächlich am Stacküberlauf liegt wirst Du mit den bisherigen Debugausgaben nur bedingt weiterkommen, weil der Code an sich korrekt ist aber zu viele Verschachtelungsebenen auftreten. Du kannst evtl. eine Debug-Ausgabe basteln die die die Aufrufebenen zurückgibt, bzw. den Stackpointer. Du könntest auch mal im Code gucken ob irgendwo absichtlich oder unabsichtlich Rekursionen auftreten und ob die Abbruchbedingungen wirklich mit true bewertet werden. Läuft der Code im Simulator? Kannst Du den Fehler im Simulator auch provozieren? Eine gute Möglichkeit ist auch, einen Lint über Deinen Code laufen zu lassen. Es gibt da einige für Linux. Falls noch nicht geschehen, lasse Dir alle Warnings ausgeben und beseitige alle (zeige die die Du meinst nicht beseitigen zu können). So, das sind einige Vorschläge. Über die Reihenfolge könnte man noch gesondert reden, aber da Du schreibst das Du Programmiererfahrung hast, kannst Du das wahrscheinlich selbst gut entscheiden.
Huch schrieb: >>* Ich versuche daran zu arbeiten! >> Anfänger bin ich nicht mehr, ich hoffe das sieht man auch ein wenig am >> Code, aber Profi bin ich auch nicht. Ich programmiere hauptberuflich, >> aber eben nur auf PCs unter Linux. > > Gut. Ich werde das berücksichtigen. Aber vorerst werde ich Deine > Antworten weiter hinterfragen. Gerne! > >>Wenn ich mich unkorrekt ausgedrückt habe, dann möchte ich mich dafür >>entschuldigen! > Das ist wirklich und absolut unnötig. Ich mache Dir keine Vorwürfe, > erwarte keine Zerknirschung, kein Bedauern, keine Unterwerfung oder > Wiedergutmachung. Wenn ich darüber schreibe, dann allein deswegen weil > diese sprachlichen "Eigenheiten" den Analyseprozess entstellend > beeinflussen. Alles klar. Nochmals danke an alle (und speziell an Dich!) ! > Ich will trotzdem versuchen Dir mit dem was ich weiss zu helfen. Gehe > Dir mit dem sprachlichen Zeug wahrscheinlich ein paarmal auf die Nerven. Klasse! Wenn ich dabei lerne, dann ists mir nur Recht! > Das mit dem Debuggen der Windows-Variante unter Linux scheint mir ein > guter Ansatz zu sein. Das habe ich mittlerweile durchführen können mit folgendem Ergebnis: 1. Flashen des unter Linux kompilierten Hexfiles. 2. Laufen lassen --> µC stellt LED blinken, Pintogglen und Debugausgaben ein = "meine" Umschreibung für "hängen bleiben". 3. Debugger klar gemacht und versucht das Linux Hexfile zu debuggen. Also Debugger scharf gemacht und gestartet -> AVR Studio zeigt den ersten Eintrag in der Main, danach F5 (Run) ==> Läuft ... ???? Wirklich seltsam. Wenn der Debugger dran hängt und der µC per Run laufen gelassen wird, dann läufts wie soll. Debugausgaben kommen und die LED blinkt ... Sobald ich das Programm ohne Debugger auf dem µC laufen lassen, bleibt er wieder "hängen". > Denke daran, das das ausbleiben der Debug-Ausgabe kein "Anhalten" > bedeutet sondern nur, dass der durchlaufene Code keine Ausgaben erzeugt. > Genauso der Zustand in dem keine Änderungen an der LED oder den Ports > mehr erfolgen. Klar. Irgendwo ist das Ding in einer quasi "Endlosschleife" aus der er nicht mehr rauskommt ... > Eine weiter Möglichkeit wäre die Debug-Ausgaben weiter zu > differenzieren. Gib eine Kombination aus einem Buchstaben für die > Funktion und einer Zahl für einen Schritt in der Funktion aus. (Nicht zu > fein gliedern). Hab ich verstanden und auch schon gemacht! Werde den morgigen Tag mal nutzen und das ausgiebig erweitern!! > Was mir auffällt, ist das Du im Text von Debug-Ausgaben innerhalb des > Interrupts sprichst. An sich ist das absolut tödlich, wenn etwa Ausgaben > selbst auch über Ints laufen. Wenn Du das nicht komplett aus den ISRs > entfernen willst dann kommentiere es mal aus. Eine durchaus reale > Möglichkeit, das hier was knackt. Verstehe. Die Debugausgaben werden nicht über Interrupts ausgegeben, sondern relativ straight forward: Meine Debugfunktion ist diese hier (PSTR für das ablegen der Strings im PROGMEM): #define Debug_Str(_str) ( dputsP (PSTR(_str)) ) die Funktion dputsP sieht folgendermassen aus: inline void dputsP (const char * str) { while (pgm_read_byte(str) != 0x00) Debug_ch(pgm_read_byte(str++)); } und dann noch die Funktion Debug_ch: inline void Debug_ch (char ch) { USART_putc (&DEBUG, ch); } mit der USART_putc Funktion: void USART_putc (USART_t * _usart, char ch) { // Wait until data register empty interrupt flag is set while(!(_usart->STATUS & USART_DREIF_bm)); // Write char to DATA register _usart->DATA = ch; } mir fällt grad auf, dass hier auch noch ne while Schleife ist, die noch nicht überprüft worden ist. Hole ich nach! > Ehrlich gesagt halte ich die Möglichkeit des Stacküberlaufs für > wahrscheinlich. Um das zu erkennen kannst Du den Speicher mal mit einem > Muster vollschreiben und hinterher sehen ob das Muster noch da ist. > Gab hier gerade vor ein paar Tagen eine Diskussion dazu. Suche einfach > danach. > Falls es tatsächlich am Stacküberlauf liegt wirst Du mit den bisherigen > Debugausgaben nur bedingt weiterkommen, weil der Code an sich korrekt > ist aber zu viele Verschachtelungsebenen auftreten. Du kannst evtl. eine > Debug-Ausgabe basteln die die die Aufrufebenen zurückgibt, bzw. den > Stackpointer. Das klingt sehr möglich! Mehr dazu morgen. Hab mal nach Möglichkeiten gesucht den Stack / Speicherbedarf zu checken gesucht. Ist das hier eine Möglichkeit Beitrag "Re: ATMEGA32 Stackauslastung im AVR Studio anzeigen" ?? > Du könntest auch mal im Code gucken ob irgendwo absichtlich oder > unabsichtlich Rekursionen auftreten und ob die Abbruchbedingungen > wirklich mit true bewertet werden. Mach ich morgen! > Läuft der Code im Simulator? Kannst Du den Fehler im Simulator auch > provozieren? Unter Linux hab ich den Simulator noch nicht bemüht. Könnte man im Simulator auch die Kommunikation mit den Sensoren simulieren?? Denn das, denke ich ist Vorraussetzung für einen sinnvollen Test !? > Eine gute Möglichkeit ist auch, einen Lint über Deinen Code laufen zu > lassen. Es gibt da einige für Linux. Lint kenne ich noch nicht. Ich mach mich mal schlau ... > Falls noch nicht geschehen, lasse Dir alle Warnings ausgeben und > beseitige alle (zeige die die Du meinst nicht beseitigen zu können). Keine Warnings. > So, das sind einige Vorschläge. Über die Reihenfolge könnte man noch > gesondert reden, aber da Du schreibst das Du Programmiererfahrung hast, > kannst Du das wahrscheinlich selbst gut entscheiden. Klasse! Vielen Dank nochmals für die Vorschläge! Grüße, Michael
Hallo, also die ersten Test haben folgendes ergeben: 0. Vorbedingungen: LA an PORTA angeschlossen und alle 8 Leitungen von 0-7 angeklemmt. PIN0 wird getoggelt, wenn main durchlaufen wird. PIN1 wird getoggelt, wenn die "PinChange"-ISR des Gyros ausgeführt wird. Der Sensor setzt einen seiner Pins für 50µs auf high, wenn neue Daten vorliegen. PIN2 wird gesetzt am Anfang der TWI-ISR des Gyros und am Ende davon wieder gecleared. 1. Test: Sensorwerte auslesen und nichts berechnen. Dafür wurde in der Datei fc.c (hier läuft die Berechnung der Lagewinkel (phi, theta, psi - mit Filter) und deren Derivate (phi_dot, theta_dot, ...). In der Funktion wurden alle Berechnungen auskommentiert. Zudem wurde bei jedem 10. neu gelesenen Sensorwert eine LED getoggelt (Gyro wird mit 100Hz ausgelesen). ERGEBNIS: Es läuft durch (hab 10 Minuten gewartet). Das sehe ich an einer blinkenden LED und den Pinwacklern. Ich teste jetzt mal die Stackgeschichte speziell für die Funktion. Grüße, Michael
Also weiterer Test ist erfolgt: 0. Vorbedinungen: Die Stackprüfung wurde mit eingebaut mit folgendem Code: mem-check:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
mem-check.c:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
Sourcen sind von hier: Beitrag "Re: ATMEGA32 Stackauslastung im AVR Studio anzeigen" In der Funktion Flightcontrol () aus der Datei fc.c wurde dann vor jeder Operation ein "Memory Debug" eingefügt: das ganze sieht dann so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
301 | |
302 | |
303 | |
304 | |
305 | |
306 | |
307 | |
308 | |
309 | |
310 | |
311 | |
312 | |
313 | |
314 | |
315 | |
316 | |
317 | |
318 | |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | |
325 | |
326 | |
327 | |
328 | |
329 | |
330 | |
Soweit so gut. Der Log der Debug Ausgaben ist dieser: FC-start: + 7959<\n> LIS: + 7959<\n> LIS-end: + 7959<\n> ITG: + 7959<\n> p: + 7959<\n> q: + 7959<\n> Also der Speicher, wenn ich das Recht interpretiere, kann es nicht sein, dennoch gehts in folgender Zeile nicht "weiter" (µC bleibt stehen, keine ISRs mehr, keine Pinwackler am LA und main wird auch nicht mehr durchlaufen):
1 | |
Das Listing dazu schaut folgendermassen aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
Leider verstehe ich asm so gut wie überhaupt nicht, aber ich versuch mich mal einzuarbeiten! Vllt. fällt jemandem von Euch was auf !? Grüße, Michael
Ein Controller bleibt nicht stehen... Zu den Memorytests : Man sollte dynamisches Memory sowieso vermeiden. Das einzige, was mir auffaellt ist das call _divmodsi4 ... ist das ueberhaupt vorhanden ? Die Adressen 0x2000 + x sind oberhalb 8k. Hat's soviel RAM ?
O.. oha Jetzt ! schrieb: > Ein Controller bleibt nicht stehen... Das dachte ich auch ;-) Er macht nur nach der Zeile nicht im geschriebenen Code weiter, sondern anscheinend irgendwo anders .... > Zu den Memorytests : Man sollte dynamisches Memory sowieso vermeiden. Wie genau meinst Du das?? Malloc verwende ich jedenfalls nicht und die verwendeten array sind alle statisch. > Das einzige, was mir auffaellt ist das call _divmodsi4 ... ist das > ueberhaupt vorhanden ? Die Adressen 0x2000 + x sind oberhalb 8k. Hat's > soviel RAM ? nope. Der XMega128A1 hat 8k .... Bzgl. _divmodsi4 sagt das Listing
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Ich denke Du meinst die Zeile: mit call 0x34c6 Ich kann zwar kein asm, aber ich denke _divmodsi4 ist ne "Funktion", die der Kompiler baut und auch im Flash ablegt, oder liege ich da falsch?? Grüße, Michael
Gast
#1994189
Hi Michael K. tut mir leid, dass ich mich nicht früher gemeldet habe. Gestern Abend ist bei mir ne Virusinfektion ausgebrochen und ich habe 38,5 Fieber. Meine "Birne" ist dementsprechend "matschig". Wenn ich wieder fitter bin, dann schau ich wieder rein. Eines ist mir allerdings trotzdem aufgefallen, (wenn das keine Fieberphantasie ist): In dem Codeschnipsel wo der Debugger nichts weiter anzeigt:
1 | |
2 | |
ist der erste Summand eine Typenbezeichnung und keine Variable. Eigentlich bin ich ziemlich sicher, dass das eine Warnung, wenn nicht sogar einen Fehler zur Folge haben sollte. Wundere mich gerade wieso da keine kommt. (Kann aber auch an meiner Matschbirne liegen). Prüf das mal nach, bitte. Hast Du wirklich alle Warnings eingeschaltet? Das sollte mit -Wall gehen (ohne Gewähr, guck nochmal nach). Mehr in ein paar Tagen wenn ich wieder auf dem Damm bin (und Du das Problem noch nicht anderweitig lösen konntest). Viel Erfolg
Wenn er "irgendwo" weitermacht, dann riecht das verdammt nach nem Stack Overflow. Und den kannst auslösen, indem du zu viele Funktionen aufrufst durch ISRs. Evtl. kannst du noch den Call Stack anschaun. Und schaun wie viel da so drinsteht, bevor der Controller im Nirvana weitermacht. Bzw. schauen ob der Call Stack immer weiter wächst. Problem beim Debuggen ist halt, dass Wartzeiten auf Hardwareeinheiten wie UART durch nen Breakpoint verschwinden. An deiner Stelle würde ich die Debugausgaben per UART mit ner Präprozessoranweisung versehen, so dass die nicht unbedingt im Programm sein müssen. So sind die alle schnell mal weg. Desweiteren, versuch doch mal die Sachen in den ISRs zu verkleinern und evtl. falls du Timerinterrupts benutzt, die Intervalle zu vergrößern. Falls nach ner Schlankheitskur dein Programm läuft war wohl tatsächlich ein Stack Overflow vorhanden.
Gast
#1994193
Im Listing File taucht das mit dem Typnamen an mehreren Stellen auf.
Ich haette die Zeilen gemeint : 1b46: 60 91 44 20 lds r22, 0x2044 1b4a: 70 91 45 20 lds r23, 0x2045 .. .. 1b76: 20 93 0c 20 sts 0x200C, r18 1b7a: 30 93 0d 20 sts 0x200D, r19 1b7e: 40 93 0e 20 sts 0x200E, r20 1b82: 50 93 0f 20 sts 0x200F, r21 Das (: 0x20..) sind zugriffe oberhalb 8k. Sollte aber auch einen Fehler bringen.
Hallo, na jetzt geht ja was vorwärts! Huch schrieb: > Hi Michael K. > > tut mir leid, dass ich mich nicht früher gemeldet habe. > Gestern Abend ist bei mir ne Virusinfektion ausgebrochen und ich habe > 38,5 Fieber. Meine "Birne" ist dementsprechend "matschig". > Wenn ich wieder fitter bin, dann schau ich wieder rein. Kein Problem und GUTE BESSERUNG!! > Eines ist mir allerdings trotzdem aufgefallen, (wenn das keine > Fieberphantasie ist): > > In dem Codeschnipsel wo der Debugger nichts weiter anzeigt: > >
1 | |
2 | |
3 | |
4 | |
> > ist der erste Summand eine Typenbezeichnung und keine Variable. > Eigentlich bin ich ziemlich sicher, dass das eine Warnung, wenn nicht > sogar einen Fehler zur Folge haben sollte. Wundere mich gerade wieso da > keine kommt. (Kann aber auch an meiner Matschbirne liegen). Prüf das mal > nach, bitte. Das soll eigentlich ein Typcast sein. Die Variable (respektive das Array) GyroRaw_i16_m14d375__deg_d_s ist vom Typ int16_t. Diesen Wert will ich nach int32 casten. Compiler schmeisst kein Warning! > > Hast Du wirklich alle Warnings eingeschaltet? Das sollte mit -Wall gehen > (ohne Gewähr, guck nochmal nach). Wall ist drin! > > Mehr in ein paar Tagen wenn ich wieder auf dem Damm bin (und Du das > Problem noch nicht anderweitig lösen konntest). > > Viel Erfolg Danke! @Benni: > Wenn er "irgendwo" weitermacht, dann riecht das verdammt nach nem Stack > Overflow. Ich denke den kann ich ausschließen durch die Memory Prüfung. > An deiner Stelle würde ich die Debugausgaben per UART mit ner > Präprozessoranweisung versehen, so dass die nicht unbedingt im Programm > sein müssen. So sind die alle schnell mal weg. Kein Problem. Mach ich mal! > Desweiteren, versuch doch mal die Sachen in den ISRs zu verkleinern und > evtl. falls du Timerinterrupts benutzt, die Intervalle zu vergrößern. Timerinterrupts sind so gut wie keine drin, bis auf das auslesen des Beschleunigungsensors. Das Auslesen der Sensorwerte produziert keine Fehler, wenn die Berechnung in der fc.c nicht durchgeführt wird. Ich prüfs und teste es trotzdem mal! @hacky: Das Datenblatt für den ATXMega128A1 sagt: SRAM Bereich von 0x2000 - 0x3FFF Grüße, Michael
Gast
#1994227
>Das soll eigentlich ein Typcast sein.
Aber Du siehst das Problem oder? Mit dem Minuszeichen danach ist das
eine Subtraktion. Du subtrahierst sozusagen von dem Objekt int32_t das
Gyro....
Das GyroRaw wird nicht gecastet.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Hallo, hab grad nochmal folgende Änderung vorgenommen:
1 | |
wurde geändert in:
1 | |
um auszuschließen, dass hier ein Problem mit dem Cast und dem Vorzeichen vor der Variable auftritt .... Effekt: Keiner. Grüße, Michael
Gast
#1994231
Ach Sch.... Da wird nur das Vorzeichen geändert. Doch Matschbirne. Vergiss es.
> Aber Du siehst das Problem oder? Mit dem Minuszeichen danach ist das > eine Subtraktion. Du subtrahierst sozusagen von dem Objekt int32_t das > Gyro.... Hab ich ;-) sie Vorgängerpost ... Grüße, Michael
Gast
#1994234
Dann lass ichs für heute lieber, sonst wird das noch ne Kaffeemaschine anstelle eines Copters. ;-)
:D ... gute Besserung!
Gast
#1994674
>Wirklich seltsam. Wenn der Debugger dran hängt und der µC per Run laufen >gelassen wird, dann läufts wie soll. Debugausgaben kommen und die LED >blinkt ... >Sobald ich das Programm ohne Debugger auf dem µC laufen lassen, bleibt >er wieder "hängen". Das ist wirklich bemerkenswert, wenn es (mir) zumindest keine weiteren Informationen liefert. Aber der Weg ist auch nicht wirklich, den Debugger einfach laufen zu lassen. Vielmehr setzt Du an entscheidenden Stellen im Code einen Breakpoint und prüfst sowohl ob er erreicht wird und ob die Daten an der Stelle im Code konsistent sind, den Werten entsprechen die Du erwartest. >> Denke daran, das das ausbleiben der Debug-Ausgabe kein "Anhalten" >> bedeutet sondern nur, dass der durchlaufene Code keine Ausgaben erzeugt. >> Genauso der Zustand in dem keine Änderungen an der LED oder den Ports >> mehr erfolgen. >Klar. Irgendwo ist das Ding in einer quasi "Endlosschleife" aus der er >nicht mehr rauskommt ... Möglich, aber das ist auch nicht mehr als eine Vermutung und damit ohne grösseren Wert. Du musst feststellen was er macht und nicht Vermutungen darüber anstellen. >> Was mir auffällt, ist das Du im Text von Debug-Ausgaben innerhalb des >> Interrupts sprichst. An sich ist das absolut tödlich, wenn etwa Ausgaben >> selbst auch über Ints laufen. Wenn Du das nicht komplett aus den ISRs >> entfernen willst dann kommentiere es mal aus. Eine durchaus reale >> Möglichkeit, das hier was knackt. >Verstehe. Die Debugausgaben werden nicht über Interrupts ausgegeben, >sondern relativ straight forward: Ich habe der Aussage nicht ganz getraut und habe selbst im Code nachgesehen. Und voilà: Du machst tatsächlich Ausgaben im Interrupt! Z.B. in der Datei: lis3lv02dq.c, gleich vorne in der ISR (LIS_TWI_INT) erfolgt tatsächlich eine Ausgabe "im" Interrupt. Ich muss bekennen, das ich selbst einmal von Ausgaben "im" Interrupt spreche und einmal von Ausgaben "über" Interrupts. Das ist nicht dasselbe. Ausgaben "über" (also im Sinne von "mittels") Interrupts sind hier nicht relevant. Sondern die Ausgaben "in" Interrupts. Diese können wegen der Warteschleife in USART_putc zu starken Verzögerungen führen. (Die bessere Technik ist eigentlich auch die Ausgabe in Buffer die per Interupt ausgegeben werden). Diese Verzögerungen können wiederrum Probleme verursachen wenn mehrere Int-Quellen aktiv sind. Also, nehme die Ausgaben in den Ints raus. Dnke daran auch die Debug-Ausgaben aus den Funktionen herauszunehmen die von der ISR aufgerufen werden. Aufgrund von Anwenundunginterrupts darf keine Debugausgabe erfolgen! Allenfalls mal ein wackeln an nem Portpin für ne LED. >> Du könntest auch mal im Code gucken ob irgendwo absichtlich oder >> unabsichtlich Rekursionen auftreten und ob die Abbruchbedingungen >> wirklich mit true bewertet werden. >Mach ich morgen! Was hat sich dabei herausgestellt? >> Eine gute Möglichkeit ist auch, einen Lint über Deinen Code laufen zu >> lassen. Es gibt da einige für Linux. >Lint kenne ich noch nicht. Ich mach mich mal schlau ... Und? Wie stehts damit? >Also der Speicher, wenn ich das Recht interpretiere, kann es nicht sein, >dennoch gehts in folgender Zeile nicht "weiter" (µC bleibt stehen, keine >ISRs mehr, keine Pinwackler am LA und main wird auch nicht mehr >durchlaufen): Genau genommen ist das nicht so zu interpretieren. Schau Dir die Testroutine mal an. Sie beschreibt den Speicher mit einem festen Muster und prüft später bis wohin das Muster noch vorhanden ist. Es sehr wohl möglich das das Muster auch in den "normalen" Daten vorhanden ist, die beim Programmlauf auftreten. Insofern ist nur die Aussage wirklich relevant, das der Speicher nicht ausreicht. Die Aussage, das der Speicher reicht ist nur bedingt richtig. Es ist nützlich, die Routine mal mit noch einem oder zwei anderen Mustern mitlaufen zu lassen und die Ergebnisse zu vergleichen. Ausserdem sind auf diese Weise die Interrupts nicht abgedeckt. Du müsstet noch sicherstellen, das vor Aufruf von get_mem_unused alle Interrupts wenigstens einmal in allen Zweigen durchlaufen worden sind. Besser ist es, das im Simulator einmal durchzuspielen. Aber was mir auffällt, ist das Du Dich von dem Gedanken, dass eine CPU stehenbleibt noch nicht verabschiedet hast. Streich das aus Deinem Denken. Sowas gibt es nicht. Er macht immer irgendwas. Und genau das ist wichtig! Was genau macht er anstelle des Codes der dasteht? Setze einen Breakpoint auf die Codezeile. Bei erreichen stellst Du auf Anzeige des Assembler-Codes um und gehst im Einzelschritt weiter. Guck Dir den Stack an, ob die Return-Addressen gültig sind, insbesondere vor rets. Berichte hier am besten im Detail darüber was Du festgestellt hast, auch wenn Dir nichts besonderes auffällt. Ich möchte Dir an dieser Stelle empfehlen zunächst den Code durch einen Lint laufen zu lassen. Das Problem ist, das die anderen Methoden relativ viel Aufwand erfordern und Kenntnisse von Assembler und des uC. Der Lint hingegen findet relativ mühelos Probleme im Code auf. Erst wenn das nichts bringt würde ich mit dem Debuggen weitermachen. Die Entfernung der Debug-Ausgaben aus den Interrupts ist wichtig. Mach das auf jeden Fall. Dann erst wieder Debuggen bzw. Simulieren. Hoffe das bringt Dich weiter. Viel Erfolg.
Hallo > Aber der Weg ist auch nicht wirklich, den Debugger einfach laufen zu > lassen. Vielmehr setzt Du an entscheidenden Stellen im Code einen > Breakpoint und prüfst sowohl ob er erreicht wird und ob die Daten an der > Stelle im Code konsistent sind, den Werten entsprechen die Du erwartest. Das hab ich gemacht. Debuggen geht zur Zeit leider nur unter Windows, und da läuft der Code ja .... > >>> Denke daran, das das ausbleiben der Debug-Ausgabe kein "Anhalten" >>> bedeutet sondern nur, dass der durchlaufene Code keine Ausgaben erzeugt. >>> Genauso der Zustand in dem keine Änderungen an der LED oder den Ports >>> mehr erfolgen. > >>Klar. Irgendwo ist das Ding in einer quasi "Endlosschleife" aus der er >>nicht mehr rauskommt ... > Möglich, aber das ist auch nicht mehr als eine Vermutung und damit ohne > grösseren Wert. Du musst feststellen was er macht und nicht Vermutungen > darüber anstellen. Stimmt. Bin dabei! > >>> Was mir auffällt, ist das Du im Text von Debug-Ausgaben innerhalb des >>> Interrupts sprichst. An sich ist das absolut tödlich, wenn etwa Ausgaben >>> selbst auch über Ints laufen. Wenn Du das nicht komplett aus den ISRs >>> entfernen willst dann kommentiere es mal aus. Eine durchaus reale >>> Möglichkeit, das hier was knackt. > >>Verstehe. Die Debugausgaben werden nicht über Interrupts ausgegeben, >>sondern relativ straight forward: > > Ich habe der Aussage nicht ganz getraut und habe selbst im Code > nachgesehen. Und voilà: Du machst tatsächlich Ausgaben im Interrupt! > Z.B. in der Datei: lis3lv02dq.c, gleich vorne in der ISR (LIS_TWI_INT) > erfolgt tatsächlich eine Ausgabe "im" Interrupt. Ich muss bekennen, das > ich selbst einmal von Ausgaben "im" Interrupt spreche und einmal von > Ausgaben "über" Interrupts. Das ist nicht dasselbe. Ausgaben "über" > (also im Sinne von "mittels") Interrupts sind hier nicht relevant. > Sondern die Ausgaben "in" Interrupts. Diese können wegen der > Warteschleife in USART_putc zu starken Verzögerungen führen. (Die > bessere Technik ist eigentlich auch die Ausgabe in Buffer die per > Interupt ausgegeben werden). Diese Verzögerungen können wiederrum > Probleme verursachen wenn mehrere Int-Quellen aktiv sind. > Also, nehme die Ausgaben in den Ints raus. Dnke daran auch die > Debug-Ausgaben aus den Funktionen herauszunehmen die von der ISR > aufgerufen werden. Aufgrund von Anwenundunginterrupts darf keine > Debugausgabe erfolgen! Allenfalls mal ein wackeln an nem Portpin für ne > LED. Der Unterschied ist mir klar. Momentan erfolgen keine Ausgaben im Interrupt. Die können über die tricopter_config.h ausgeschaltet werden: #define TWI_DEBUGGING 0 #define LIS_DEBUGGING 0 #define LIS_ERROR_DEBUGGING 0 #define ITG_DEBUGGING 0 #define ITG_ERROR_DEBUGGING 0 und in der lis3lv02dq.h:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
>>> Du könntest auch mal im Code gucken ob irgendwo absichtlich oder >>> unabsichtlich Rekursionen auftreten und ob die Abbruchbedingungen >>> wirklich mit true bewertet werden. > >>Mach ich morgen! > Was hat sich dabei herausgestellt? Alle so wie es sein sollte ... > >>> Eine gute Möglichkeit ist auch, einen Lint über Deinen Code laufen zu >>> lassen. Es gibt da einige für Linux. > >>Lint kenne ich noch nicht. Ich mach mich mal schlau ... > Und? Wie stehts damit? splint ist installiert und läuft ... bekomme leider relativ häufig: Parse Error. Bin dabei das zu beheben. >>Also der Speicher, wenn ich das Recht interpretiere, kann es nicht sein, >>dennoch gehts in folgender Zeile nicht "weiter" (µC bleibt stehen, keine >>ISRs mehr, keine Pinwackler am LA und main wird auch nicht mehr >>durchlaufen): > Genau genommen ist das nicht so zu interpretieren. Schau Dir die > Testroutine mal an. Sie beschreibt den Speicher mit einem festen Muster > und prüft später bis wohin das Muster noch vorhanden ist. Es sehr wohl > möglich das das Muster auch in den "normalen" Daten vorhanden ist, die > beim Programmlauf auftreten. Insofern ist nur die Aussage wirklich > relevant, das der Speicher nicht ausreicht. Die Aussage, das der > Speicher reicht ist nur bedingt richtig. Es ist nützlich, die Routine > mal mit noch einem oder zwei anderen Mustern mitlaufen zu lassen und die > Ergebnisse zu vergleichen. Ausserdem sind auf diese Weise die Interrupts > nicht abgedeckt. Du müsstet noch sicherstellen, das vor Aufruf von > get_mem_unused alle Interrupts wenigstens einmal in allen Zweigen > durchlaufen worden sind. Besser ist es, das im Simulator einmal > durchzuspielen. OK. Ich werde das unter Windows mal durchführen. > Aber was mir auffällt, ist das Du Dich von dem Gedanken, dass eine CPU > stehenbleibt noch nicht verabschiedet hast. Streich das aus Deinem > Denken. Sowas gibt es nicht. Er macht immer irgendwas. Und genau das ist > wichtig! Was genau macht er anstelle des Codes der dasteht? Ist gestrichen. Das "anhalten" ist mehr eine Umschreibung meinerseits für das Beobachtete, als eine konkrete Beschreibung! Das Problem ist, dass er nichts mehr macht, was im Code darsteht (also weder Pins wackeln noch LED blinken, noch Debug produzieren) > Setze einen Breakpoint auf die Codezeile. Bei erreichen stellst Du auf > Anzeige des Assembler-Codes um und gehst im Einzelschritt weiter. Guck > Dir den Stack an, ob die Return-Addressen gültig sind, insbesondere vor > rets. OK. > Berichte hier am besten im Detail darüber was Du festgestellt hast, > auch wenn Dir nichts besonderes auffällt. Mach ich. > Ich möchte Dir an dieser Stelle empfehlen zunächst den Code durch einen > Lint laufen zu lassen. Das Problem ist, das die anderen Methoden relativ > viel Aufwand erfordern und Kenntnisse von Assembler und des uC. Der Lint > hingegen findet relativ mühelos Probleme im Code auf. Erst wenn das > nichts bringt würde ich mit dem Debuggen weitermachen. s.o. > Die Entfernung der Debug-Ausgaben aus den Interrupts ist wichtig. Mach > das auf jeden Fall. Ist schon passiert! > Dann erst wieder Debuggen bzw. Simulieren. > > Hoffe das bringt Dich weiter. > > Viel Erfolg. Vielen Dank nochmals an alle ... ich kämpfe weiter und gebe Feedback! Grüße, Michael
Soooo, viel ist passiert und gleich vorweg ... ich scheine einen Bug unabsichtlich behoben zu haben, denn jetzt läufts. Warum -- weiss ich noch nicht genau ;-) Der von mir eingesetzte Sensor ITG-3200 gibt an einem Pin für 50µs ein high Signal aus wenn neue Daten abgefragt werden können. Das hab ich mir einer PinChange ISR (rising edge) mitgekriegt und die Datenabfrage gestartet. Soweit so gut, aber mein anfängliches Problem war, dass mit dem Sensor relativ häuft der Busstate "ARB Lost" eingetreten ist, trotz sauberer I2C Beschaltung (Pullups, etc.). Stromversorgung war ok, die Pegel auch und trotzdem liefs einfach nicht so wirklich rund. Alle 1 - 2 Sekunden hat sich der Bus verabschiedet. Mein Workaround war dann: 1. TWI abschalten und SDA als Input und SCL als Output konfigurieren. 2. SCL so lange toggeln bis SDA wieder hoch kommt 3. Wenn SDA wieder high ist, dann TWI wieder einschalten und konfigurieren und weiter gehts. Das hat soweit auch recht gut funktioniert. Jetzt habe ich zu Testzwecken mal ne Debugausgabe vor dem Starten der Datenabfrage reingemacht und plötzlich waren die ARB-Lost Stati weg!? Mittlerweile wird die Datenabfrage gestartet, wenn das Data-Ready-Signal fällt, also 50µs später und die ARB-Lost sind so gut wie verschwunden (1 - 2 in 10 Minuten). Zum Recovern wurde der TWI Bus Status im Interrupt abgefragt und wenn der State ARB Lost eingetreten ist, dann wurde die "Recoverfunktion" aus dem Interrupt heraus aufgerufen. Im Zuge der Einarbeitung Eurer Vorschläge (Ints schlank und schnell halten, ohne Debug Ausgaben) hab ich dann auch den Aufruf Funktion aus dem Interrupt genommen und statt dessen einfach ein Flag gesetzt, das eine Funktion prüft, die aus der main aufgerufen wird. Und ... jetzt rennts. Genau kann ich noch nicht sagen warum genau, aber ich habe die Vermutung, dass der µC dauerhaft im TWI Interrupt hängen geblieben ist und nicht mehr raus kam. Das hätte ich eigentlich mit dem LA sehen müssen - hab ich aber nicht ... ich teste weiter und immerhin hab ich schon mal nen Anhaltspunkt, wo die Ursache liegen könnte. Ich halte Euch auf dem Laufenden! Grüße, Michael
Hallo zusammen, Leider ist die Zeit im Hinblick auf Neujahr leider ein wenig knapp und deshalb konnte ich weniger schaffen, als erwartet, aber es gibt wieder ein paar Neuigkeiten. Ich hab das vorgeschlagene Vorgehen von Huch mal durchgeführt und ausgiebigst gedebugged. Den Beschleunigungssensor hab ich mal "rausgenommen" und die Gyrowerte abgefragt und das Ganze im Debugger angeschaut. Breakpoints in den Interrupts vor und nach while Schleifen und mir auch den ASM Code angeschaut und die Rücksprungadressen kontrolliert. Dabei konnte ich keinen Fehler feststellen. Alles läuft wie gewollt. Kompiliert, geflasht und gedebugged unter Windows. Soweit super. Ich wollte die Änderungen vom Gyro-"Treiber" auch für den Beschleunigungssensor (der soll mit 100Hz abgefragt werden) umsetzen, der nicht wie das Gyro per PinChange-Interrupt abgefragt wird, sondern per Timer-Interrupt. 0. Gyrosensor soll mit 400Hz ausgelesen werden. 1. Sensor gibt für 50µs ein High - Signal, wenn neue Daten verfügbar sind. 2. PinChange - Interrupt startet das Auslesen des Sensors per TWI 3. Gyro-Treiber arbeitet Interruptbasiert 4. LA Konfiguration: -- 0: Pin toggle in der main -- 1: Pin toggle in der Pin Change ISR (Gyro) -- 2: am Anfang der TWI ISR wird Pin2 gesetzt und beim verlassen wieder gecleared -- 4: Pin toggle in der Timer OVF ISR (Accelerometer) Bild LA_WIN / LA_WIN2 ist ein Screener vom LA. * Die weißen Blöcke auf Kanal 0 zeigen, wenn die main durchlaufen wird. * Kanal 1 zeigt den Pin Toggle aus der PinChange ISR. Die "Toggle"-Frequenz entspricht den gewollten 400Hz. * Kanal 2 zeigt die TWI ISR. Sobald neue Daten am Gyro verfügbar sind startet die Datenübertragung und die TWI ISR wird durchlaufen. Ein ISR Durchlauf dauert in der Regel 1-3µs. Und die komplette Datenabfrage vom Sensor ist nach ca. 0.2ms abgeschlossen. * Kanal 4 zeigt die TimerOVF-ISR in der momentan nur ein Pin getoggelt wird. Alles super. Dann gings unter Linux weiter. Also wieder LA dran und schon gab es die ersten seltsamen Ergebnisse. Code ist der gleiche wie unter Windows. Die Bilder LA_LINUX / LA_LINUX2 zeigen den gleichen Code, nur unter Linux kompiliert und geflasht. Das Gyro arbeitet wie erwartet, jedoch wird die Timer OVF ISR für den Beschleunigungssensor nicht so "sauber" ausgeführt (unregelmässiger PinToggle, vgl. Kanal4) wir mit dem unter Windows kompilierten Code. Der Beschleunigungssensor wird momentan noch nicht ausgelesen und ist somit inaktiv! Ich wollte nur kontrollieren, ob die Timer-ISR sauber ausgeführt wird und zu der Windows Version sind hier heftige Unterschiede!! Irgendwas ist mit dem Linux faul .... Ich wünsche Euch dennoch ein gutes neues Jahr und einen guten Rutsch heute abend!! Ich melde mich dann bis ins neue Jahr ab, da langsam die Vorbereitungen für heute abend anlaufen ... Grüße, Michael
Gast
#4534346
Michael K. schrieb: > Soweit so gut, aber mein anfängliches Problem war, dass mit > dem Sensor relativ häuft der Busstate "ARB Lost" eingetreten ist, Das hatte ich auch. Hat mich ziemlich lang beschäftigt. Hat sich herausgestellt, dass ich einen Wackelkontakt am Weg von Xmega zu Steckbrett hatte. Gemessen habe ich mit dem Oszilloskop immer an den Pullups... Die so gesehene Spannung hat der Xmega an seinem SDA Pin allerdings nie zu spüren bekommen. Der war damit mehr oder weniger Floating... --> ARB Lost... Sry, dass ich damit dieses alte Thema noch mal aufgreife... Habs aber mit Googel gefunden, da "gleiches Problem" und möchte zukünftige Sucher damit einen Lösungsweg aufzeigen. :)
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.



