GCC float in ISR & stacking

Gast #5269853
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
#5269949
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.
Gast #5269973
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.
Gast #5269979
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.
#5269996
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.
Gast #5271936
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).
Gast #5271938
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?
Gast #5271944
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?
#5271980
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.
#5272784
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren