Hallo zusammen, kurze Problemdarstellung: In meinem System kommt es zu einem Verhalten was auftritt (Messungen belegen dies), jedoch kann "ich" es weder nachvollziehen noch reproduzieren. Ich habe zwar eine Idee was es sein könnte, kann es jedoch nicht prüfen, da ich es nicht in diesen Zustand bekomme. Nun die Idee: Falls ich in der FW diesen Zustand erkenne, würde ich direkt alle Interrupts deaktivieren und die 128KB RAM auf die SD Karte spiegeln. Danach die Werte mithilfe des *.map File analysieren. (Um zu schauen welche Variablen evtl. aus der Reihe tanzen) Gibt es ein Programm welches eine *.map File über ein Image vom RAM legt und direkt anzeigt welche Variablen welche Werte hatten? Gruß Adam
Adam P. schrieb: > In meinem System kommt es zu einem Verhalten was auftritt (Messungen > belegen dies), jedoch kann "ich" es weder nachvollziehen noch > reproduzieren. > Ich habe zwar eine Idee was es sein könnte, kann es jedoch nicht prüfen, > da ich es nicht in diesen Zustand bekomme. Nun, wenn du eine Idee hast, was es sein könnte (das ist gut, praktisch der halbe Weg zur Lösung, wenn sie zutrifft!!!), dann sollte es kein Problem sein, die Situation gewollt herbei zu führen. Leider ist es viel typischer, dass man eigentlich erstmal gar keine Idee hat, denn man hat natürlich alles nach bestem Wissen und Gewissen umgesetzt. > Nun die Idee: > Falls ich in der FW diesen Zustand erkenne Das setzt doch aber schon eine zutreffende Idee voraus, oder nicht? Wie soll das sonst gehen? > würde ich direkt alle > Interrupts deaktivieren und die 128KB RAM auf die SD Karte spiegeln. Nunja, heutzutage macht man sowas mit einem Debugger. Wenn man erstmal weiß, wo es sinnvoll ist, einen Breakpoint zu setzen, um die Fehler-Situation zu fangen, ist schonmal ein Drittel der Miete drin. Mit ein bissel Glück ist es dann möglich, mit der im Debugger eingefrorenen Situation (die ja im Prinzip deiner Mapfile-Idee entspricht, aber eher doch besser ist als diese), die Sache zu klären. Leider ist das aber nicht immer möglich. Es gibt da leider richtig fiese Fehler, die sich Millionen oder Milliarden Takte vor dem eingefrorenen Zustand ausgewirkt haben, ursächlich für diesen Zustand sind, aber aus dem eingefrorenen Zustand trotzdem praktisch nicht mit vernünftigem Aufwand ermitteln lassen. Solche Fehler zu finden, das ist dann die Spielwiese für Simulatoren und Stimuli. Natürlich zusammen mit in den Code einzubauenden Mechanismen für's Logging (woher sollen sonst die Stimuli für den Simulator kommen).
Kommt es denn zu einem Hardfault oder ähnliches? Ansonsten guck dir mal Segger Systemview an, damit kannste live aufs System gucken. Geht mit deren Tracer zwar noch schneller, aber der kost dann ordentlich.
c-hater schrieb: > dann sollte es kein > Problem sein, die Situation gewollt herbei zu führen. Ich kenne die Auswirkung, aber bekomme diesen Zustand nicht hin, sprich den Grund für dieses Verhalten. c-hater schrieb: >> Nun die Idee: >> Falls ich in der FW diesen Zustand erkenne > > Das setzt doch aber schon eine zutreffende Idee voraus, oder nicht? Wie > soll das sonst gehen? In dem ich prüfe ob dieser Zustand gerade da ist. c-hater schrieb: > Nunja, heutzutage macht man sowas mit einem Debugger. Klar, wenns neben dir liegt, sehr gerne...jedoch sind diese Geräte nicht bei mir und externe Debug Möglichkeiten gibt es dort vor Ort nicht. Mw E. schrieb: > Kommt es denn zu einem Hardfault oder ähnliches? Nein, ein Hardfault wäre ja noch einfach zu finden (Call Stack). Es ist einfach ein "Funktionsaussetzer", ein Modul tut nicht mehr das was es soll. Mw E. schrieb: > Ansonsten guck dir mal Segger Systemview an, damit kannste live aufs > System gucken. > Geht mit deren Tracer zwar noch schneller, aber der kost dann > ordentlich. Das geht wie gerade gesagt nicht, da ich es nicht in diesen Zustand bekomme. Keine Ahnung was oder wie die es da draußen machen, unerklärlich. Deshalb wollte ich diesen Weg einschlagen. Ein Log (Image) erstellen und dann auslesen lassen, mir zuschicken, schauen/vergleichen. Die Sache ist, ich kann mich doch jetzt nicht da hinsetzen und ein RAM Image händisch mit dem map file vergleichen und dann schauen welche Werte ok sind oder nicht. Wäre schon schick, wenn es ein Programm gäbe das ein Byte Image und dem map File übereinander legt und zumindest die Werte der Variablen anzeigt. Aber ich glaub das werde ich dann wohl selbst schreiben müssen?
:
Bearbeitet durch User
Hi Nie was damit gemacht aber evtl. hilft dir das weiter https://github.com/adamgreen/CrashDebug Matthias
> Klar, wenns neben dir liegt, sehr gerne...jedoch sind diese Geräte nicht > bei mir und externe Debug Möglichkeiten gibt es dort vor Ort nicht. Es gibt auch J-Links mit Netzwerkanschluss. .-) Ansonsten kannst du dir natuerlich beim uebersetzen deines Programms eine lange Liste mit allen Variablen und sonstigen Speicherpositionen erzeugen lassen. Ich nutze das z.B um in einem selbstgeschriebenen Programm mit Jlink auf einen Controller zuzugreifen um mir in Echtzeit Variablen anzuschauen. Das macht in Ausnahmen Sinn. Allerdings nicht wenn du letztlich die gesamte Funktionalitaet eines Debuggers ersetzen willst. Einfach zuviel Arbeit. Du koenntest aber einen anderen Weg gehen. Schreibe dein Speicherabbild und natuerlich auch ein Abbild der Register des Controllers raus und lese es zuhause wieder ein. Dann kannst du dich danach ja mit deinem Debugger mit dem Programm verbinden und schauen was es so macht. Das sollte grundsaetzlich kein Problem sein, jedenfalls wenn du mit der dann fehlenden Initialisierung deiner Hardware leben kannst. Aber immerhin koenntest du dann mit dem Debugger den Softwarestand analysieren. Trotz allem vermutlich noch eine Menge Arbeit bis es im Detail laeuft. Olaf
Da es kein offensichtliches Tool für sowas gibt machts wohl auch kaum jemand. Wennes selber schreibst, dann nimm das elf File mit Debugsymbolen statt dem map. Das müssteste ja sonst noch selber parsen. Zudem steht im mapfile nicht jede Variable einzeln, sondern der Größenverbrauch der obj wird gemappt. (Beim GCC, andere Compiler machens vllt anders) (Beispiel: .bss 0x20000af0 0x1c periph/usart.o) Für elf gibts Python Libs. -> https://github.com/eliben/pyelftools Da lässt sich Adresse, Name und Initwert von Speicherbereichen auslesen. Olaf schrieb: > Es gibt auch J-Links mit Netzwerkanschluss. .-) Segger bietet auch nen Tunnelserver an um Remote überall auf der Welt zu debuggen! -> https://www.segger.com/products/debug-probes/j-link/tools/j-link-remote-server/ Das geht aber auch mitm USB J-Link und nem Laptop. Mal noch ne Frage am Rande (für die Zukunft). Die MPU is aktiv? Damit lassen sich die Adressbereiche vor dem Flash sperren und schon fällt jeder Nullpointerzugriff direk auf, der sonst zu vagabundierenden Programmen inkl "komischer" Zustände führen kann. (Nich vergessen das VBAR aufn FLash zeigen zu lassen vorher)
Eigentlich ist das alles genau Aufgabe von gdb. Der kann auch eine core-Datei einlesen und wenn man ihm die Symboltabelle spendiert, kann man direkt per Name jede Variable anschauen. Also geht es doch "nur" darum, alles was du hast, in eine Form zu bringen, die der gdb lesen kann.
Klaus W. schrieb: > Eigentlich ist das alles genau Aufgabe von gdb. > Der kann auch eine core-Datei einlesen und wenn man ihm die > Symboltabelle spendiert, kann man direkt per Name jede Variable > anschauen. > Also geht es doch "nur" darum, alles was du hast, in eine Form zu > bringen, die der gdb lesen kann. Und genau das versucht das von mir genannte Tool zu automatisieren. Matthias
Adam P. schrieb: > Falls ich in der FW diesen Zustand erkenne, würde ich direkt alle > Interrupts deaktivieren und die 128KB RAM auf die SD Karte spiegeln. Und dann hast du eine große Menge an Daten, die niemand auswerten kann. Erzeuge lieber Log-Meldungen die du auf ein Speichermedium schreibst oder seriell ausgibst. Bei Dateien kann es Sinn machen, diese in einem FIFO Puffer zu sammeln und den Puffer nur dann in die Datei zu schreiben, wenn ein Fehler erkannt wurde. Wobei dann jeder Thread einen eigenen Puffer haben sollte.
Erstmal danke für die genannten Tools, werde ich mir mal näher anschauen. Die Ideen mit "Ferndebugen" sind nicht möglich, da die Geräte zu sind und nicht geöffnet werden dürfen/können. Stefan ⛄ F. schrieb: > Erzeuge lieber Log-Meldungen die du auf ein Speichermedium schreibst Ja, das war meine erste Idee, da ich eh Log-Meldungen habe die seriell ausgegeben werden. (Diese Schnittstelle ist jedoch auch nicht zugänglich) Ich werde es dann wohl erst mit den Log-Meldungen versuchen und diese auf die SD Karte umleiten.
> Zudem steht im mapfile nicht jede Variable einzeln, sondern der > Größenverbrauch der obj wird gemappt. (Beim GCC, andere Compiler machens > vllt anders) So? Eine Kommandozeile schnell getippert: nm -n -S BoardTest |grep '^2' |grep ' 0000' |grep -v '__' >variable.txt Olaf
Olaf schrieb: > Eine Kommandozeile schnell getippert: > > nm -n -S BoardTest |grep '^2' |grep ' 0000' |grep -v '__' >variable.txt Ist "BoardTest" dein *.map File?
:
Bearbeitet durch User
Adam P. schrieb: > Ist "BoardTest" dein *.map File? nm gibt man eine Objektdatei mit als Argument. Nachtrag: gibt man keine an, wird a.out angenommen.
:
Bearbeitet durch User
Also nimmt Olafs Kommandozeile kein map file, sondern die elf. Die Endung is ja egal. Da steht dann auch alles sinnvolle drinne, so wie ich oben schon angemerkt habe. Output:
1 | 20000000 00000004 D _impure_ptr |
2 | 20000008 00000428 d impure_data |
3 | 200009ac 00000100 b usart3_tx_buf |
4 | 20000aac 00000024 b usart3_irq |
5 | 20000ad0 00000010 b usart3_rx_buf |
6 | 20000ae0 00000001 b receive_index |
7 | 20000ae4 00000002 b recbuf |
8 | 20000ae8 00000004 b ubase |
9 | 20000aec 00000004 b byteout_p |
10 | 20000af0 0000001c b irq_idx |
11 | 20000b40 00000004 B _PathLocale |
12 | 20000b44 00000004 b heap_end.4144 |
13 | 20000b6c 00000004 B errno |
Scheint jetz aber nich alles zu sein, die Lücke vor 200009ac kommt mir etwas zu groß vor.
Mw E. schrieb: > Also nimmt Olafs Kommandozeile kein map file, sondern die elf. > Die Endung is ja egal. > Da steht dann auch alles sinnvolle drinne, so wie ich oben schon > angemerkt habe. Also das sieht schon einmal gut aus.
> Scheint jetz aber nich alles zu sein, die Lücke vor 200009ac kommt mir > etwas zu groß vor. Man kann mit den Parametern von nm einiges spielen. Ich hab da ganz bewusst verschiedenes weggelassen weil ich nur diese Variablen brauche um sie ueber den jlink aus meinem Controller auszulesen. Olaf
Mw E. schrieb: > Scheint jetz aber nich alles zu sein, die Lücke vor 200009ac kommt mir > etwas zu groß vor. Nö, die impure_data struktur is so absurd groß in newlib. Such das mal im Map File.
Ist an sich eine gute Idee und wird so auch häufig bei komplexeren Systemen gemacht (wenn man nicht mit dem Debugger rein kommt). Der Linux Kernel erzeugt dir einen Core Dump wenn er sich verabschiedet, bei Windows heißt die Technik dazu Minidump und macht das gleiche. Was du nicht vergessen solltest: Speicher nach Möglichkeit auch ein paar wichtige Register (Stack- und Base Pointer, MSRs bzw. auf ARM ?Control Register? usw.) und MMIO Address Spaces ab (=Register der Peripherie). Um das fehlende Tooling anzugehen könntest du probehalber das Image auf ein baugleiches Board spielen und dann mit dem Debugger drauf gehen. Brauchst ja gar nicht laufen lassen. Ansonsten musst du halt die Bytes durchgehen, wobei man mit ein wenig Skripting da schon viel erreichen kann.
Mw E. schrieb: > die Lücke vor 200009ac kommt mir > etwas zu groß vor. Der letzte Wert vorher könnte ja auch ein Feld sein. Außerdem wechselt an der Lücke die section: Vorher ist D und d, das sind Werte aus der initialisierten data section. Die mit B und b sind BSS (unitialisiert).
Johannes schrieb: > Um das fehlende Tooling anzugehen könntest du probehalber das Image auf > ein baugleiches Board spielen und dann mit dem Debugger drauf gehen. > Brauchst ja gar nicht laufen lassen. Das ist mal eine gute Idee. Weißt du zufällig wie ich das geschickt machen könnte? Ich arbeite mit Atmel Studio und dem Atmel SAM-ICE von SEGGER. Bekomme ich im Debug Mode (Breakpoint) auch irgendwie das RAM geschickt ausgelesen, außer mit dem Memory View?
Mit den Debuggern hab ich leider keine Erfahrung. Mit dem GDB kannst du blockweise Speicher lesen/schreiben von/in Datei, egal ob die CPU läuft oder angehalten ist. https://sourceware.org/gdb/onlinedocs/gdb/Dump_002fRestore-Files.html
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.