工业控制 | 能源技术 | 汽车电子 | 通信网络 | 安防监控 | 智能电网 | 移动手持 | 无线技术 | 家用电器 | 数字广播 | 消费电子 | 应用软件 | 其他方案

电路设计->综合电路图->综合电路图->Cortex-M4 FPU浮点运算解析

Cortex-M4 FPU浮点运算解析

作者:angelazhang时间:2015-11-18

   近年,在Cortex-M3之后ARM公司又推出Cortex-M4内核,和之前的M3内核的区别之一就是M4带了一个单精度浮点运算单元(FPU)。本文就Silicon Labs M4  FPU单元进行一个简单介绍,帮助工程师更快的理解FPU单元。


1、Cortex-M系列内核指令集
从ARM公司发布的白皮书看,Cortex-M系列内核的指令集如下图所示:

  从图上可以看出,Cortex-M系列的指令是向下兼容的,M0/M1的指令最少,M0/M1和M3的指令都使用于M4的芯片。Silicon Labs Corttex-M4的指令集分两部分,一部分是在M3的指令集外增加了一些扩展功能。另一部分即上图中红色部分,就是用于FPU单元的单精度浮点运算指令。这部分指令都是用V-开头的汇编指令,仅在FPU功能被使能时使用。


       需要注意的是FPU单元是指的芯片上的一个独立于CPU处理的浮点运算单元整个单元在大多厂家芯片中都是可以被使能和关闭的。相对于芯片,编译器也设置了相应的FPU功能开启/关闭的选项,在编译时需要告诉编译器是否开启FPU功能。汇编器一旦开启FPU功能,在处理单精度浮点运算的语句时就会带V-开头的汇编指令进行编译。


       如果编译器使能了FPU功能,而芯片未开启FPU单元,程序运行到浮点语句时就会出现异常。相反,如果编译器未能使能FPU功能,芯片即使开启了FPU单元,程序还是会按照未使能FPU的代码进行处理。


2.编译器中的FPU功能使能
      以KEIL为例,在创建一个Cortex-M4的工程后,在工程的Options for target “xxx”窗口的Target页面中选择是否开启FPU功能。如下图所示:


编译器通过该选项来判断是否使用V-开头的浮点运算指令。


        一旦选择了“use FPU”功能,如果代码中有单精度浮点运算的代码,编译器就会使能带V-的FPU单元汇编指令,无论芯片是否开启了FPU单元功能。如果选择了不使用FPU功能,即使芯片开启了FPU单元,编译器一样不会采用带V-的汇编指令。


3.例程分析
      下面用一个实例来分析开启、关闭FPU单元的程序处理。
001. static float fDat1  = 0.0; 
002. static float fDat2  = 0.01;  
003. //****************************************** 
004. // fpu test.  
005. //****************************************** 
006. int main(void) 
007. {  
008.     int i;  
009.     FPUEnable();  
010.     FPUStackingEnable(); 
011.     for (i = 0; i <100; i++) 
012.     {  
013.         fDat1 = fDat1 + fDat2; 
014.     } 
015.  }
其中011.~014. 行在开启编译器FPU功能后,编译出来的代码为:  
MOVS        r0, #0x00 
VLDR        s0, [r1,#0x04] 
VLDR     s1, [r1,#0x00] 
ADDS     r0, r0, #1 
CMP      r0, #0x64 
VADD.F32 s1,s1,s0  
VSTR         s1, [r1, #0x00] 
BLF          0x00000316  
其中红色标注的都是以V-开头的汇编代码,这些代码在FPU单元中运行。

如果关闭编译器的FPU功能,编译出来的代码如下:  
MOVS     r4, #0x00 
LDR         r6, [r5,#0x04] 
LDR         r0, [r5, #0x00] 
MOV         r1, r6  
BL.W         __aeabi_fadd(0x0000029C) 
ADDS     r4, r4, #1  
STR         r0, [r5, #0x00] 
CMP         r4, #0x64 
BLT         0x00000430  
其中红色标注部分是程序执行浮点加法运算的部分,调用了单精度浮点运算的库函数。



评论

技术专区