Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Pueden funcionar la fpu y la cpu stm32 f4 al mismo tiempo?

¿Pueden funcionar la fpu y la cpu stm32 f4 al mismo tiempo?

Sí.

Hoy en día, aquellos con FPU o capacidades informáticas de punto flotante de hardware incluyen principalmente DSP de alta gama (como TI F28335/C6000/DM6XX/OMAP, etc.), CPU de uso general (coprocesador matemático X87) y dispositivos avanzados de procesamiento ARM+DSP, etc.

STM32-F4 pertenece a la arquitectura Cortex-M4F. La mayor diferencia con M0 y M3 es que tiene un F-float adicional, que admite conjuntos de instrucciones de punto flotante, por lo que puede manejar operaciones matemáticas mejor que. M0/M3 El rendimiento es docenas o incluso cientos de veces mayor, pero para aprovechar al máximo el rendimiento matemático de la FPU, se requieren algunas pequeñas configuraciones:

1. Opciones de control de compilación: aunque las rutinas. de la biblioteca de firmware STM32F4XX son system_stm32f4XXX El código correspondiente se agrega al archivo .c, pero no se incluye en la rutina STM32F4-Discovery para la evaluación del usuario. Por lo tanto, al escribir un programa de operación de punto flotante en MDK4.23, aunque el. El compilador genera correctamente la instrucción V para realizar operaciones de punto flotante. Sin embargo, debido a que el archivo system_stm32f4XXX.c no habilita la FPU, la CPU solo piensa que encuentra una instrucción ilegal y salta a la interrupción HardFault_Handler() durante la ejecución. Por lo tanto, para garantizar que este error no ocurra, se debe agregar el siguiente código a la función system_init():

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

SCB ->CPACR |= ((3UL << 10*2)|(3UL << 11*2));

#endif

Porque esta opción está controlada por compilación condicional, por lo que debe agregar la siguiente declaración a la pestaña Definir de C/C++ en las opciones del proyecto (Proyecto->Opciones para el destino "XXXX"): __FPU_PRESENT=1,__FPU_USED =1. De esta manera, el código para iniciar la FPU se agrega durante la compilación y la CPU puede usar la FPU de manera correcta y eficiente para realizar sumas, restas, multiplicaciones y divisiones simples.

Pero esto no es suficiente. Para operaciones complejas, como funciones trigonométricas, raíz cuadrada y otras operaciones, si aún usa el archivo de encabezado math.h al programar, no mejorará la eficiencia: debido a que el archivo de encabezado math.h es para todos los procesadores ARM, sus funciones de operación Se basa en CPU de punto fijo y algoritmo estándar (IEEE-754), y no prevé el uso de FPU. Requiere muchas instrucciones y procesos complejos para completar el cálculo, lo que aumenta el tiempo de cálculo. Por lo tanto, para utilizar completamente la función de punto flotante de M4F, debe usar arm_math.h que viene con la biblioteca de firmware. Este archivo determina qué método de función usar según el elemento de control de compilación (__FPU_USED == 1): si el. No se usa FPU, entonces simplemente llame a la función definida en el archivo de encabezado math.h estándar de keil. Si usa FPU, use la función de optimización que viene con la biblioteca de firmware para resolver el problema.

Hay esta información de control de compilación al comienzo de arm_math:

#ifndef _ARM_MATH_H

#define _ARM_MATH_H

#define __CMSIS_GENERIC

#si está definido (ARM_MATH_CM4)

#incluye "core_cm4.h"

#elif está definido (ARM_MATH_CM3)

#incluye "core_cm3 .h"

#elif definido (ARM_MATH_CM0)

#include "core_cm0.h"

#else

#include "ARMCM4 .h"

#warning "Defina ARM_MATH_CM4 O ARM_MATH_CM3... De forma predeterminada, basándose en ARM_MATH_CM4....."

#endif

#undef __CMSIS_GENERIC

#include "string.h"

#include "math.h"

Es decir, si no usas CMSIS, usarás llame a las funciones de biblioteca estándar propias de keil. De lo contrario, se utiliza la definición CMSIS. Debido a que aquí se usa STM32F4, se debe requerir el control ARM_MATH_CM4, es decir, se agrega core_cm4.h; de lo contrario, se usa ARMCM4.h, pero durante la compilación, keil le indicará que no se puede encontrar este archivo. Por lo tanto, debe continuar agregando la declaración ARM_MATH_CM4 para definirla en la pestaña C/C++ de las opciones del proyecto.

Después de agregar los elementos de control de compilación anteriores, el uso de funciones matemáticas avanzadas básicamente no es un problema, como el cálculo de funciones trigonométricas seno y coseno. Pero debe tenerse en cuenta que si usa directamente funciones como sin (), cos () y sqrt (), el resultado seguirá siendo una llamada a keil's math.h. Puede ver el código correspondiente durante la depuración. La instrucción es BL. Por lo tanto, para completar el cálculo de funciones trigonométricas en este momento, se debe utilizar arm_sin_f32() o arm_cos_f32(). El uso permanece sin cambios. Los prototipos de estas dos funciones se encuentran en arm_sin_f32.c y arm_cos_f32.c respectivamente. El valor preciso de la función en cualquier ángulo se obtiene consultando la tabla de funciones trigonométricas de 256 puntos y el algoritmo de interpolación, que es mucho más rápido que el sin() y el cos() "originales".

Por supuesto, existen algunas excepciones a la función de desarrollo sqrt(), que se define en arm_math.h:

static __INLINE arm_status arm_sqrt_f32(float32_t in, float32_t *pOut)

{

si(en > 0)

{

// #if __FPU_USED

#if ( __FPU_USED = = 1) && definido ( __CC_ARM )

*pOut = __sqrtf(in);

#else

*pOut = sqrtf(in);

#endif

return (ARM_MATH_SUCCESS);

}

else

{

* pOut = 0.0f;

return (ARM_MATH_ARGUMENT_ERROR);

}

}

La función utilizada para la raíz cuadrada es arm_sqrt_f32 (), que primero determina si el libro desarrollado es mayor que 0. Solo se pueden operar aquellos mayores que 0; de lo contrario, el resultado de salida es 0 y se devuelve un indicador de "error". Si es mayor que 0 y se utilizan los elementos de control FPU y __CC_ARM, llame a __sqrtf() para completar la compilación; de lo contrario, llame a sqrtf(); este sqrtf() se puede encontrar en math.h de keil, es decir, llame la subfunción para completar la operación, y ¿qué pasa con __sqrtf()? Creo que todos pueden adivinar qué hay de nuevo: sí, ¡es el comando VSQRT! Por lo tanto, para poner en práctica este rendimiento, debe continuar agregando la declaración __CC_ARM a la definición de la pestaña C/C++ en las opciones del proyecto. Puede comparar la diferencia en el código ensamblador después de agregar __CC_ARM o no.

Por supuesto, todavía hay algunos problemas con la función arm_sqrt_f32(). Si confirma que el libro que se prescribe es mayor o igual a 0, utilice directamente la función __sqrtf() para completar la operación. , que es una instrucción VSQRT simple.

La biblioteca de firmware STM32F4 también proporciona otras funciones matemáticas útiles, todas ubicadas en la carpeta DSP_Lib. ¡Explore lentamente y descubra!