2016-04-02 15 views
5

Ich verwende die STM32F7-Discovery-Karte und habe versucht, den DWT-Zykluszähler zu aktivieren. Von dem, was ich online gesehen haben sollte dies ausreichen, es zu ermöglichen:STM32 - So aktivieren Sie den DWT-Zykluszähler

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 
DWT->CYCCNT = 0; 
DWT->CTRL |= 1; 

Wenn jedoch jemals betreibe ich diesen Code die Werte nicht geändert oder die Operationen sind übersprungenen (Ich bin nicht sicher, was passiert ist).

Ich habe versucht, Zeiger auf die Adressen im Speicher zu machen und sie direkt ohne Erfolg auch zu ändern. Ex:

volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000; 
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004; 
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC; 
*DEMCR = *DEMCR | 0x01000000; 
*DWT_CYCCNT = 0; 
*DWT_CONTROL = *DWT_CONTROL | 1; 

Derzeit ist die einzige Art, wie ich bekommen habe das ist, wenn sie mit dem Debugger in Visual Studio (mit VisualGDB) Schreiten durch, wenn ich den Wert von DWT-> CTRL auf den ON-Wert ändert sich der Zyklus Zähler beginnt. Abgesehen davon, kann ich nicht den Wert bekommen, den Code zu ändern.

Edit: Was könnte das Verhalten verursachen, wo diese Codezeilen ihre Aufgaben nicht ausführen, aber auch nicht abstürzen und fortfahren.

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 
DWT->CYCCNT = 0; 
DWT->CTRL |= 1; 

Nachdem diese Zeilen von Codes ausgeführt wird, alle Werte an diesen Speicherstellen gleich bleiben und nicht mit den Operationen verändert, die durchgeführt werden sollen, um.

Z.B. :

//DWT_CTRL_CYCCNTENA_Msk = 1 
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk 

Sollten im Wert von DWT-> führen CTRL 0x40000001 zu sein, aber es bleibt bei dem Standardwert 0x40000000

Die folgenden Bilder sind ein Beispiel dafür, was während der Laufzeit auftritt.

Before After

+0

"Die Werte werden nicht geändert oder die Operationen werden übersprungen "- Warum erfährst du es nicht bevor du fragst? Und benutze die CMSIS-Header. Definieren Sie keine eigenen Register. Übrigens. Die Definitionen erzeugen viel mehr Code, da Sie die Zeiger als Variablen definieren. (Denken Sie nicht an ybout 'const' Qualifier, sie werden immer noch Variablen sein.) – Olaf

+0

Nun, ich bin durch sie gegangen und die Operationen sehen aus wie sie auftreten, aber die Werte ändern sich nicht für jeden Speicherort, den ich bearbeiten möchte . Ich habe versucht, es ohne viel Nutzen herauszufinden, also dachte ich mir, der logische nächste Schritt wäre, nachzufragen. – KenQueso

+0

Sollte funktionieren nach [dies] (http://stackoverflow.com/questions/13379220/generating-nanosecond-delay-in-c-on-stm32). Beachten Sie, dass der Debugger den DWT für seine eigenen Zwecke verwendet, wenn Sie den Debugger verwenden. Sie können den Debugger daher nicht wirklich mit diesem Code verwenden. – user3386109

Antwort

3

Nicht sicher, ob das auf dem STM32F7 identisch ist, aber das ist, wie es richtig zu tun, um die CMSIS Header auf einem STM32F4 verwenden (sollte auf jedem Cortex-M3 tatsächlich funktionieren/4 (/ 7 ?), die dieses Modul bereitstellt):

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 
DWT->CYCCNT = 0; 
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 

Sie müssen auch das Trace-Modul aktivieren. Vorsicht, der Code ist nicht unterbrechungssicher! Im Allgemeinen sollten Sie den Counter einfach frei laufen lassen und Unterschiede von Snapshots für das Timing berücksichtigen.

Stellen Sie sicher, dass Ihre Toolchain nicht Ihren Code beeinträchtigt. OpenOCD/gdb ist nicht sicher, was Tools angeht, die eine manuelle Profilerstellung ermöglichen.

Wie ich bereits betont, in den Kommentaren: Nicht einige homebrew Definitionen für die Register verwenden. ST (und ARM) bieten CMSIS Header für die Standard-Peripherie-Module (DWT und CoreDebug sind tatsächlich ARM IPs), die Sie verwenden sollten. Dazu gehören nicht magische Zahlen, aber die definierten Konstanten/Makros.

Weitere Informationen finden Sie im "Architecture Reference Manual". Vorsicht: gibt es auch eine "Architektur Application Level Referenzhandbuch", die nicht was Sie wollen.

+0

Ich habe das oben mit den vordefinierten Definition Header versucht, aber ich habe immer noch das gleiche Problem, wo die Werte nicht bearbeitet werden können. Der CoreDebug-> DEMCR wird nicht geändert, was sehr seltsam ist. Die einzige andere Sache, die ich mir vorstellen kann, ist, ob FreeRTOS oder LwIP den CMSIS-Header verwenden, aber wenn dies der Fall wäre, würde ich nicht den CYCCNT-Wert erhöhen, wenn das Programm läuft? – KenQueso

+0

@KenQueso: Dies ist kein Grund, meine Antwort zu verwerfen! Nicht sicher, was du mit deinem Kommentar meinst, AFIK die IPs sind in diesen Aspekten identisch. Was meinst du mit "wo die Werte nicht bearbeitet werden können"? Es ist völlig unklar. Und das hängt nicht mit FreeRTOS usw. zusammen. Die Header können ohne Betriebssystem verwendet werden, nur der richtige Compiler. Vielleicht fehlen dir einige Grundlagen mit deiner Toolchain. Stellen Sie eine [mcve] bereit. – Olaf

+0

Ich habe deine Antwort nicht abgelehnt, ich habe nicht einmal genug Punkte, um über Fragen abzustimmen. So oder so, habe ich ein Vorher-Nachher-Bild zum ursprünglichen Beitrag hinzugefügt, um zu versuchen, was passiert ist – KenQueso

4

Vielleicht fehlt die DBG regs (DWT-> LAR = 0xC5ACCE55) zu entsperren: Sequenz unten gelöst pb für mich:

 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 
     DWT->LAR = 0xC5ACCE55; 
     DWT->CYCCNT = 0; 
     DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 
2

Sie machen alles richtig, außer dass Sie den Zugriff auf DWT zu entsperren fehlen registrieren (wie Howard darauf hingewiesen hat).

volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000; 
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004; 
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC; 
volatile uint32_t *LAR = (uint32_t *) 0xE0001FB0; // <-- added lock access register 

*DEMCR = *DEMCR | 0x01000000;  // enable trace 
*LAR = 0xC5ACCE55;    // <-- added unlock access to DWT (ITM, etc.)registers 
*DWT_CYCCNT = 0;     // clear DWT cycle counter 
*DWT_CONTROL = *DWT_CONTROL | 1; // enable DWT cycle counter 

zu beachten, dass, wie in ARMv7-M Architektur Referenzhandbuch angegeben, Verriegelungsmechanismus nur auf Software-Zugang gilt: In Ihrem Code wäre es etwas ähnliches sein. DAP-Zugriff ist immer erlaubt (deshalb können Sie den Zykluszähler mit dem Debugger aktivieren).

Bitte beachten Sie, dass beide STM32F7 documentation und ARM documentation einen Tippfehler haben und geben 0xE0000FB0 als Adresse des Verschluss-Zugriffsregister (siehe here). Die Verwendung von CMSIS-Kernregistrierungsdefinitionen (core_cm7.h) hätte Ihnen dieses Problem erspart, da sie korrekt sind und natürlich effizienter gewesen wären, wie Olaf sagte;)

Verwandte Themen