Forum: Mikrocontroller und Digitale Elektronik STM32F407 und Double/Float mit FPU


von Pepe (Gast)


Lesenswert?

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 ?

von Little B. (lil-b)


Lesenswert?

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.

von Pepe (Gast)


Lesenswert?

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 ;-) )

von m.n. (Gast)


Lesenswert?

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.

von Jojo S. (Gast)


Lesenswert?

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

von Pepe (Gast)


Lesenswert?

@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.

von m.n. (Gast)


Lesenswert?

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"

von Pepe (Gast)


Lesenswert?

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 :-)

von m.n. (Gast)


Lesenswert?

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 ;-)

von Pepe (Gast)


Lesenswert?

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.

von m.n. (Gast)


Lesenswert?

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.

von Pepe (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Pepe (Gast)


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

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).

von Ingo L. (corrtexx)


Lesenswert?

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.

von Ingo K. (unseen)


Lesenswert?

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

von Pepe (Gast)


Lesenswert?

Stefan schrieb:
> der neue CortexM7 von Atmel

Hab ich auch schon gesehen. Der ist aber ja noch weniger lieferbar wie 
der STM32F7...

von Stefan (Gast)


Lesenswert?

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