Hallo. Ich habe ein Problem mit Keil 5.15 und der Verwendung der FPU auf dem STM32F407. char buffer[100]; float dParam; strcpy(buffer, (char *) &_cmd[0]); // Kopiert String in lok. Buffer dParam = atof(Buffer); In den Projektoptionen hab ich die FPU Hardware mit "Use Single Precision" ausgewählt. Obiger Code funktioniert solange dParam vom Typ float ist. Sobald ich "double dParam" verwende erhalte ich immer "fast 0" zurück (xxe-314). Schaue ich mir die ASM Befehle im Disassembler an, kann ich sehen, dass beide Male __hardfp_atof verwendet wird. Da der STM32F407 aber ja nur Single Precision kann, glaube ich, dass dies mein Problem ist. Ich brauche aber an einigen Stellen die Double-Genauigkeit, die Floats müssen aber schnell berechnet werden, da mir sonst meine Regelschleife zu langsam wird. Was kann man da machen ?
Wie du schon bemerkt hast, kann der STM32F4 nur Single Precision. Willst du double rechnen, so wird dir die FPU nicht weiterhelfen können. atof() gibt normal einen double zurück. Ob das auch hier der Fall ist, musst du deiner Bibliothek entnehmen. Ich vermute jedoch, dass hier atof() auch nur mit single precision arbeitet. Das Phänomen, was du beschreibst, kann ich daher nur auf einen Mislungenen typecast des compilers zurückführen. Was aber genau schief läuft, könnte man dem Disassembly entnehmen. Was man machen kann? Den Controller wechseln! Cortex M haben generell nur eine single precision FPU. Double müssen also in Software berechnet werden. Sind dafür die etwa 200MHz zu wenig, bleibt nur die Wahl eines größeren Controllers.
Das sind die beiden Varianten des Disassemblys. Mit "double dParam;": 640: dParam = atof(buffer); 0x08007088 A801 ADD r0,sp,#0x04 0x0800708A F7FDFC8D BL.W __hardfp_atof (0x080049A8) 0x0800708E EEB08A40 VMOV.F32 s16,s0 0x08007092 EEF08A60 VMOV.F32 s17,s1 Mit "float dParam;" 0x08007088 A801 ADD r0,sp,#0x04 0x0800708A F7FDFC8D BL.W __hardfp_atof (0x080049A8) 0x0800708E EEB0AA40 VMOV.F32 s20,s0 0x08007092 EEF0AA60 VMOV.F32 s21,s1 0x08007096 EC510B1A VMOV r0,r1,d10 0x0800709A F008FD1F BL.W __aeabi_d2f (0x0800FADC) 0x0800709E EE080A10 VMOV s16,r0 Da ich nur an ganz wenigen Stellen mit double-Genauigkeit rechnen muss (z.B. beim Vorberechnen der Bahnparameter für eine Fahrt), hatte ich auf eine Lösung Richtung "Double = softfp & float = hardfp" gehofft. Gibt es so was ? ( Am besten ohne die "SoftFP"-Lib selbst in ASM zu programmieren ;-) )
Little B. schrieb: > Was man machen kann? > Den Controller wechseln! > Cortex M haben generell nur eine single precision FPU. Double müssen > also in Software berechnet werden. Sind dafür die etwa 200MHz zu wenig, > bleibt nur die Wahl eines größeren Controllers. Obwohl ich nicht mit Keil arbeite, muß ich widersprechen. Weder muß der Controller gewechselt werden, noch ist er zu langsam. Auch gibt es Cortex M Prozessoren mit 'double-FPU' (Atmel war das, glaube ich). Vom Keil-Compiler kannst Du erwarten, daß float und double in Deinem Programm gleichzeitig und unabhängig genutzt werden können. Bevor Du Dich hier in die Irre führen läßt, frag bei Keil nach, welche Einstellungen sinnvoll sind, um beide Datentypen zu mischen. Vielleicht gibt es die passende Antwort auch schon unter FAQ.
liegt das vielleicht an der Microlib? Ist in den Projekteinstellungen wählbar. Oder hilft die Option '--fpmode=std'? siehe auch: http://www.keil.com/support/man/docs/armccref/armccref_CIHJCADC.htm
@m.n. Hab schon eine Supportanfrage am laufen. War aber bisher noch nicht erfolgreich. Und bei mir brennt gerade die Hütte... ich muss fertig werden. Deshalb frag ich gleich noch parallel :-) @jojos --fpmode=std hat nichts gebracht; die MicroLib hab ich eigentlich immer aus. Gerade bei Prozessoren wo ich kein Platzproblem habe.
Pepe schrieb: > Und bei mir brennt gerade die Hütte... ich muss fertig > werden. Deshalb frag ich gleich noch parallel :-) Wenn Du Alles mit 'double' rechnest, ist es tatsächlich zu langsam? Vor ein, zwei Jahren hatten hier einige Leute Testwerte geliefert, die zeigten, daß auch 'double'-Berechnungen sehr schnell gehen. Ich habe es gefunden: Beitrag "Re: Controller mit FPU"
Ich habe probeweise schon umgestellt von hardfp auf softfp. Ich hab zwar die Dauer meiner Regelschleife dann nicht gemessen, aber ich hab gesehen, dass ich meinen bisherigen Regeltakt um einiges sprenge. Damit die Regelung wieder "in den Regelungstakt passt", müsste ich den Takt mind. 2x nehmen. Da springt mir wahrscheinlich mein Kunde ins Gesicht :-)
Kannst Du Deine 'double'-Berechnungen vielleicht in eine separate .c-Datei auslagern und die Funktionen mit passenden Übergabewerten aufrufen? Damit könnte man u.U. eine Kollison der Datentypen verhindern. Eigentlich müßte doch die fixpoint-Fraktion eine einfache Lösung parat haben ;-)
Das Auslagern könnte ich mir ansehen. Wäre evtl. eine Lösung, da ich ja die Bahnsteuerung mit double/softfp und nur Regelung mit float/hardfp brauche. Werd' ich mir morgen mal anschauen. Festkomma mag ich eigentlich nicht so gern. Gerade bei einer Bahnsteuerung mit "Jerk" (Polynom 3.er Ordnung) kann es da schon mal unübersichtlich werden... sprich fehleranfällig.
Pepe schrieb: > Festkomma mag ich eigentlich nicht so gern. Das war eine ironische Anmerkung. Ich mag Festkomma garnicht, obwohl ich es mal vor 20 Jahren verwendet hatte.
m.n. schrieb: > Ich mag Festkomma garnicht Aber ehrlich gesagt, hab ich mir das schon überlegt. Bei kleineren Prozessoren (z.B. Atmega's) find ich Festkomma gar nicht so schlecht, wenn die Anwendung überschaubar ist. Aber ich hab noch keine Anwendung mit Festkomma gehabt, wo ich nicht beim Debuggen geflucht habe, weil ich wieder irgendwo ein Ergebnis hatte was um Welten daneben liegt. PS. Hab zwischenzeitlich eine Aussage vom ARM Support: Ein "mixed mode" zwischen hardfp und softfp ist nicht vorgesehen.
Pepe schrieb: > PS. Hab zwischenzeitlich eine Aussage vom ARM Support: Ein "mixed mode" > zwischen hardfp und softfp ist nicht vorgesehen. Mixed hardfp und softfp geht tatsächlich nicht (da jeweils anderes ABI), aber man kann trotzdem Double Berechnungen mit einem Cortex M4F und hardfp ABI machen. IMO geht das mit GCC ARM Embedded einwandfrei.
Jim M. schrieb: > IMO geht das mit GCC ARM Embedded Welche Compiler Settings etc. verwendest Du? Vielleicht kann man das ja an den Keil anpassen.
Falls es für Dich eine Option ist den MCU zu wechseln, der neue CortexM7 von Atmel implementiert floating und double precision FPU (im Gegensatz zu STM32F7 nur float).
Stefan schrieb: > im Gegensatz zu STM32F7 nur float Ja, das hat ST wohl verpennt... Mich wundert sowieso das man nicht alle Controller (bei denen es Sinn macht) mit ner double-precision FPU ausstattet.
Nur weil die FPU keine double-Berechnungen ausführen kann muss man doch nicht gleich auf reine Softfloats umstellen. Methoden, um die Präzision von Berechnungen durch Verwendung von mehreren Float-Zahlen zu erhöhen sind seit Jahrzehnten bekannt und wurden von der GPU-Compute-Fraktion wieder ausgegraben und teilweise erweitert, weil Grafikchips nicht immer (schnell) mit doubles rechnen können. Eine bei kurzem Überfliegen brauchbar aussehende Übersicht mit vielen Verweisen auf weitere Quellen gibts hier: http://andrewthall.org/papers/df64_qf128.pdf
Stefan schrieb: > der neue CortexM7 von Atmel Hab ich auch schon gesehen. Der ist aber ja noch weniger lieferbar wie der STM32F7...
Pepe schrieb: > Stefan schrieb: >> der neue CortexM7 von Atmel > > Hab ich auch schon gesehen. Der ist aber ja noch weniger lieferbar wie > der STM32F7... Digikey verkauft die SAMS70 schon
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.