STM32F407 und Double/Float mit FPU

Gast #4220732
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 ?
#4220813
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.
Gast #4220831
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 ;-) )
Gast #4220850
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.
Gast #4220879
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.
Gast #4220932
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 :-)
Gast #4220969
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 ;-)
Gast #4221027
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.
Gast #4221233
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.
#4222220
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.