Forum: Mikrocontroller und Digitale Elektronik STM32F4, FPU klappt nicht mit sqrtf()


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dirk (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche mich an der FPU des STM32F4 mit CooCox und 
'gcc-arm-none-eabi'.
Die Multiplikation zweier Float-Zahlen aus der 'main.c' im Anhang 
funktioniert und erzeugt im Disassembler den Befehl
  08000288:   vmul.f32 s15, s14, s15

Jedoch wird bei 'sqrtf()' die FPU anscheinend nicht benutzt, denn der 
Disassembler zeigt
  08000294:   bl 0x8000570 <sqrtf>
statt
  vsqrt.f32
wie es lt.
  http://www.atmel.com/Images/Atmel-42144-SAM4E-FPU-and-CMSIS-DSP-Library_AP-Note_AT03157.pdf
und
  Beitrag "Re: Floating Pointing Unit STM32F4"
eigentlich sein sollte.


Ich benutze 'gcc-arm-none-eabi 5.4'. Als libm.a verwende ich die aus dem 
Verzeichnis
  \arm-none-eabi\lib\armv7e-m\fpu
Andere Versuche mit
  \arm-none-eabi\lib\fpu\libm.a
  \arm-none-eabi\lib\armv7e-m\fpu\libm.a
  \arm-none-eabi\lib\armv7-m\libm.a
  \arm-none-eabi\lib\armv7-ar\thumb\fpu\libm.a
  \arm-none-eabi\lib\armv7e-m\fpu\fpv5-d16\libm.a
bringen bestenfalls das gleiche Ergebnis, in manchen Fällen läuft auch 
das Programm nicht mehr oder das Kompilieren/Linken bricht mit einer 
Fehlermeldung ab.

Ich hatte irgendwo gelesen, dass die o.g.
  \arm-none-eabi\lib\armv7e-m\fpu\libm.a
benutzt werden soll.
Allerdings ist ARMv7E-M meines Wissens die Architektur des Cortex-M7.
Die Architektur des Cortex-M4 ist lt.
  https://de.wikipedia.org/wiki/ARM-Architektur
die ARMv7-M.
Ein Verzeichnis
  \arm-none-eabi\lib\armv7-m\fpu
ist aber leider bei mir nicht vorhanden.

Kann mir jemand helfen?

Gruß
  Dirk

P.S.:
  Compileraufruf:
    arm-none-eabi-gcc -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard 
-mthumb -Wall -ffunction-sections -g -O0 -c -DSTM32F407VG -DSTM32F4XX 
-DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ -D__FPU_USED 
-IC:\CooCox\CoIDE\workspace\Testprojekt_02 
-IC:\CooCox\CoIDE\workspace\Testprojekt_02\cmsis_boot 
-IC:\CooCox\CoIDE\workspace 
-IC:\CooCox\CoIDE\workspace\Testprojekt_02\cmsis_lib 
-IC:\CooCox\CoIDE\workspace\Testprojekt_02\cmsis 
-IC:\CooCox\CoIDE\workspace\Testprojekt_02\cmsis_lib\include 
C:\CooCox\CoIDE\workspace\Testprojekt_02\main.c
  Linkeraufruf:
    arm-none-eabi-gcc -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard 
-mthumb -Wall -g -nostartfiles -Wl,-Map=Testprojekt_02.map -O0 
-Wl,--gc-sections 
-LC:\CooCox\CoIDE\configuration\ProgramData\Testprojekt_02 
-Wl,-TC:\CooCox\CoIDE\configuration\ProgramData\Testprojekt_02/arm-gcc-l 
ink.ld  -g -o Testprojekt_02.elf ..\obj\startup_stm32f4xx.o 
..\obj\main.o ..\obj\stm32f4xx_rcc.o ..\obj\stm32f4xx_gpio.o 
..\obj\system_stm32f4xx.o -L..\..\.. -lm

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Dirk schrieb:
> Ich benutze 'gcc-arm-none-eabi 5.4'. Als libm.a verwende ich die aus dem
> Verzeichnis
>   \arm-none-eabi\lib\armv7e-m\fpu

GCC ist durchaus in der Lage sich die korrekte Lib selbst rauszusuchen, 
Du musst ihm aber beim Linken die Optionen für CPU und FPU mit angeben.

Mein GCC generiert da interessanten Code:
1
  22:   eef1 7ac7       vsqrt.f32       s15, s14
2
  26:   eef4 7a67       vcmp.f32        s15, s15
3
  2a:   eef1 fa10       vmrs    APSR_nzcv, fpscr
4
  2e:   d005            beq.n   3c <main+0x3c>
5
  30:   eeb0 0a47       vmov.f32        s0, s14
6
  34:   f7ff fffe       bl      0 <sqrtf>

Da wird sqrtf() offenbar für die Sonderfälle aufgerufen. Ich nehme an 
dass die Arbeitsweise der Instruktion nicht 100%ig mit der C-Definition 
für Square Root übereinstimmt.

Übrigens generert er nur die vsqrt.f32 Instruktion mit "-ffast-math".

von Dirk (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jim M. schrieb:
> GCC ist durchaus in der Lage sich die korrekte Lib selbst rauszusuchen,
> Du musst ihm aber beim Linken die Optionen für CPU und FPU mit angeben.

Was müsste ich denn dazu bei meinem Linker-Aufruf (siehe oben) ändern?


Jim M. schrieb:
> Mein GCC generiert da interessanten Code:

Arbeitest Du auch mit CooCox?
Wie sieht denn Dein Compiler-, Linkeraufruf aus?
Und welchen libm.a-Pfad benutzt Du?


Jim M. schrieb:
> Da wird sqrtf() offenbar für die Sonderfälle aufgerufen. Ich nehme an
> dass die Arbeitsweise der Instruktion nicht 100%ig mit der C-Definition
> für Square Root übereinstimmt.

Was meinst Du denn mit "Sonderfälle"?


>
> Übrigens generert er nur die vsqrt.f32 Instruktion mit "-ffast-math".

Habe ich bei CooCox unter 'Misc Controls' eingetragen und erschien dann 
auch in der Konsole beim Compileraufruf.
Hat aber leider nichts geholfen...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.