[原创] M4之浮点运算单元FPU个人总结!!!!!!!!!!!!!!!!!!!!!!!!

Linchpin   2014-11-29 11:25 楼主
最近一直在纠结M4的浮点运算单元该怎么开启,为何语句里配置了(FPUEnable();FPULazyStackingEnable();)跟没配置程序运行速度是一个样的,有幸得到坛友指点,才解决了这个问题。
下面说一下开启FPU的方法:
首先,需要在编译器上开启FPU功能。CCS:默认为开启状态。可以在propertise——bulid——arm compiler——processor options 里的specify floating point support里配置,默认为FPv4SPD16 ,即开启状态。
其次,需要在代码里加上这两句 FPUEnable();FPULazyStackingEnable();(最好加在main函数入口处,具体原因我也不清楚。)

那面下面来讨论下这几种情况:
1.编译器未开启FPU,代码里配置了FPU。程序还是会按照未使能FPU的代码进行处理。
2.编译器开启FPU,代码里未配置FPU。如果代码中带有单精度浮点(注意是单精度)运算的代码,编译器就会使用带V的FPU单元汇编指令,无论芯片是否开启了FPU单元功能。除非用户在代码中关闭FPU功能(FPUDiable语句),那么程序执行就会出现错误,进入FaultISR;

所以我们平时写的程序只要用到了浮点运算,即使没有在代码中配置FPU,就如上面情况2所说的,默认是使用FPU功能的。。所以根本就不需要我们刻意去开启了。
还有一点要注意的是浮点运算单元只适用于单精度浮点(Float型)的运算,而对于double型就不管用。要是你语句中有 a=a*1.2 这样的语句,这个1.2系统是默认定义为double型的,运算时按double型进行运算,再把结果转化成float,所以应写成 a=a*1.2f(将1.2定义为float型) 才行。


以上为本人个人愚见,如有错误,望各位大大指点!

回复评论 (14)

a,b,c,d均为float型 这样一段代码用时12.8秒 for(i=0;i<500000;i++) { a=a+1234.56789; b=a*9876.54321/1234.56789; c=b/a; d=a*b*c*1.222; } 而如果我将代码改成这样,用时1秒 for(i=0;i<500000;i++) { a=a+1234.56789f; b=a*9876.54321f/1234.56789f; c=b/a; d=a*b*c*1.222f; } 本帖最后由 Linchpin 于 2014-11-29 11:34 编辑
点赞  2014-11-29 11:32
非常好的总结
    懒得很
点赞  2014-11-29 12:08
写得不错,最近移植UCOSII的时候正不知道ccs中怎么处理FPU有关的问题,官方只有M4在keil和IAR部分的内容。看到这知道了应该在os_cpu_a,asm中写上 .if __TI_FPV4SPD16_SUPPORT__ = 1就和keil中IF {FPU} != "SoftVFP"及IAR中的#ifdef __ARMVFP__一样来获取编译器的配置情况决定是否编译和FPU堆栈有关的代码。 补充一下楼主说的第二种情况。以CCS为例,当编译器使能了fpu选项后在运行到主函数前的启动代码栏有这么一段
  1. _c_int00: .asmfunc
  2. .if !__TI_ARM_V7M__ & !__TI_ARM_V6M0__
  3. .if __TI_NEON_SUPPORT__ | __TI_VFP_SUPPORT__
  4. ;*------------------------------------------------------
  5. ;* SETUP PRIVILEGED AND USER MODE ACCESS TO COPROCESSORS
  6. ;* 10 AND 11, REQUIRED TO ENABLE NEON/VFP
  7. ;* COPROCESSOR ACCESS CONTROL REG
  8. ;* BITS [23:22] - CP11, [21:20] - CP10
  9. ;* SET TO 0b11 TO ENABLE USER AND PRIV MODE ACCESS
  10. ;*------------------------------------------------------
  11. MRC p15,#0x0,r0,c1,c0,#2
  12. MOV r3,#0xf00000
  13. ORR r0,r0,r3
  14. MCR p15,#0x0,r0,c1,c0,#2
即一旦检查到编译器使能了FPU,则会将CPACR寄存器中的CP11、CP10置为11,以便程序能在特权级和用户级两种模式下使用FPU的协处理器,这相当与函数FPUEnable()干的事,而FPULazyStackingEnable()用于设置寄存器FPCCR的ASPEN为和LSPEN位为1,以启动中断发生时与FPU相关的寄存器的压栈特性,但这个位复位值就是为1。所以在编译器设置了FPU的情况下即使不调用这两个函数,编译器也能够产生汇编指令,并不会发生错误。 本帖最后由 鬼眼刀道 于 2014-11-29 17:25 编辑
点赞  2014-11-29 15:04
非常不错  学习了
点赞  2014-11-29 20:43
很好的总结!
点赞  2014-11-30 12:28
很好的总结
点赞  2015-3-11 09:56
引用: 鬼眼刀道 发表于 2014-11-29 15:04
写得不错,最近移植UCOSII的时候正不知道ccs中怎么处理FPU有关的问题,官方只有M4在keil和IAR部分的内容 ...

您所说的官方文档是什么?有链接么?
点赞  2016-1-14 22:15
引用: ztyhalo 发表于 2016-1-14 22:15
您所说的官方文档是什么?有链接么?

挖了个老坟,这个就是micrium官网给的关于tiva的移植模版,印象中应该只有IAR和keil的,没有ccs的,所以移植起来不是很方便。现在还好了,因为ti出了msp432也是M4内核的,它的移植模版有ccs平台的,拿过来参考一下应该差不多。链接的话在这:http://micrium.com/downloadcenter/
点赞  2016-1-15 12:50
引用: 鬼眼刀道 发表于 2016-1-15 12:50
挖了个老坟,这个就是micrium官网给的关于tiva的移植模版,印象中应该只有IAR和keil的,没有ccs的,所以 ...

谢谢你了!!!!!
点赞  2016-1-16 21:44
非常有价值的经验,本人之前也在Keil中使能了FPU,但计算耗时和不使用FPU一样,原来是要加一个'f',学习了。谢谢!!!!
点赞  2016-4-11 23:44
楼主很棒  参考了!!
点赞  2016-4-20 01:07
msp432 UCOSII  还是无法用浮点运算,求解?
点赞  2016-6-15 15:22
芯币怎么获得
点赞  2016-7-14 13:20
校友,您好!
淡泊明志 宁静致远
点赞  2017-7-26 21:26
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复