Cortex-M3 Programm-Counter auslesen?

OP (Firma: EleLa - www.elela.de) #2085270
Lesenswert?
• ▲
▼
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
OP (Firma: EleLa - www.elela.de) #2085279
Lesenswert?
• ▲
▼
Ja, das wäre eine Idee. Dann mache ich das so in die allgemeine H-Datei 
rein, wo anders ist der Speicher deklariert:
1
extern u32 iPC[16];
2
extern u8  iPCPos;
3
#define SAVE_PC(X) {iPCPos=(iPCPos+1)%16;iPC[iPCPos]=(u32)X;}
4
//#define SAVE_PC(X)

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?
OP (Firma: EleLa - www.elela.de) #2085304
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
In der Annahme, dass du gcc verwendest:
1
static inline __attribute__((always_inline)) uint32_t read_pc(void) {
2
  uint32_t tmp;
3
  asm volatile("mov %0, r15" : "=r" (tmp) );
4
  return tmp;
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.
OP (Firma: EleLa - www.elela.de) #2085423
Lesenswert?
• ▲
▼
Vielen Dank, Ingo, das scheint gut zu klappen.
Anbei der Code vom globalen Header:
1
extern vu32 iPC[16];
2
extern vu8  iPCPos;
3
#define SAVE_U32(X) {iPCPos=(iPCPos+1)%16;iPC[iPCPos]=(u32)X;}
4
#define SAVE_PC() {u32 t;iPCPos=(iPCPos+1)%16;asm volatile("mov %0, r15" : "=r"(t));iPC[iPCPos]=t;}

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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.