Datum:
Hallo, ich programmiere jetzt seit einiger Zeit die STM32 Controller mit dem Atollic TrueStudio. Ich frage mich jetzt nur ob die FPU der STM32F4 Controller wirklich gestartet wird. Ausgewählt habe ich im Projekt-Erstellen Dialog vom Atollic TrueStdio "Floating Pointing : Mix HW/SW implementation". Im Startup-Code steht auch
/*FPU settings*/ ldr r0, =0xE000ED88 /* Enable CP10,CP11 */ ldr r1,[r0] orr r1,r1,#(0xF << 20) str r1,[r0] |
Hat jemand eine Idee wie ich rausfinden kann ob die FPU läuft? Moritz
Datum:
Moritz M. schrieb: > Hat jemand eine Idee wie ich rausfinden kann ob die FPU läuft? Wieso sollte sie nicht laufen, nachdem Du CP10/11 aktiviert hast? Um das zu prüfen lässt Du einfach einen FPU Befehl ausführen und schaust, ob er das gewünschte Ergebnis liefert. -- Marcus
Datum:
Hallo, okay vielen Dank! Wie würde den so ein FPU Befehl aussehen? ich dache wenn ich mit Gleitkomma rechne würde die FPU das automatisch erledigen? Moritz
Datum:
>Wie würde den so ein FPU Befehl aussehen? ich dache -> Cortex reference manuals. >wenn ich mit Gleitkomma rechne würde die FPU das automatisch erledigen? Wenn Du die richtigen Compileroptionen anwendest oder in Assembler programmierst und den Rat von Marcus oben befolgst, sollte das auch passieren.
Beitrag #2707640 wurde von einem Moderator gelöscht.
Beitrag #2707656 wurde von einem Moderator gelöscht.
Datum:
Moritz M. schrieb: > ich dache > wenn ich mit Gleitkomma rechne würde die FPU das automatisch erledigen? Wenn man dem Compiler mitteilt, dass man das möchte, dann ja:
COMMON_FLAGS += -mfloat-abi=hard COMMON_FLAGS += -mfpu=fpv4-sp-d16 |
für AS, CC, LD. Dann wird aus
const float f2 = f * 2.29f; |
so etwas:
8001488: edd4 7a00 vldr s15, [r4] 800148c: ee27 7a88 vmul.f32 s14, s15, s16 |
ohne FPU sieht es es so aus:
8001ba4: 4925 ldr r1, [pc, #148] ; (8001c3c <main+0x120>) 8001ba6: 6820 ldr r0, [r4, #0] 8001ba8: f7fe ec68 blx 800047c <__aeabi_fmul> 8001bac: 4607 mov r7, r0 |
Datum:
Gut dass es diesen Thread gibt ;-) Nicht alle haben bisher die FPU richtig benutzt, bzw. wissen wie es richtig geht (incl. mich). Zum ersten, wenn man die Compileroptionen (siehe oben) setzt und man hat nicht diese 4 Assember Befehle für das Aktivieren der FPU drin und man nutzt float Zahlen, dann gibt es einen Absturz mit "Hard-Fault-Exception()" Interrupt. Somit muss immer beides gemacht werden. Verwirrender weise zeigt das Listing von GCC den Assembler Befehl "fmuls" hingegen im Disassembler Fenster beim Debuggen "vmul.f32" an. Nun zu meinen kleinen Tests:
float f = 1.01f; CORE_SysTickEn(); vu32 it = CORE_GetSysTick(); float f2 = f * 2.29f; vu32 it2 = CORE_GetSysTick() - it; |
Das Ergebnis ist bei der GCC und der FPU Variante immer gleich. Nur der Windows Taschenrechner zeit eine andere Zahl. Die Taktberechnung verbraucht 6 Takte, die habe ich von der Float-Zählung abgezogen: GCC: 41 FPU: 5 Dann habe ich die Zeile geändert:
float f2 = f / 2.29f; |
GCC: 155 FPU: 21 Ist doch ein deutlicher Unterschied. Testboard: STM32F4-Discovery Compiler: arm-none-eabi-gcc.exe (Sourcery CodeBench Lite 2011.09-69) 4.6.1 Optimierungsstufe: -O0 Defines für den Systic:
// Sys-Tick Counter - Messen der Anzahl der Befehle des Prozessors: #define CORE_SysTickEn() (*((u32*)0xE0001000)) = 0x40000001 #define CORE_SysTickDis() (*((u32*)0xE0001000)) = 0x40000000 #define CORE_GetSysTick() (*((u32*)0xE0001004)) |
Datum:
Markus Müller schrieb: > Somit muss immer beides gemacht werden. Ich dachte, das sei nach den beiden ersten Postings klar ;-) Markus Müller schrieb: > Defines für den Systic:// Sys-Tick Counter - Messen der Anzahl der Befehle des Prozessors: > #define CORE_SysTickEn() (*((u32*)0xE0001000)) = 0x40000001 > #define CORE_SysTickDis() (*((u32*)0xE0001000)) = 0x40000000 > #define CORE_GetSysTick() (*((u32*)0xE0001004)) Ist das der Cortex-SysTick? Wo hast Du denn diese Adressen/Register gefunden?
Datum:
Das ist der Befehls-Counter mit dem man exakt messen kann wie viele Clock-Takte der CPU für die Bearbeitung vergehen. Die Register stehen im "Cortex-M3 Technical Referenz Manual" unter "Data Watchpoint and Trace registers" der Firma ARM. Such einfach nach "E0001000". Das geht somit auch beim LPC17xx und anderen Prozis mit einem Cortex-M3/M4 drin. Dieser Befehl ist wichtig, wenn man Zeitkritische Anwendungen hat und man kann somit exakt feststellen wie viele µS eine Routine benötigt. Ich musste mal AD-Interrupts recht komplex berechnen, da war es natürlich wichtig, dass die Routine weniger Zeit braucht, als wie der Interrupt erneut aufgerufen wird und die App genügend Reserve hat. Beim ARM7 musste man dafür noch extra einen Timer konfigurieren/missbrauchen.
Datum:
Markus Müller schrieb: > Die Register stehen im "Cortex-M3 Technical Referenz Manual" unter "Data > Watchpoint and Trace registers" der Firma ARM. Such einfach nach > "E0001000". Aha. Mich hat die Angabe "SysTick" verwirrt. Denn damit assoziiere ich den Cortex SysTick Timer, dessen Register an einer anderen, aber ähnlichen Adresse liegen. Zu "E0001000" findet sich leider auch nix in core_cm4.h Sehr interessant - wieder etwas gelernt.
Datum:
Roland H. schrieb: > Zu "E0001000" findet sich leider auch nix in core_cm4.h > > Sehr interessant - wieder etwas gelernt. Das ist der optimistische Standpunkt :-) Man könnte auch sagen, die Datenblätter sind zu bescheiden. Die Stückelinformationen von STM gehen mir machmal auf den Geist!
Datum:
Vollprofi schrieb: > Die > Stückelinformationen von STM gehen mir machmal auf den Geist! Das trifft den Falschen. core_cm4.h wird von ARM bereitgestellt. Das hat mit STM nix zu tun.
Datum:
Hallo, wer weiß den wo man die Compiler-Optionen im Atollic TrueStudio einfügen muss? (Arbeite noch nicht solange mit Atollic TrueStudio) Ausserdem fügt Atollic TrueStudio auch den Code
/*FPU settings*/ ldr r0, =0xE000ED88 /* Enable CP10,CP11 */ ldr r1,[r0] orr r1,r1,#(0xF << 20) str r1,[r0] |
ein, wenn man "Floating Pointing: Software implementation" auswählt. Moritz
Datum:
Benutzt du denn die Vollversion von Atollic TrueStudio. Die frühen Demoversionen konnten kein Hardware Fließkomma und die aktuellen können zwar Fließkomma aber haben eine Größenbeschränkung.
Datum:
Soviel ich weiß kann die code sourcery lite von 2011 die du verwendest noch keine native FPU Unterstützung des Cortex M4. Dagegen soll die von ARM (https://launchpad.net/gcc-arm-embedded/4.6) herausgegebene Toolchain dies können (habe ich nicht verifiziert). Ich habe diese anstatt der code sourcery lite installiert und die geht stattdessen einwandfrei. Grüße
Datum:
Zitat aus lauchpad.net: Features: * All GCC 4.6 features, plus latest mainline features * Cortex-M0/M1/M3 support * Cortex-M4 with hard float multilib support
Datum:
Ich nutze Codesourcery Lite und wie man oben sieht (Taktmessung) klappt das auch mit den FPU Befehlen. Beitrag "Re: Floating Pointing Unit STM32F4"
Datum:
Markus Müller schrieb: > Ich nutze Codesourcery Lite und wie man oben sieht (Taktmessung) klappt > das auch mit den FPU Befehlen. Das kann ich auch bestätigen, solange keine Funktionen aus der Mathlib verwendet werden. Bei der Version von Launchpad ist eine Multilib dabei, da klappt es auch mit mathematischen Funktionen und der FPU. Das hab ich getestet.
Datum:
Hallo, ich benutze eine Demo Version von TrueStudio allerdings gibt es da noch keine Code-Begrenzung. wo muss mann die Optionen nun hinzufügen? Moritz
Datum:
Hallo, okay ich hab jetzt die CooCox CoIDE. Wo fügt ihr die FPU Init Befehle ein? (startup_stm32f4xx.c ?) Ich finde es übrigens super dass das gleich in das STM32-Tutorial eingefügt wurde! :) Moritz
Datum:
Aktivierung ist in den STMicro Beispielen für STM32F4 aus der StdPeriphLib (das ist nicht das Codepacket zum STM32F4 Discovery-Board) in system_STM32F4.c/SystemInit() untergebracht. Sieht so aus:
void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif ... |
__FPU_PRESENT und __FPU_USED werden in STM32F4xx.h bzw. core_cm4.h definiert, in letzterer durch Auswertung von vordefinierten Macros in Abhängigkeit von den Compileroptionen. Man kann relativ leicht die StdPeriphLib aktualisieren, muss dann nur auf die HSE-Frequenz und die PLL Einstellung in SystemInit achten.
Datum:
Hallo!
Wenn ich das Beispiel von Markus Müller auf meinem STM32F4Discovery
probiere komme ich auch auf die 21 Takte bei der Division, nur bei der
Multiplikation auf 12 Takte anstatt wie bei ihm 5 Takte.
Was könnt der Grund hierfür sein?
In CP10 steht 0b11 und in CP11 auch 0b11!
Der Disassembly Code für die Multiplikation:
float f2 = f * 2.29f;
ED977A03 vldr s14, [r7, #12]
EDDF7A0B vldr s15, 0x080003F0 <__text_start__+0x5C>
EE677A27 vmul.f32 s15, s14, s15
EDC77A02 vstr s15, [r7, #8]
Danke für eure Hilfe!!
Datum:
Hi, hab ne Zwischenfrage zu "__FPU_PRESENT und __FPU_USED werden in STM32F4xx.h bzw. core_cm4.h definiert" In der STM32F4xx.h steht #define __FPU_PRESENT 1 /*!< FPU present Dennoch erhalte ich beim bauen folgende Fehlermeldung: Libraries\CMSIS\Include/core_cm4.h:131:8: warning: #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" Ich habe als Flag -D"ARM_MATH_CM4" eingetragen, damit der Kompiler die Mathe-Funktionen lädt. Hab ich etwas vergessen?