Hallo, Ich habe einen STM32. Und ich möchte immer wieder den Programmcounter (Register R15) auslesen und in einer Liste merken. Denn das Ding stürzt mit einer "BusFaultException" irgendwo irgendwann ab und damit sehe ich dann welche Funktionen samt Historie zu letzt liefen. Wie kann ich das Register R15 (PC) in C auslesen? Im LR Register steht leider nu FFFFFFF9 drin. Der Stackponinter ist gut, also nicht über gelaufen. Gruß Markus
Markus Müller schrieb: > Wie kann ich das Register R15 (PC) in C auslesen? Nur mit Inline-Assembler. In C kannst Du allerdings die Startadresse von Funktionen bestimmen (&funktionsname), vielleicht genügt das für Dich ja schon.
Ja, das wäre eine Idee. Dann mache ich das so in die allgemeine H-Datei rein, wo anders ist der Speicher deklariert:
1 | |
2 | |
3 | |
4 | |
Der Aufruf ist dann: SAVE_PC(&funktionsname); Müsste gehen oder? Edit: Wenn ich doch anstatt &funktionsname den PC rein bekommen könnte, dann gibt es weniger Copy&Paste Fehler, das Projekt ist ziemlich groß. Kannst Du mir schreiben wie der Assembler-Befehl aussehen müsste?
Wenn der Stack noch gut ist kannst du im BusFault die Interrupts abschalten und das Programm dann per singlestep weiter laufen lassen um zu gucken von wo er kam. Nach dem Busfault springt er ja zurück.
Wenn ich das Register auslesen würde? "DWT Program Counter Sample Register Use the DWT Program Counter Sample Register (PCSR) to enable coarse-grained software profiling using a debug agent, without changing the currently executing code." Mit *((u32 *)0xE000101C) ? Ist dieser Inhalt des Registers der aktuelle Programmcounter?
Gast
#2085329
In der Annahme, dass du gcc verwendest:
1 | |
2 | |
3 | |
4 | |
5 | |
Der damit ausgelesene Wert von r15 ist in einem kurzen Test hier immer um 4 grösser als die Adresse an der der Befehl laut objdump tatsächlich steht, ich schiebe das mal ohne weitere Analyse aufs Pipelining.
Vielen Dank, Ingo, das scheint gut zu klappen. Anbei der Code vom globalen Header:
1 | |
2 | |
3 | |
4 | |
Dann noch in irgend einer C-Datei die die zwei Variablen rein. Der Aufruf: SAVE_U32(&funktionsname); oder SAVE_PC(); Damit das in der Echt-Version nicht merhr drin ist: #define SAVE_U32(X) #define SAVE_PC() in der Header-Datei.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.