Forum: Mikrocontroller und Digitale Elektronik Benutzt hier jemand die Cortex-M4-FPU?


von Bauform B. (bauformb)


Lesenswert?

moin, moin,

wenn ich schon Floatingpoint-Hardware habe und eine geniale printf() 
gefunden habe, könnte ich die auch benutzen -- dachte ich. Das Ergebnis 
ist ein länglicher Kommentar in meinem Makefile. Es geht auch ohne bzw. 
das Preis/Leistungsverhältnis ist mir zu schlecht, das ist jetzt kein 
Problem. Aber evt. kann jemand etwas dazu sagen?
1
# DO NOT USE  CFLAGS += -march=armv7e-m+fp -mtune=cortex-m4 -mfpu=fpv4-sp-d16
2
# DO NOT USE  CFLAGS += -mfloat-abi=hard -fsingle-precision-constant
3
# DO NOT USE  # CFLAGS += -mfloat-abi=softfp -fsingle-precision-constant
4
# DO NOT USE  LDFLAGS += -lgcc
5
# DO NOT USE
6
# DO NOT USE  Mit -march=armv7e-m+fp baut der GCC FPU-Befehle auch in reine
7
# DO NOT USE  Integer-Funktionen ein. Also evt. auch in Interrupt-Routinen!
8
# DO NOT USE  Wenn die FPU per default abgeschaltet ist, wie ARM behauptet,
9
# DO NOT USE  gibt es dann einen fault.
10
# DO NOT USE  Praktisch ist sie aber nicht abgeschaltet. Damit kostet jeder
11
# DO NOT USE  Interrupt 72 Byte mehr Stack. Deshalb ist es nicht klar, ob der
12
# DO NOT USE  SVC noch funktioniert bzw. was noch alles zu beachten ist.
13
# DO NOT USE
14
# DO NOT USE  Es ist nicht praktikabel, die FPU nur in main() oder nur in
15
# DO NOT USE  genau einer task zu benutzen um Stack und Zeit zu sparen

von Programmierer (Gast)


Lesenswert?

Bauform B. schrieb:
> # DO NOT USE  Mit -march=armv7e-m+fp baut der GCC FPU-Befehle auch in
> reine
> # DO NOT USE  Integer-Funktionen ein. Also evt. auch in
> Interrupt-Routinen!

Nur wenn man ohne Optimierungen kompiliert. Du kannst die FPU auch beim 
Betreten der ISR abschalten (CPACR Register), sodass dann bei 
fälschlicher Nutzung der FPU ein Fault kommt, und du den Bug finden 
kannst. Du kannst die ISRs auch in eine separate Datei packen und diese 
ohne FPU-Nutzung kompilieren. Außerdem gibt es ja noch das Lazy Context 
Save.

Bauform B. schrieb:
> Praktisch ist sie aber nicht abgeschaltet.

Dann wird sie irgendwo in deinem Startup-Code eingeschaltet.

Ich habe die FPU schon problemlos in Cortex-M4F- und Cortex-A8-Projekten 
genutzt, auch in ISRs.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Was ist denn nun die Frage? Wie man die FPU abschaltet, oder wie man sie 
einschaltet, oder was?
Und ja, nach ein paar Compilermäkeleien und Wirrwar mit den -D Flags 
nutze ich die FPU nun.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Matthias S. schrieb:
> Was ist denn nun die Frage?

Er versteht den Kommentar im Makefile nicht. Weil er das Konzept 
"context saving" nicht verstanden hat. Und wie es mit der FPU 
zusammenhängt. Der Kommentarschreiber hatte es anscheinend auch nicht 
verstanden.

Wir haben also eine Situation, wo der Blinde dem Tauben etwas über 
Farben erzählt. Sicher nicht zielführend, aber lustig anzusehen.

von Bauform B. (bauformb)


Lesenswert?

Programmierer schrieb:
> Nur wenn man ohne Optimierungen kompiliert.
Oder mit -Os.

> Du kannst die FPU auch beim Betreten der ISR abschalten
> (CPACR Register), sodass dann bei fälschlicher Nutzung der FPU
> ein Fault kommt, und du den Bug finden kannst.
Das ist eine gute Idee für den Notfall. Aber eigentlich ist es dann 
doppelt zu spät. Einmal hat der GCC schon falschen Code erzeugt und die 
extra Bytes auf dem Stack sind schon verbraucht.

> Du kannst die ISRs auch in eine separate Datei packen und diese
> ohne FPU-Nutzung kompilieren.
Dann habe ich aber zwei verschiedene Procedure Call Standards. Das ist 
wie vom Regen in die Traufe, wer weiß, was das für Überraschungen gibt.

> Außerdem gibt es ja noch das Lazy Context Save.
Zweifellos sehr nett für zeitkritische Sachen, aber sonst ändert das 
garnichts.

> Bauform B. schrieb:
>> Praktisch ist sie aber nicht abgeschaltet.
>
> Dann wird sie irgendwo in deinem Startup-Code eingeschaltet.
Das wäre dann eine üble Nebenwirkung. Bis heute werden hier CPACR, FPCCR 
usw. nirgendwo definiert oder benutzt. Es sieht sehr danach aus, dass 
reset value eben nicht 000 ist.

> Ich habe die FPU schon problemlos in Cortex-M4F- und Cortex-A8-Projekten
> genutzt, auch in ISRs.
Naja, hier hat auch alles funktioniert, aber ich weiß nicht warum und 
wie lange. Es geht ja um Fehler, die nur sehr selten auftreten. 
Freiwillig lässt man sich darauf nicht ein.

Matthias S. schrieb:
> Und ja, nach ein paar Compilermäkeleien und Wirrwar mit den -D Flags
> nutze ich die FPU nun.
Das macht es nur noch schlimmer. Was würde mir ein -D helfen?

Axel S. schrieb:
> Er versteht den Kommentar im Makefile nicht. Weil er das Konzept
> "context saving" nicht verstanden hat. Und wie es mit der FPU
> zusammenhängt.
Egal was das ist und wie das zusammenhängt, warum sollte man die 
FPU-Register anders behandeln als alle anderen? Das heißt eben auch, 
wenn ich die FPU nur in main() benutze, muss auch nichts gerettet 
werden. r4 bis r11 werden ja auch nur bei Bedarf gerettet.

Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch 
mit float gearbeitet wird. "Natürlich" ist es nicht so einfach. 
Anscheinend kann man den context save sowieso nur zwischen lazy oder 
nicht umschalten (und nicht ganz abschalten). Also geht nur alles oder 
nichts und die FPU wird eben nicht benutzt.

> Wir haben also eine Situation, wo der Blinde dem Tauben etwas über
> Farben erzählt. Sicher nicht zielführend, aber lustig anzusehen.
:)

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Meine Antwort lautet: "ja, ich benutze die FPU".

Den Rest der Frage (war da einer?) habe ich nicht verstanden.

von Programmierer (Gast)


Lesenswert?

Bauform B. schrieb:
> Oder mit -Os.

Kannst du ein Beispiel zeigen?

Bauform B. schrieb:
> und die
> extra Bytes auf dem Stack sind schon verbraucht.

Nur wenn man das FP Context Saving eingeschaltet hat (FPCCR.ASPEN).

Bauform B. schrieb:
> Dann habe ich aber zwei verschiedene Procedure Call Standards.

Nicht wenn du -mfloat-abi=softfp nutzt. Wenn du vom Nicht-FPU-ISR-Code 
"normale" Funktionen mit potentieller FPU-Nutzung aufrufen willst, 
verlagert sich das Problem natürlich nur; der gesamte ISR-Code inkl. 
aufgerufener Funktionen müsste natürlich ohne FPU kompiliert worden 
sein. Dann sind die unterschiedlichen ABIs egal.

Bauform B. schrieb:
>> Außerdem gibt es ja noch das Lazy Context Save.
> Zweifellos sehr nett für zeitkritische Sachen, aber sonst ändert das
> garnichts.

Doch, damit kannst du gefahrlos in der ISR die FPU nutzen, und wenn du 
sie nicht nutzt, wird auch nicht unnötig gesichert.

Bauform B. schrieb:
> Es sieht sehr danach aus, dass
> reset value eben nicht 000 ist.

Dann ist da etwas sehr faul. Welcher Controller ist das? Bei z.B. den 
STM32F3 und den STM32F4 ist das nicht so.

Bauform B. schrieb:
> Es geht ja um Fehler, die nur sehr selten auftreten.
> Freiwillig lässt man sich darauf nicht ein.

Im Zweifelsfall guckt man sich das Disassembly an und sucht nach 
FPU-Instruktionen.

Bauform B. schrieb:
> Egal was das ist und wie das zusammenhängt, warum sollte man die
> FPU-Register anders behandeln als alle anderen?

Weil die alle zu Sichern lange dauert. Genau deswegen hast du ja ein 
Problem! Wenn du FPCCR.ASPEN=1 setzt werden sie automatisch bei 
ISR-Eintritt gesichert und dein Problem löst sich auf.

Bauform B. schrieb:
> Das heißt eben auch,
> wenn ich die FPU nur in main() benutze, muss auch nichts gerettet
> werden.

Korrekt. Dito wenn du sie nur in den ISRs nutzt und die nicht 
verschachteln.

Bauform B. schrieb:
> Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch
> mit float gearbeitet wird. "Natürlich" ist es nicht so einfach.

Der GCC ist halt clever genug auch andere Dinge, die von der FPU 
profitieren, auf dieser auszuführen... Am Rande: Die "NEON" Erweiterung 
der größeren ARMs kann nicht nur float, sondern auch 
Vector-Integer-Operationen, weshalb der Neon-Status hier auch von 
Integer-Operationen beeinflusst werden kann.

Bauform B. schrieb:
> Anscheinend kann man den context save sowieso nur zwischen lazy oder
> nicht umschalten (und nicht ganz abschalten). Also geht nur alles oder
> nichts und die FPU wird eben nicht benutzt.

Nö, laut ARM gibt es drei Varianten:

When an ARMv7-M processor implements the FP extension, it has three 
possible modes for stacking FP context information on taking an 
exception:
* Do not stack any FP context. The processor stacks only a Basic frame, 
as described in Operation of 8-byte stack alignment on page B1-535.
* Stack an Extended frame, containing the Basic frame and the FP state 
information, as shown in Figure B1-4 on page B1-538. This preserves the 
floating-point state required by the AAPCS.
* Reserve space on the stack for an Extended frame, but write-only the 
Basic frame information. This is similar to the operation shown in 
Figure B1-4 on page B1-538, except that no data is pushed into the stack 
locations reserved for S0 - S15 and the FPSCR value. This is an FP lazy 
context save, see Lazy context save of FP state on page B1-538.

The FPCCR.ASPEN and FPCCR.LSPEN bits determine which action is taken, 
see Floating Point Context Control Register, FPCCR on page B3-615.

von Bauform B. (bauformb)


Angehängte Dateien:

Lesenswert?

Programmierer schrieb:
> Bauform B. schrieb:
>> Oder mit -Os.
>
> Kannst du ein Beispiel zeigen?
Es passiert nur in einer Funktion und die ist praktisch "noreturn" weil 
sie  nur in einer noreturn-Funktion aufgerufen wird. Insofern darf die 
FPU hier ohne save benutzt werden. Anscheinend ist der GCC wirklich 
schlau. Ich hab' mal den obhdump angehängt, ist leider etwas sperrig. 
Übersetzt wurde das mit -Os -g -march=armv7e-m+fp -mtune=cortex-m4 
-mfpu=fpv4-sp-d16 -mfloat-abi=softfp. Mit -mfloat-abi=hard kommt 
dasselbe raus.

> Bauform B. schrieb:
>> Dann habe ich aber zwei verschiedene Procedure Call Standards.
>
> Nicht wenn du -mfloat-abi=softfp nutzt.
o.k., das wäre vernünftig, wenn nicht sogar logisch ;)

>> Es sieht sehr danach aus, dass
>> reset value eben nicht 000 ist.
>
> Dann ist da etwas sehr faul. Welcher Controller ist das? Bei z.B. den
> STM32F3 und den STM32F4 ist das nicht so.
das ist ein STM32L451, sowohl ARM als auch das PM0214 sagen: CPACR reset 
value = 0. Allerdings FPCCR.ASPEN und .LSPEN reset value = 0b11. Ich 
fasse beide Register nicht an, trotzdem funktionieren die FPU-Befehle. 
Vom FPCCR her ist das ja klar und das CPACR wird evt. vom eingebauten 
Bootloader gesetzt. Oder der Default ist bei neueren Chips 
benutzerfreundlicher? Ich lade immer nur per Bootloader ins RAM und 
starte auch auf dem Umweg.

> Im Zweifelsfall guckt man sich das Disassembly an und sucht nach
> FPU-Instruktionen.
Rein zwecks der Neugierde hab' ich das gemacht. Hätte ich vielleicht 
nicht tun sollen ;)

>> Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch
>> mit float gearbeitet wird. "Natürlich" ist es nicht so einfach.
>
> Der GCC ist halt clever genug auch andere Dinge, die von der FPU
> profitieren, auf dieser auszuführen...
Eigentlich eine gute Sache, aber kein Vorteil ohne Nachteil...

>> Anscheinend kann man den context save sowieso nur zwischen lazy oder
>> nicht umschalten (und nicht ganz abschalten).
>
> Nö, laut ARM gibt es drei Varianten:
o.k., wenn man das ganze Kapitel liest, schreibt STM letztlich doch 
dasselbe

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Bauform B. schrieb:
> Das macht es nur noch schlimmer. Was würde mir ein -D helfen?

Ich meinte natürlich Flags wie -D__FPU_PRESENT=1 oder -DARM_MATH_CM4 in 
deinem Makefile. Die fangen nun mal mit -D an.

von Programmierer (Gast)


Lesenswert?

Bauform B. schrieb:
> Anscheinend ist der GCC wirklich schlau.

Ach! Wenn ich das richtig sehe sind die einzigen FPU-Instruktionen vpush 
und vmov. Da wird anscheinend das FPU-Register s16 als zusätzliche 
Datenablage missbraucht, um aufwendigere Stack-Zugriffe zu sparen.
Dieses Register ist Callee-Save, und dementsprechend wird es von der 
Funktion gesichert. Das heißt, in diesem Fall gibt es sowieso kein 
Problem.

Bauform B. schrieb:
> trotzdem funktionieren die FPU-Befehle.

Kann es sein dass vmov und vpush trotzdem gehen?

Bauform B. schrieb:
> Oder der Default ist bei neueren Chips benutzerfreundlicher

Dann wäre es aber Stromverbrauch-unfreundlicher. Schau dir doch mal 
direkt im Reset_Handler das CPACR an.

von Axel S. (a-za-z0-9)


Lesenswert?

Bauform B. schrieb:
> Axel S. schrieb:
>> Er versteht den Kommentar im Makefile nicht. Weil er das Konzept
>> "context saving" nicht verstanden hat. Und wie es mit der FPU
>> zusammenhängt.

> Egal was das ist und wie das zusammenhängt, warum sollte man die
> FPU-Register anders behandeln als alle anderen?

Wie gesagt: du hast context saving nicht verstanden.

Der Kommentar im Makefile besagt ja nur: wenn du mit hardfloat ABI 
compilierst, dann werden die FPU Register genau so wie alle anderen 
Register behandelt und die ISR muß sie sichern. Und der Kommentator 
schreibt weiterhin, daß er es doof findet, daß das pro Interrupt so 
viele CPU-Zyklen und Stack verbrät. Ja, das kann man so sehen.

Aber nein - deswegen ganz auf die FPU zu verzichten, ist auch Unsinn.

> Das heißt eben auch,
> wenn ich die FPU nur in main() benutze, muss auch nichts gerettet
> werden.

Nur wenn der Compiler sicher weiß, daß deine ISR keine FPU Operation 
ausführen wird. Entweder direkt (im ISR Body) oder indirekt (über 
Funktionsaufrufe aus der ISR heraus).

Und weil statische Codeanalyse dafür (außer in trivialen Fällen) nicht 
ausreicht, versucht der Compiler gar nicht erst, das selber 
rauszufinden.

Du mußt dem Compiler entweder explizit verklickern "diese ISR faßt die 
FPU nicht an" oder du nutzt Tricks wie lazy FPU stacking.

von Tobias P. (hubertus)


Lesenswert?

Axel S. schrieb:
> Und der Kommentator schreibt weiterhin, daß er es doof findet, daß das
> pro Interrupt so viele CPU-Zyklen und Stack verbrät. Ja, das kann man so
> sehen.

Dann ist er ein bisschen doof, wenn er einen 32 Bit Boliden mit FPU 
verwendet und sich darüber beschwert, dass die FPU Register gesichert 
werden.
Das ist, als ob man Ferrari fährt und jammert, dass der zu viel Sprit 
braucht.

von Axel S. (a-za-z0-9)


Lesenswert?

Tobias P. schrieb:
> Axel S. schrieb:
>> Und der Kommentator schreibt weiterhin, daß er es doof findet, daß das
>> pro Interrupt so viele CPU-Zyklen und Stack verbrät. Ja, das kann man so
>> sehen.
>
> Dann ist er ein bisschen doof, wenn er einen 32 Bit Boliden mit FPU
> verwendet und sich darüber beschwert, dass die FPU Register gesichert
> werden.

Das stimmt nicht so ganz. Denn tatsächlich muß der FPU-Kontext nur dann 
gesichert werden, wenn die ISR die FPU auch benutzt. Bei einer ISR ist 
es andererseits durchaus wahrscheinlich, daß sie die FPU nicht braucht.

Das Verhalten des Compilers, den FPU Kontext einfach immer zu sichern, 
ist pessimistisch. In vielen Fällen unnötig pessimistisch. Genau 
deswegen haben Leute über das Problem nachgedacht und die bereits 
genannten Workarounds ausgeknobelt.

Wer sich allerdings auf den Standpunkt unseres TE stellt "nerv mich 
nicht mit Details, mach einfach, daß es funktioniert", der kriegt dann 
eben die langsame, sichere Variante. Keine Arme, keine Kekse!

von Programmierer (Gast)


Lesenswert?

Axel S. schrieb:
> Das Verhalten des Compilers, den FPU Kontext einfach immer zu sichern,
> ist pessimistisch.

Der Compiler sichert nie den ganzen FPU Content, sondern nur die 
Callee-Save-Register s16-s32. Die Caller-Save-Register s0-s15 sichert 
die CPU automatisch, lazy oder gar nicht, je nach Einstellung.
Man sollte also prüfen ob die ISRs direkt oder indirekt die FPU nutzen 
und dann ggf. das lazy saving aktivieren, dann ist alles in Butter. Nur 
wenn man echte Kontextwechsel für RTOS macht muss man etwas mehr 
knobeln.

Tobias P. schrieb:
> Das ist, als ob man Ferrari fährt und jammert, dass der zu viel Sprit
> braucht.

Das ist eher wie: Man fährt Ferrari und beschwert sich dass der länger 
zum Anlassen braucht. Außer bei extrem kurzen Strecken kommt man 
trotzdem schneller ans Ziel (StVO außen vor ?).

Axel S. schrieb:
> Aber nein - deswegen ganz auf die FPU zu verzichten, ist auch Unsinn.

Ganz genau! Die paar Takte Kontext Sichern sind durch die erste float 
Addition wieder rein geholt.

von Tobias P. (hubertus)


Lesenswert?

Programmierer schrieb:
> Nur wenn man echte Kontextwechsel für RTOS macht muss man etwas mehr
> knobeln.

und halt im Zweifelsfall eben alle Register sichern.
Eine FPU kostet halt auch etwas, die kommt nicht umsonst. Und wenn man 
so weit gekommen ist, dass die paar Takte zum Sichern der paar Register 
auf einem so schnellen Rechner zu Engpässen führen, dann hat man sowieso 
ein Design was auf Kante genäht ist - nicht gut. Die Zeit sollte man 
schon haben.

Aber eben - jedenfalls in meinen Projekten generiert der GCC nur dann 
Instruktionen zum Sichern der FPU-Register, wenn die auch benutzt 
werden. Fass ich in einer Funktion/ISR kein float an, sehe ich da auch 
nirgends push {s0-s15} oder ähnliches.
Nur sein push r7 streut der GCC überall hin, selbst wenn r7 nicht 
verwendet wird. Weiss der Geier wieso. Aber das stört ja nicht, bei dem 
CPU Takt können die paar ns nichts ausmachen.

von Programmierer (Gast)


Lesenswert?

Tobias P. schrieb:
> Nur sein push r7 streut der GCC überall hin, selbst wenn r7 nicht
> verwendet wird.

-fomit-frame-pointer ;-)

Tobias P. schrieb:
> Und wenn man so weit gekommen ist, dass die paar Takte zum Sichern der
> paar Register auf einem so schnellen Rechner zu Engpässen führen, dann
> hat man sowieso ein Design was auf Kante genäht ist - nicht gut.

Ja, und wenn es mit FPU und mit Sichern zu langsam ist, dann ist es ohne 
FPU definitiv zu langsam.

Tobias P. schrieb:
> Aber eben - jedenfalls in meinen Projekten generiert der GCC nur dann
> Instruktionen zum Sichern der FPU-Register, wenn die auch benutzt
> werden.

Manchmal passiert es eben doch, s.o.

von Bauform B. (bauformb)


Lesenswert?

Falls sich mal jemand mit einem FPU-Problem hierher verirrt: die 
Application Note 298 (ARM DAI0298A), "Cortex-M4(F) Lazy Stacking and 
Context Switching" ist absolut lesenswert, mit Abstand das Beste, was 
ich von ARM kenne. Einen Link gibt's leider nicht, ich hab' die mitten 
in einem Haufen FAQs gefunden.

Pauschal kann ich jetzt sagen: mit viel RAM für den Stack und ohne 
Multitasking kann man float überall benutzen, alles, auch verschachtelte 
Interrupts funktionieren automatisch optimal. Es ist auch total ok, wenn 
in reinen Integer-Funktionen FPU-Register benutzt werden. Dadurch hat 
man einfach viel mehr freie Register für lau.

Man sollte nur aufpassen, dass man nicht versehentlich double benutzt, 
dann wird's laaangsam. Dabei hilft die GCC-Option 
-fsingle-precision-constant. Und man muss die FPU per SCB->CPACR 
einschalten:

Bauform B. schrieb:
> Wenn die FPU per default abgeschaltet ist, wie ARM behauptet,
> gibt es dann einen fault.
> Praktisch ist sie aber nicht abgeschaltet.
Programmierer schrieb:
> Schau dir doch mal direkt im Reset_Handler das CPACR an.

Wenn ich in der crt0 als erstes das CPACR ins RAM kopiere, sind die 
cp10- und cp11-Bits
 * nicht gesetzt, wenn das Programm normal aus dem Flash startet; dann 
gibt es einen "Usage fault, No coprocessor".
 * gesetzt, wenn ich das Programm mit dem eingebauten UART-Bootloader 
ins RAM lade und starte.
In der AN2606 heißt es
1
Note: If you choose to execute the Go command, the peripheral registers
2
      used by the bootloader are not initialized to their default reset
3
      values before jumping to the user application. They should be
4
      reconfigured in the user application if they are used.
Also passen Manual und Wirklichkeit zusammen. Wozu ein Bootloader die 
FPU braucht will man garnicht wissen, aber sie sei ihm gegönnt ;)


Multitasking funktioniert auch automatisch, solange man float nur in 
einer Task benutzt und diese getrennt mit -march=armv7e-m+fp übersetzt. 
Der ganze Rest muss mit -march=armv7e-m übersetzt werden. Wer mehr will, 
findet die Lösungen in der o.g. AN298. Aber aufpassen: Mit FPU braucht 
man 108 statt 36 Byte Stack, für SVC und 2 geschachtelte Interrupts also 
324 Byte nur für gerettete Register. Der Platz wird oft garnicht 
gebraucht, aber immer reserviert.


Das Preis/Leistungsverhältnis von printf("%f",float) ist leider extrem 
schlecht. Wegen der varargs muss float als double übergeben werden, d.h, 
es wird nur für den Aufruf float->double->float per Software 
konvertiert. Das dauert, kostet viel Platz und man braucht nur dafür die 
libgcc. Dagegen hilft etwas wie
print_float (const char *format, float value).


Mit der GCC-Option -mfloat-abi=softfp werden für die Parameterübergabe 
nur r0 bis r3 benutzt, auch für float. Mit -mfloat-abi=hard wird float 
in FPU-Registern übergeben, man hat viel mehr freie Register. softfp 
scheint mir eine Notlösung für fremde libs zu sein.

von Programmierer (Gast)


Lesenswert?

Bauform B. schrieb:
> mit Abstand das Beste, was ich von ARM kenne.

Kennst du was schlechtes von ARM? Die ganze Doku ist extrem präzise, 
vollständig und eindeutig. Da können sich die IC-Hersteller wie ST oder 
TI noch ein paar ganze Laibe von abschneiden...

Bauform B. schrieb:
> Dabei hilft die GCC-Option -fsingle-precision-constant

Oder immer 'f' an die Literale dran schreiben. Dann ist's portabler.

Bauform B. schrieb:
> Also passen Manual und Wirklichkeit zusammen.

Ach!

Bauform B. schrieb:
> softfp scheint mir eine Notlösung für fremde libs zu sein.

Das ist nützlich wenn man eine Menge Software von verschiedensten 
Herstellern auf verschiedenen Plattformen nutzt. Daher wird das z.B. bei 
Android verwendet. Libraries können einfach komplett mit Soft FP 
kompiliert werden (wenn sie wenig float nutzen), oder dynamisch 
entscheiden Soft oder Hard Float zu verwenden (für mehr number 
crunching), aber das ABI bleibt immer gleich.

Fun fact: Der Linux Kernel hat Funktionen für Software Integer Division, 
und prüft beim Hochfahren ob der Prozessor Hardware Integer Division 
kann (udiv/sdiv). Falls ja, werden diese Funktionen mit dieser 
Instruktion überschrieben (Self Modifying Code).

von John Doe (Gast)


Lesenswert?

Bauform B. schrieb:
> Falls sich mal jemand mit einem FPU-Problem hierher verirrt: die
> Application Note 298 (ARM DAI0298A), "Cortex-M4(F) Lazy Stacking and
> Context Switching" ist absolut lesenswert, mit Abstand das Beste, was
> ich von ARM kenne. Einen Link gibt's leider nicht, ich hab' die mitten
> in einem Haufen FAQs gefunden.


http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/DAFGGBJD.html

von Seppel V. (seppelv)


Lesenswert?

Hallo,

momentan versuche ich mich in das Thema einzuarbeiten, aber ich suche 
ein Dokument das auch die Grundlagen erklärt, vor allem die Intention 
der Teilung in Caller/Callee-Register(S0..S15 und S16..S31).

*Lazy Stacking:*

Soweit ich es verstehe wird durch das Lazy-Stacking bei einem 
Kontext-Wechsel auf dem Stack der Platz für S0..S15 reserviert. Wenn der 
Kontext in den gewechselt wird die FPU verwendet, werden in diesen 
reservierten Bereich die Register S0..S15 gesichert. Bei einem 
zurück-wechseln werden S0..S15 wieder hergestellt. Dies funktioniert bei 
verschachtelten Kontextwechseln und funktioniert unabhängig von der 
Verschachtelungstiefe.

Was ich nicht verstanden habe, wann S16—S31 verwendet werden und warum 
nennen sich diese Caller/Callee-Register, was ist die Intention, und 
wann wird das zum Sichern verwendet? Wie werden S16..S31 von der FPU 
generell verwendet?

*Automatic Stacking:*

Zum „Automatic Stacking“ oder „Eagerly-Stacking“ das in z.B. der ST 
AN4044 erwähnt wird, fehlt mir Dokumentation, ich weiß nicht was das ist 
und wie es funktioniert. Da fehlt mir eine Definition und eine 
Funktions/Implementierungsbeschreibung.

Vielen Dank.

Grüße, Seppel

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Seppel V. schrieb:
> fehlt mir Dokumentation

Versuch durch mal durch die Dokumentation von ARM durchzuwühlen:
- 
https://developer.arm.com/documentation/#q=stacking&cf[navigationhierarchiesproducts]=IP%20Products,Processors,Cortex-M,Cortex-M4

Ansonsten mit konkreten Fragen besser einen neuen Thread eröffnen...

von Stefan F. (Gast)


Lesenswert?

Dafür hat er inzwischen einen neuen Thread eröffnet. Ein Thread zum 
Thema genügt. Lass und hier abbrechen und dort weiter machen.
Beitrag "ARM M4F FPU: "Lazy stacking" und "Automatic stacking""

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.