From: http://blog.renren.com/blog/256814551/844695191
Floating Point operation has been a fixed point CPU problems, such as a simple 1.1 + 1.1, fixed point CPU must follow the IEEE-754 standard algorithm to complete the operation, for 8-bit single chip microcomputer has been a nightmare, for 32 single-chip microcomputer, there will not be much improvement. Although the Q-based processing of floating point numbers can give full play to the operational performance of 32-bit single-chip microcomputer, the accuracy is limited and not too high. For single-chip microcomputer or CPU with FPU (floating point unit), floating point addition is just a few instructions.
At present, FPU or hardware floating point computing capabilities mainly include high-end DSPs (such as Ti f28335/C6000/dm6xx/OMAP) and general-purpose CPU (x87 mathematical co-processor) and advanced ARM + DSP processors.
STM32-F4 belongs to the Cortex-M4F architecture, which is the biggest difference with M0, M3 is an F-float, that is, the floating point instruction set, therefore, when processing mathematical operations, the performance is dozens or even hundreds of times higher than that of M0/m3. However, to fully utilize the mathematical performance of FPU, you still need some small settings:
1. compile control option: although the corresponding code is added to the system_stm32f4xxx.c file of the stm32f4xx Firmware Library, but it is not in the STM32F4-Discovery routine used for user evaluation, so when mdk4.23 writes a floating point computation program, although the compiler correctly generates the V command for floating-point operations, the FPU is not enabled in the system_stm32f4xxx.c file. Therefore, when the CPU is executed, it is regarded as an invalid command and the jump to hardfault_handler () is interrupted. Therefore, to ensure that this error does not occur, you must add the following code in the system_init () function:
/* FPU settings ------------------------------------------------------------*/
# If (_ fpu_present = 1) & (_ fpu_used = 1)
SCB-> cpacr | = (3ul <10*2) | (3ul <11*2);/* Set cp10 and cp11 full access */
# Endif
This option has Conditional compilation control, so you need to select the project option (Project-> options for target "XXXX ") in the C/C ++ tab, add the following statement to define: __fpu_present = 1 ,__ fpu_used = 1. In this way, the code for starting FPU is added during compilation, and the CPU can use FPU correctly and efficiently for simple addition, subtraction, multiplication, division, and so on.
However, this is far from enough. For complex operations, such as trigonometric functions and operators, if math is used for programming. h header file, which cannot improve efficiency: Because math. h header file is for all arm processors, its operation function is based on fixed point CPU and standard algorithm (IEEE-754), and does not foresee the use of FPU, it takes a lot of instructions and complex processes to complete the operation, which increases the operation time. Therefore, to make full use of the m4f floating point function, you need to use the arm_math.h that comes with the Firmware Library. This file is based on the Compilation control items (_ fpu_used = 1) to determine which function method to use: If FPU is not used, then the standard math of Keil is called. h: The function defined in the header file. If FPU is used, the optimized function provided by the Firmware Library is used to solve the problem.
The compilation control information is available at the beginning of arm_math:
# Ifndef _ arm_math_h
# DEFINE _ arm_math_h
# DEFINE _ cmsis_generic/* disable between C and between ick functions */
# If defined (arm_math_cm4)
# Include "core_cm4.h"
# Elif defined (arm_math_cm3)
# Include "core_cm3.h"
# Elif defined (arm_math_cm0)
# Include "core_cm0.h"
# Else
# Include "armcm4.h"
# Warning "define either arm_math_cm4 or arm_math_cm3... by default building on arm_math_cm4 ....."
# Endif
# UNDEF _ cmsis_generic/* enable functions C and feature ick functions */
# Include "string. H"
# Include "math. H"
That is to say, if cmsis is not used, the standard library function provided by Keil will be called. Otherwise, use the definition of cmsis. In this case, because objective F4 is used, arm_math_cm4 should be used for control, that is, core_cm4.h should be added; otherwise, armcm4.h should be used -- but during compilation, Keil will prompt that this file cannot be found. Therefore, you must add the statement arm_math_cm4 in the define of the C/C ++ tab of the project option.
After the above compilation control items are added, the use of advanced mathematical functions is basically no problem, such as the calculation of positive cosine trigonometric functions. However, if you directly use functions such as sin (), cos (), and SQRT (), the result is still the math of Keil. h. You can view the corresponding code in debug. The Assembly command is BL. W _ hardfp_xxx. Therefore, arm_sin_f32 () or arm_cos_f32 () is used to complete the trigonometric function calculation. The usage of these two functions remains unchanged. The prototypes are respectively in arm_sin_f32.c and arm_cos_f32.c. The exact function values from any angle are obtained through the query and interpolation algorithms of the 256-point trigonometric function table, which is much faster than the original sin () and cos.
Of course, some exceptions are the development function SQRT (), which is defined in arm_math.h as follows:
Static _ inline arm_status arm_sqrt_f32 (float32_t in, float32_t * pout)
{
If (in> 0)
{
// # If _ fpu_used
# If (_ fpu_used = 1) & defined (_ cc_arm)
* Pout = _ sqrtf (in );
# Else
* Pout = sqrtf (in );
# Endif
Return (arm_math_success );
}
Else
{
* Pout = 0.0f;
Return (arm_math_argument_error );
}
}
That is, the function used by the open party is arm_sqrt_f32 (). First, judge whether the developed book is greater than 0. Only those greater than 0 can be used for calculation, otherwise, the output result is 0 and the "error" flag is returned. If the value is greater than 0 and FPU and _ cc_arm control items are used, call _ sqrtf () to complete compilation; otherwise, call sqrtf () -- This sqrtf () is a math that can be used in Keil. h, that is, the subfunction is called to complete the operation. What about _ sqrtf? I believe everyone can guess what it is: yes, it is the vsqrt command! Therefore, to achieve this performance, you need to add the statement _ cc_arm to the define on the C/C ++ tab of the project option. You can compare whether the differences between compiled code after _ cc_arm is added.
Of course, the arm_sqrt_f32 () function is still troublesome. If you confirm that the book to be opened is greater than or equal to 0, use the _ sqrtf () function to complete the operation, that is, a simple vsqrt command.
The ikef4 Firmware Library also provides other useful mathematical functions in the dsp_lib folder!