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
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
|
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...
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).
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; |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.