Forum: Compiler & IDEs GCC float in ISR & stacking


von Chester (Gast)


Lesenswert?

Hallo,

ich habe einem STM32F407 mit FPU und arbeite mit dem GCC.
Sowohl in der ISR als auch im Hauptprogramm möchte ich float benutzen.
Nun muss die ISR bei float ja zusätzliche Register der FPU stacken. 
Macht das der GCC schon von sich, oder muss man das von Hand machen?

Chester

von Timmo H. (masterfx)


Lesenswert?

Gucke dir doch einfach den compilierten Assembler Code an. Ich behaupte 
mal ja sofern du hardware float im Compiler aktiviert hast

von Martin B. (ratazong)


Lesenswert?

Habe die selbe Frage.

Der GCC stellt sich ziemlich intelligent an, wenn er in den Interrupt 
läuft. Er pusht nur die Register, die er auch braucht.
Bei mir pusht er aber keine floating point Register in den interrupt 
routinen. (habe mir die assembler outputs angeschaut)

Ich vermute, dass Du das per Hand machen musst. Ich wüsste das aber auch 
zu gerne. Die Fehler, die auftreten können sind halt beschissen. Hatte 
das Problem mal auf dem PC im Interrupt. Fiel wochenlang nicht auf, dass 
matlab, excel und co manchmal komisch rechnen.

Beim Keil Compiler soll man das Verhalten optionen steuern können. 
Vielleicht gibt es auch für den GCC so etwas.

von Dr. Sommer (Gast)


Lesenswert?

Es muss entweder das Bit FPCCR.ASPEN auf 1 gesetzt werden (der Prozessor 
sichert die FPU Register bei jedem Exception Eintritt) oder das Bit 
FPCCR.LSPEN (der Prozessor sichert die Register im Interrupt erst dann, 
wenn eine FPU-Instruktion genutzt wird). Siehe Kapitel B1.5.7, S. 533 im 
ARMv7M Architecture Reference Manual. Der Compiler hat damit nichts zu 
tun.

von Chester (Gast)


Lesenswert?

Ich seh eigentlich nicht, dass die Register zB. S14,S15 irgendwo 
gestackt werden. Aber ich hab zum Test auch mal in der Main im Kreis 
floats berechnet während die Interrupts kräftig ebenfalls auf die 
Register zugreifen und es treten erst mal keine Rechenfehler auf. Ist 
aber kein Beweis.

von Martin B. (ratazong)


Lesenswert?

Dr. Sommer schrieb:
> Es muss entweder das Bit FPCCR.ASPEN auf 1 gesetzt werden (der Prozessor
> sichert die FPU Register bei jedem Exception Eintritt) oder das Bit
> FPCCR.LSPEN (der Prozessor sichert die Register im Interrupt erst dann,
> wenn eine FPU-Instruktion genutzt wird). Siehe Kapitel B1.5.7, S. 533 im
> ARMv7M Architecture Reference Manual. Der Compiler hat damit nichts zu
> tun.

Danke,

das ist doch jetzt mal eine Information. Werde ich bei Gelegenheit mal 
testen.

von ich (Gast)


Lesenswert?

Da der GCC nicht weiß wann der Interrupt kommt, kann er auch keine 
Register pushen; Dass macht die Hardware automatisch.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Babefdjc.html

von Dr. Sommer (Gast)


Lesenswert?

ich schrieb:
> Da der GCC nicht weiß wann der Interrupt kommt, kann er auch keine
> Register pushen;

Er tut es am Anfang der ISR. Aber nur bei den Registern bei denen es 
nötig ist, nämlich die "Callee-Safe" Register, also r4-r12 und s16-s31 
(IIRC). Beim Rest macht's die Hardware (FPU Register nur falls 
aktiviert).

von ich (Gast)


Lesenswert?

Hm, interessant

woher weiß der GCC, dass die Funktion in Wirklichkeit ein Interrupt ist? 
Die address der Funktion wird doch nur in der Vector-Table hinterlegt 
und nicht mit einer Art "interrupt" Markierung versehen?

von ich (Gast)


Lesenswert?

Kann es sein das der GCC beim Funktionsaufruf erstmal nur R1-R3 sichert, 
dann in die Funktion springt und dann noch R4-R11 sichert?

Wenn die Funktion als Interrupt aufgerufen wird sichert die Hardware 
R1-R3 und die Funktion R4-R11?

von Markus F. (mfro)


Lesenswert?

ich schrieb:
> Hm, interessant
>
> woher weiß der GCC, dass die Funktion in Wirklichkeit ein Interrupt ist?
>

Gar nicht.

Die Hardware sorgt dafür, dass bei einer Exception genau die Register 
(automatisch) gesichert (und danach wiederhergestellt) werden, die ein 
"normaler" Caller auch sichern und restoren würde. Man kann also ohne 
Nachdenken "ganz normale" C-Funktionen als Interrupt-Handler benutzen.

Alles was man dazu tun muss, ist dem µC einmal zu erklären, ob man 
gedenkt, die FPU zu nutzen oder nicht.

von Christopher J. (christopher_j23)


Lesenswert?

ich schrieb:
> Wenn die Funktion als Interrupt aufgerufen wird sichert die Hardware
> R1-R3 und die Funktion R4-R11?

Der Caller (die aufrufende Funktion) sichert immer R0-R3, R12, LR, PC 
und xPSR. Ist der Caller eine normale Funktion kümmert die sich um das 
Stacking und im Falle eines IRQs macht es eben die Hardware. Nutzt der 
Callee (also die aufgerufene Funktion) über die automatisch gestackten 
Register hinaus noch weitere Register (R4-R11), so werden die 
entsprechend zu Beginn der Funktion vom Callee gesichert. Mit den 
FPU-Registern verhält es sich wie von Dr. Sommer geschildert (siehe auch 
"The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors" Kap.8, 
S.273-286). Speziell zum Stacking beim M4F gibt es auch von ARM eine 
AppNote: 
https://static.docs.arm.com/dai0298/a/DAI0298A_cortex_m4f_lazy_stacking_and_context_switching.pdf

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.