Forum: Mikrocontroller und Digitale Elektronik Takte zählen beim STM32F4


von Christoph B. (nuke)


Lesenswert?

Hallo,

ich würde gern auf dem STM32F4 irgendwie die Anzahl der Takte ermitteln, 
die eine Reihe von Instruktionen braucht. Gibt es da eine verlässliche 
und halbwegs einfache Möglichkeit? Es geht u.A. um den Vergleich mit und 
ohne FPU-Nutzung.
Ich würde ungern in den Assembler-Code schauen und dort die Takte 
zählen, da ich auch Codeblöcke mit ein paar mehr Instruktionen auswerten 
möchte.

Danke schonmal im Voraus!

Beste Grüße, Christoph

von Timmo H. (masterfx)


Lesenswert?

SysTick ?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Macht der Cortex-Core schon:
1
// Sys-Tick Counter - Messen der Anzahl der Befehle des Prozessors:
2
#define CORE_SysTickEn()      (*((u32*)0xE0001000)) = 0x40000001
3
#define CORE_SysTickDis()     (*((u32*)0xE0001000)) = 0x40000000
4
#define CORE_GetSysTick()     (*((u32*)0xE0001004))
5
#define CORE_ClearSysTick()   (*((u32*)0xE0001004)) = 0

von Christoph B. (nuke)


Lesenswert?

Vielen Dank für den Code! Das Problem ist nur folgendes:

Ich lasse mir die Variable über den USART ausgeben, doch sobald ich den 
Debug-Modus vom TrueStudio verlasse und den Controller selber werkeln 
lasse, kommt nur eine 0 an, statt der sonst 6 Takte.

Ich habe folgenden Code ausgeführt, um zu testen, wie lange die 
SysTick-Abfrage an sich ohne Code dazwischen braucht:
1
CORE_ClearSysTick();
2
CORE_SysTickEn();
3
4
vu32 time1 = CORE_GetSysTick();
5
vu32 time2 = CORE_GetSysTick();
6
7
CORE_SysTickDis();
8
9
vs32 diff = time2 - time1;

edit: An der USART-Kommunikation liegts nicht, das habe ich durch eine 
testweise Addition von diff mit 1 ausgeschlossen...

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der Code funktioniert bei einem STM32F103. Evt. ist das Register beim 
Cortex-M4 ein anderes, lese mal in der Doku von ARM über die Core 
internen Register. (Kann ich mir jetzt nicht vorstellen.)

Ich ermittle damit auch den Zeitbedarf bei kritischen Interrupts, die 
sich oft wiederholen (z.B. schnelle AD Messung mit 1,6µS).

von Timmo H. (masterfx)


Lesenswert?

Auszug aus der core_cm4.h
1
/* Memory mapping of Cortex-M4 Hardware */
2
#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
3
#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
4
#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
5
#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
6
7
.....
8
9
/** \brief  Structure type to access the System Timer (SysTick).
10
 */
11
typedef struct
12
{
13
  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
14
  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
15
  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
16
  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
17
} SysTick_Type;

von Christoph B. (nuke)


Lesenswert?

Ich habe jetzt die Adressen entsprechend geändert und es funktioniert 
auch.
Nur tritt folgendes Phänomen auf:

Wenn ich zum Test eine gewisse Anzahl NOPs messe ( asm("nop"); ), kommt 
am Ende nicht die entsprechende Anzahl Takte heraus. Die Anzahl ist idR 
höher und ist abhängig vom Code vor der Messung. (zB 
Variablendefinitionen verändern den Wert)

Woran liegt das?

Viele Grüße,
Christoph

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
Noch kein Account? Hier anmelden.