Ich schreibe etwas Code für ein Stellaris Launchpad-Board von Texas Instruments (ein Cortex-M4F, der Chip ist ein LM4F120H5QR ). Ich verwende die IRMP- Bibliothek für die Infrarot-Decodierung, die gut funktioniert, solange ich keine Gleitkomma-Mathematik außerhalb ihrer ISR verwende. Nur eine einzige Operation wie in
MAP_SysCtlDelay((MAP_SysCtlClockGet())/ 30.0);
bricht die IRMP-Bibliothek. Der Chip läuft noch, IRMP ruft alle benötigten Funktionen auf, UART-Übertragungen funktionieren, aber IRMP kann keinen Infrarot-Empfang mehr entschlüsseln.
Ganz oben in meiner main
Funktion habe ich:
// Enable FPU
MAP_FPULazyStackingEnable();
MAP_FPUEnable ();
Wenn ich diese Zeilen auskommentiere, bleibt die Software tatsächlich während der Initialisierung hängen.
Ich habe verschiedene Varianten dieser FPU-Aktivierungsfunktionen (ROM_, MAP_, FPUStackingEnable, FPULazyEnable) ausprobiert, aber nichts scheint das Problem zu beheben.
Die letzten 4 Stunden des Googelns haben sich als nutzlos erwiesen, also hatte ich gehofft, hier eine Antwort zu finden.
Bearbeiten: Mehr Verrücktheit: Wenn ich mit -O0 kompiliere, dekodiert IRMP auch nichts. Sobald ich die Optimierungen auf O1 oder höher stelle, funktioniert es wieder (sofern außerhalb der Timer-ISR-Routine und der von ihr aufgerufenen Funktionen keine Gleitkomma-Arithmetik stattfindet).
Oh, und falls es hilft, arm-none-eabi-gcc --version
gibt:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305]
Ich kompiliere mit den folgenden Optionen:
-DPART_LM4F120H5QR -DARM_MATH_CM4 -DTARGET_IS_BLIZZARD_RA1 -I$SOMEDIR/stellarisware
-Os -Wall -std=gnu99 -c -fmessage-length=0 -fsingle-precision-constant -mcpu=cortex-m4
-mfpu=fpv4-sp-d16 -mthumb -mfloat-abi=softfp -ffunction-sections -fdata-sections
Bearbeiten 2: Ich sollte hinzufügen, dass im IRMP-Code keine tatsächlichen Gleitkommaberechnungen stattfinden. Das heißt: Alle Variablen sind ganze Zahlen. Es gibt jedoch viele Definitionen, die Zwischenfloaten sind, z.
#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5)
uint16_t
Diese Konstanten werden im eigentlichen Code mit anderen Typen verglichen . Ich bin mir nicht ganz sicher, warum dies FP-Arithmetik im Laufzeitcode erfordert, es sind alles feste Werte, die in Ganzzahlen gefaltet werden können.
Warum versuchen Sie nicht, alle Gleitkommaberechnungen aus den Interrupt-Service-Routinen zu entfernen? Viele Leute würden darauf hinweisen, dass es überhaupt nicht dort sein sollte.
Berechnen Sie Gleitkomma-Dinge im Hauptcodefluss vor, sodass sie nicht in der ISR sein müssen. Dies erfordert möglicherweise ein Überdenken der verwendeten Algorithmen, führt jedoch häufig zu robusterem und schlankerem Code.
PeterJ
A VH
A VH
A VH
Michael Karas
Michael Karas
A VH
A VH
A VH