在学习Cotex-A架构的I.MX6ULL时,可以开启浮点运算单元FPU。其原理是通过附带的协处理器CP15实现。
1、ARMv7-A 协处理器
ARMv7-A 处理器除了标准的 R0~R15,CPSR,SPSR 以外,由于引入了 MMU、TLB、Cache 等内容,ARMv7-A 使用协处理器来对这些扩展来进行管理,ARMv7-A 支持 16 个协处理器,编号从 CP0~CP15,其中的 CP15 协处理器称之为系统控制协处理器,CP15 协处理器下的寄存器包含了 MMU、TLB、Cache等关键组件,其余的 CP0~CP14 有的控制Debug功能,有的控制 SIMD,有的控制浮点。
/*
* @description : 使能I.MX6U的硬件NEON和FPU
* @param : 无
* @return : 无
*/
void imx6ul_hardfpu_enable(void)
{
uint32_t cpacr;
uint32_t fpexc;
/* 使能 NEON 和 FPU */
cpacr = __get_CPACR();
cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk)) |
(3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
__set_CPACR(cpacr);
fpexc = __get_FPEXC();
fpexc |= 0x40000000UL;
__set_FPEXC(fpexc);
}
并且在编译指令中加入:-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard
,用于指定编译浮点运算的时候使用硬件FPU。
像 51单片机和 STM32F1系列都没有硬件FPU,因此想用浮点运算需要引入<math.h>
库,需要占用 CPU运算,因此运算很长。其原理是替换成汇编的时会用非浮点指令替代,但是又能够完成正确的浮点操作。
ARM的浮点数计算貌似没那么简单,背后的原理还挺复杂的,还涉及到gcc编译指令,暂时挖个坑,之后来填!