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
Gucke dir doch einfach den compilierten Assembler Code an. Ich behaupte mal ja sofern du hardware float im Compiler aktiviert hast
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.
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.
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.
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.
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
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).
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?
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?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.