Forum: Mikrocontroller und Digitale Elektronik STM32 Float Problem


von Bergfried (Gast)


Lesenswert?

Hallo,

mein Problem ist, dass Gleitkommazahl (float) Operationen nicht 
funktionieren. Ich arbeite mit Ride7 von Raisonance.
Beispiel:
1
float func(float a)
2
{
3
  return a / 2.0f;
4
}
5
6
void main()
7
{
8
  float v;
9
  v = func(2.0f);
10
  // => v beinhaltet dann nach dem ausführen nur Datenschrott
11
  while(1);
12
}

Kennt jemand eine Lösung für dieses Problem?

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Mit hard-float Option compiliert? FPU dann vor Verwendung auch 
eingeschaltet (in SBP-Register CPACR)?

von Bergfried (Gast)


Lesenswert?

Leider scheint es bei Ride7 keine Makefile zu geben,
und in den Einstellungen kann ich nicht zu hard-float oder 
Software-float finden.
Kenn sich jemand mit Ride7 aus?

von Bergfried (Gast)


Lesenswert?

Ich habe etwas seltsammes festgestellt, wenn ich den Code wie folgt 
abändere, dann klappt es.
Aber Warum?
1
float func(u32 a)
2
{
3
  float a_f = (float)a;
4
  float b = 2.0f;
5
  return a / b;
6
}
7
8
void main()
9
{
10
  float v;
11
  float p = 2.0f;
12
  v = func((u32)p);
13
  // => v liefert jetzt den korrekten Wert
14
  while(1);
15
}

von Bergfried (Gast)


Lesenswert?

Ich habe mich da getäuscht, es klappt so doch nicht. Wenn ich mit dem 
Debugger reinschauer, bekommen ich lediglich für a_f, den richtigen 
Wert, das hatte vorher schon nicht geklappt.
Es scheint tatsächlich so zu sein, dass irgenwie die Hard/Software 
Float-Einstellung falsch ist.

Wie würde es in der Makefile aussehen, wenn man hard-float festlegen 
würde?

von Dennis (Gast)


Lesenswert?

Bergfried schrieb:
> Wie würde es in der Makefile aussehen, wenn man hard-float festlegen
> würde?

SuFu

von Matthias K. (matthiask)


Lesenswert?

Kenne zwar Ride7 nicht im Detail, aber z.B. bei GCC muss man für float 
eine zusätzliche Lib einbinden.

Vielleicht auch ein Optimierungsproblem, weil v nicht weiter verwendet 
wird (while(1); Versuch mal testweise volatile.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?


von Bergfried (Gast)


Lesenswert?

Ich habe mittlerweile das Problem ausmachen können und auch provisorisch 
gelöst. Das Problem ist nicht die Gleitkomma berechnung, folgendes 
funktioniert z.B. problemlos:
1
void main()
2
{
3
  float a, b;
4
  a = 5.0f;
5
  b = a / 2.0f;
6
  if(b == 2.5f)
7
  {
8
    // Funktioniert
9
  }
10
11
  while(1);
12
}

Zu Problemen kommt es wenn float Variablen als Parameter oder als 
Rückgabewert einer Funktion benutzt werden, dann kommt es zu 
Datenschrott und Zufallsfehlern.

Gelöst habe Ich das Ganze in dem Ich anstelle von float den Pointer 
unsignet int* verwende und in der Funktion diesen dann Caste.
1
void func(unsigned int* flt_value)
2
{
3
  float* value = (float*)flt_value;
4
  *value = *value / 2.0f;
5
}

Die Ursache sehe Ich im RKit-ARM V1.24.10.0050, welches mit der Standard 
Version (32KB Debugger Beschränkung) ausgeliefert wird.
Es gibt zwar eine neuere Version, welche nach einer Registrierung 
heruntergeladen werden kann, aber diese kann nicht mit der RLink 
Standard Version benutzt werden.

Ich bin absolut enttäuscht von dem Raisonance RLink und der Ride7 IDE,
alles ist verbuggt und support gibt es nur für die Prof. Version.

Deshalb kann ich nur von diesem Produkt abraten.

von frame (Gast)


Lesenswert?

> Ich bin absolut enttäuscht von dem Raisonance RLink und der Ride7 IDE,
> alles ist verbuggt und support gibt es nur für die Prof. Version.

> Deshalb kann ich nur von diesem Produkt abraten.

Vorsichtig - meist sitzt das Problem vor der Tastatur.

Ich kenne den ARM-Compiler von Raisonance auch nicht - meine Firma setzt 
allerdings den STM8-Compiler kommerziell ein, mit dem ich auch arbeite.

Bei ARM/Cortex hast du bezüglich FP drei Möglichkeiten:
1. float-abi=soft
2. float-abi=softfp
3. float-abi=hard
Die erste Möglichkeit erzeugt Aufrufe der Lib-Funktionen OHNE FPU-
Benutzung, mit Parameterübergabe in Core-Registern.
Die zweite Möglichkeit erzeugt Aufrufe der Lib-Funktionen MIT FPU-
Benutzung,die Parameter werden ebenfalls in Core-Registern übergeben.
Die dritte Möglichkeit erzeugt direkten FPU-Code wenn möglich, und 
benutzt FPU-Register (und keine Core-Register) bei Lib-Aufrufen.

Das bedeutet erstens, daß die von deinem Projekt benutzte ABI identisch 
mit der der verwendeten libm.a sein muß (also Übergabe in Core-Registern 
ODER in FPU-Registern). Und zweitens machen 'softfp' und 'hard' nur 
Sinn, wenn du einen Controller mit FPU hast (also STM32F4).

Jedenfalls hört sich dein Problem nach Vermischung von 2. und 3. an.
Schaue doch einmal in den Projekteinstellungen nach, welche Option 
verwendet wird (Hinweis: suche nach "-mfloat-abi=<xxx>").

von Norden (Gast)


Lesenswert?

Hallo frame,

Ich schließe nicht völlig aus, dass ich irgendwie das Problem selbst 
verursache. Aber ich denke es liegt eher an den ARM-Kit. Ich habe das 
Programm auf die STM32F10x_StdPeriph_Lib_V3.5.0, die main- und die func- 
Funktion  reduziert. Da ist nicht viel was falsch gemacht werden kann. 
Ich vermute es handelt sich dabei um ein Addressierungsfehler, denn das 
Programm wird dabei vollig zerschossen. Ich habe schon einige 
ARM-Projekte realisiert, jedoch immer ohne Gleitkommazahlen.
Außerdem, das Programm läuft fehlerfrei wenn ich die integer Pointer 
benutze, im richtigen Projekt ist ein LCD-Bildschirm dabei, deshalb 
konnte ich das ganze auch schon so testen, dass ich den Debugger als 
Ursache ausschließen kann.

Bei der Ride7 IDE von Raisonance kann man die float-abi nicht über die 
Einstellungen ändern. Es gibt dort auch keinerlei Zugriff oder 
Einsichtmöglichkeiten in die Makefile. Das ganze scheint ausschließlich 
dazu zu dienen, den Benutzer davon abzuhalten, ein anderes ARM-Kit zu 
verwenden wie z.B. das Open Source GCC ARM Embedded.

Es gibt bereits ein RKit-ARM 1.44.12.0213, welches aber nur mit der 
Prof. Version benutzt werden kann. Ich kann es herunterladen und auch 
installieren, dann muß dieses aber in Ride7 Online aktiviert werden. 
Hier wird dann seitens Raisonance bemängelt, das ich nur die Standard 
Version haben und natürlich angeboten dieses sofort zu kaufen.

von frame (Gast)


Lesenswert?

Unter der Annahme, daß deine Angaben über RIDE7 + Raisonance Compiler 
für ARM korrekt sind, stimme ich dir zu - große Sch***e.

Ich habe ein ähnliches Problem für den stm32f4 mit der 
summon-arm-toolchain durchexerziert. Dort gab es allerdings nicht 
anderes als MAKE file und Kommandozeile. Wenn Kompilat und Bibliothek 
nicht zusammengepaßt haben, gab es eben wie von dir beschriebene 
Probleme.

Und die RIDE7 Variante für den STM8, die ich kommerziell nutzen darf, 
hat dieses Problem wg. fehlender FPU nicht...

Je mehr IDEs ich kennenlerne, desto mehr lerne ich BASH + MAKE schätzen.

von Roland H. (batchman)


Lesenswert?

Um welche stm32 CPU handelt es sich? Mit oder ohne FPU?

> Ich schließe nicht völlig aus, dass ich irgendwie das Problem selbst
> verursache. Aber ich denke es liegt eher an den ARM-Kit. Ich habe das
> Programm auf die STM32F10x_StdPeriph_Lib_V3.5.0, die main- und die func-
> Funktion  reduziert. Da ist nicht viel was falsch gemacht werden kann.

Oh doch. Bei der Erstellung der multi libs können Fehler gemacht werden, 
und dann noch beim Setzen von -mfloat und -mfpu. Plötzlich geht es dann 
nicht mehr, wenn float ins Spiel kommt. Besonders lustig wird es dann, 
wenn noch uint64_t dazu kommt.

Was ist das "ARM kit"? Ist das ein verpackter GCC?

Der GCC setzt ein paar #defines, _VFP_FP_,  _SOFTFP_ etc., so 
könntest Du u. U. durch die Hintertür sehen, was wirklich drin ist.

Ich würde es aber gleich mit summon-arm-toolchein probieren.

frame schrieb:
> Je mehr IDEs ich kennenlerne, desto mehr lerne ich BASH + MAKE schätzen.

Ja, Jubel, jetzt sind wird schon zu zweit :-)

von frame (Gast)


Lesenswert?

Was ich noch anfügen wollte:
Einerseits hat RIDE-7 eine recht gute Dokumentation und Hilfe, zumindest 
was die mir bekannte STM7/STM8 Variante betrifft. Ich würde einmal 
nachschauen, wie das Thema dort behandelt wird.
Raisonance hat auch ein eigenes Forum, durch ihren "SPAM-Filter" ist es 
aber schwerlich benutzbar.

Andererseits - wenn du einmal nach Schlagwortkombinationen "Cortex 
M0/3/4" und "<toolchain>" suchst, wobei <toolchain> z.B. Keil, IAR, 
Atollic, GCC oder Raisonance RIDE-7 ist, wirst du feststellen, daß 
letzteres eher wenig verbreitet ist. Möglicherweise benutzen es 
hauptsächlich Franzosen aus lokalpatriotischen Gründen (;-)).
Der Raisonance-Compiler ist definitiv nicht in CMSIS berücksichtigt, 
deshalb wäre er auch nicht meine erste Wahl.

von ttl (Gast)


Lesenswert?

die FPU muss eingeschaltet werden!!!


so z.B.
void cortexm4f_enable_fpu() {
    /* set CP10 and CP11 Full Access */
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
}

von frame (Gast)


Lesenswert?

> die FPU muss eingeschaltet werden!!!

Sonst landet man bei FPU-Befehlen üblicherweise im Hardfault-Handler.
Da das augenscheinlich nicht der Fall ist, liegt das Problem 
wahrscheinlich wo anders.

Aber du hast recht. Wobei manche Toolchain die Aktivierung der FPU 
automatisch ins Projekt integrieren, wenn man die FPU-Option auswählt.

von Bergfried (Gast)


Lesenswert?

@frame
Stimmt es ist zwar am anfang mühselig sich in der Makefile Skriptsprache 
einzuarbeiten, aber wenn man das dann hat, hat man wenigstens die 
kontrolle über den Compiler.
Im Hardware Fault lande ich garnicht, wenn ich z.B. den Float-Wert 12.5f 
übergebe, und mit dem Debugger dann in der Funktion anhalte, kommt dort 
der Wert nicht an, auch alle zusätliche Paramter haben dann völlig 
anderen Inhalte. Das ganze habe ich, da Ich den Debugger nicht getraut 
hatte, auch mit der LCD-Ausgabe überprüft.

@Roland H
Der Prozessor ist STM32F103C8T6.
uint64_t oder allgemein 64-Bit Integer habe ich nicht benutzt.

Zitat: "Was ist das "ARM kit"? Ist das ein verpackter GCC?"

Das scheint GCC + Toolchein von Raisonance zu sein, es ist wohl 
absichtlich so gemacht, das keine anderen benutzt werden können.

Und wie schon gesagt, ich benutze da einen mehrere Jahre alten Stand des 
ARM-Kit, die neueren Versionen sind nur gegen Bares erhältlich.

@ttl
Das habe Ich auch schon versucht, die Gleitkomma berechnung direkt in 
der main oder einer andern Funktion funktioniert nur als Parameter oder 
Rückgabewert einer Funktion treten die Problem auf.
Folgendes funktioniert z.B.
1
void func()
2
{
3
  float a, b;
4
  a = 5.0f;
5
  b = a / 2.0f;
6
  if(b == 2.5f)
7
  {
8
    // (x) Landet immer hier
9
    printf("Funktioniert");
10
  }
11
  else
12
  {
13
    printf("Funktioniert nicht!");
14
  }
15
}


Das ganze ist schon wirklich ärgerlich, warum verkaufen die überhaupt 
eine Standard Version, wenn diese nicht weiter entwickelt wird?
Ich werde wohl auf eine andere IDE mit ARM-GCC umsteigen, auch wenn ich 
dort auf die Debug Funktion(bis 32K) verzichten muß.

von frame (Gast)


Lesenswert?

> Der Prozessor ist STM32F103C8T6.

Damit ist das Thema FPU erst einmal vom Tisch.


> Und wie schon gesagt, ich benutze da einen mehrere Jahre alten Stand
> des ARM-Kit, die neueren Versionen sind nur gegen Bares erhältlich.

Ich habe Raisonance (für ARM) nie ernsthaft in Erwägung gezogen.
Dewegen kann ich das auch nicht beurteilen.



> Ich werde wohl auf eine andere IDE mit ARM-GCC umsteigen, auch wenn
> ich dort auf die Debug Funktion(bis 32K) verzichten muß.

Ich weiß nicht, worauf du das beziehst.
Es gibt mehrere kommerzielle IDEs in freien Versionen, die auf 32k 
Flash-
größe beschränkt sind (Keil, IAR, Atollic). Debuggen funktioniert bei
allen. Die freie Atollic IDE-Variante beschränkt übrigens Code für den
M0 auf 8k. Außerdem habe ich mit letzterer nicht so gute Erfahrungen
gemacht - außerdem basiert sie auf Eclipse ;-(.

Wenn du innerhalb der M-Familie eines Herstellers bleibst (z.B. alle
Cortex M3 Varianten von ST), kannst du auch gut mit einer Open Source
Toolchain zurecht kommen. Die in einem früheren Posting erwähnt Summon
Arm Toolchain hat templates für M3 und M4 mitgebracht. Für Linux gibt
es auch STLink-Unterstützung, inklusive GDB server.
Wenn du außerdem noch mit ARM-Controller von NXP, Atmel oder Freescale
hantieren willst, hast du das gleiche Problem.

Deswegen habe ich mir eine private Lizenz für Crossworks zugelegt, die
ist noch relativ günstig (dafür aber nicht für kommerzielle Nutzung
freigegeben).

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.