problemas de FPU Cortex-M4F

5

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.

    
pregunta Darhuuk

1 respuesta

5

¿Por qué no intenta eliminar todos los cálculos de punto flotante de las rutinas del servicio de interrupción? Muchas personas señalarían que no debería estar allí en primer lugar.

Pre-calcule cosas de punto flotante en el flujo de código de la línea principal para que no sea necesario que esté en el ISR. Esto puede requerir un replanteamiento de los algoritmos utilizados, pero a menudo conducirá a un código más robusto y ágil.

    
respondido por el Michael Karas

Lea otras preguntas en las etiquetas