Estoy escribiendo algo de código para una placa Stellaris Launchpad de Texas Instruments (un Cortex-M4F, el chip es un LM4F120H5QR ). Estoy usando la biblioteca IRMP para la decodificación infrarroja, que funciona bien, siempre y cuando no use ningún punto flotante Matemáticas fuera de su ISR. Solo una operación como en
MAP_SysCtlDelay((MAP_SysCtlClockGet())/ 30.0);
rompe la biblioteca IRMP. El chip aún se ejecuta, IRMP llama a todas sus funciones requeridas, las transmisiones de UART funcionan, pero IRMP ya no puede decodificar ninguna recepción de infrarrojos.
En la parte superior de mi función main
tengo:
// Enable FPU
MAP_FPULazyStackingEnable();
MAP_FPUEnable ();
De hecho, si comento esas líneas, el software simplemente se bloquea durante la inicialización.
He probado varios sabores de esas funciones habilitadoras de FPU (ROM_, MAP_, FPUStackingEnable, FPULazyEnable), pero nada parece solucionar el problema.
Las últimas 4 horas de Google han resultado inútiles, por lo que esperaba encontrar una respuesta aquí.
Editar: Más rarezas: si compilo con -O0, IRMP tampoco descodifica nada. Tan pronto como establezco las optimizaciones en O1 o superior, comienza a funcionar nuevamente (siempre que no se realicen operaciones aritméticas de punto flotante fuera de la rutina ISR del temporizador y las funciones a las que llama).
Ah, y en caso de que ayude, arm-none-eabi-gcc --version
da:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305]
Estoy compilando con las siguientes opciones:
-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
Edición 2: Debo agregar que no se realizan cálculos de punto flotante en el código IRMP. Es decir: todas las variables son enteros. Sin embargo, hay muchas definiciones que son flotadores intermedios, por ejemplo:
#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5)
Estas constantes se comparan con otros tipos uint16_t
en el código real. No estoy muy seguro de por qué esto requiere aritmética FP en el código de tiempo de ejecución, todos los valores fijos se pueden plegar en enteros.