您的位置 首页 IC

SAM4E单片机之旅——23、在AS6(GCC)中运用FPU

浮点单元(FloatingPointUnit,FPU),是用于处理浮点数运算的单元。为使用FPU,除了需要启用FPU外,还需要对编译器进行设置,以使其针对浮点运算生成特殊的指令。虽然在Atme

  浮点单元(Floating Point Unit,FPU),是用于处理浮点数运算的单元。

  为运用FPU,除了需求启用FPU外,还需求对编译器进行设置,以使其针对浮点运算生成特别的指令。虽然在Atmel Studio 6中,开发板运用的工程模板中默许就完结了这两部分作业,但这次依然对设置的办法进行介绍,一起简略测验一下FPU的功率。

  一、 编译器设置

  AS6.1 SP2中,运用的编译器为arm-none-eabi-gcc.exe,版别为4.7.3。其间“none”表明没有指定操作系统,“eabi”表明运用的二进制文件接口是eabi。

  在ARM GCC中,能够运用-mfloat-abi选项设置浮点数的ABI:

  soft: 调用软浮点库对浮点运算进行支撑。在GCC中选用常用的指令来模仿浮点运算。

  softfp: 运用FPU进行浮点数运算。可是在函数调用时,依然运用通用的寄存器传递浮点数参数。这需求额定的类型转化的开支。

  hard: 运用FPU进行浮点数运算。并且在函数调用时,运用FPU的寄存器传递浮点数参数。

  AS6.1运用的编译器,默许情况下即运用soft选项。而为了运用FPU,这儿将运用softfp选项。

  运用-mfpu选项设置FPU硬件的类型。

  SAM4E搭载了Cortex-M4F FPU,它完结了FPv4-SP版别(SP表明单精度)的浮点数扩展。别的,它也搭载了32个32位的单精度寄存器,而这些寄存器也能够被当作16个64位的双精度寄存器以进行load,store和move操作。

  所以需求将-mfpu赋值为fpv4-sp-d16。其间d16表明有16个64位寄存器。

  AS6中的设置。

  在解决方案管理器中,右键点击工程,进入特点页面。然后选中“Toolchain”选项卡,再挑选“ARM/GUN C Complier”下的“Miscellaneous”选项,就能够看到自界说的编译器的选项了。

  能够看到,默许情况下现已追加了“-mfloat-abi=softfp -mfpu=vfpv4”的选项了。vfpv4默许表明vfpv4-D32,表明完结了彻底的FPV4的版别,且配有32个64位寄存器。很明显,这是一个不怎么正确的设置,所以需求更改为“-mfloat-abi=softfp -mfpu= fpv4-sp-d16”:

image

 

  留意,在Release版别的装备中也需求进行修正。

  二、 启用FPU

  开发板重置时,FPU是制止拜访的。可是AS6中运用的startup文件会依据编译器设置启用FPU。

  启用FPU的办法

  向FPU的CPACR寄存器的CP10和CP11字段写入0b11即可敞开FPU的彻底拜访权限。别的,在特权形式下才干读写该寄存器。

  在CMSIS中该寄存器的地址被界说成了保存地址。可是在fpu.h 中供给了相应的API:

  #include // 会和sam.h的宏界说抵触,运用board.h即可

  fpu_enable();

  fpu_enable() 的完结如下:

  /** CPACR寄存器 */

  #define ADDR_CPACR 0xE000ED88

  #define REG_CPACR (*((volatile uint32_t *)ADDR_CPACR))

  /** 保存CPU当时中止的状况,并屏蔽之 */

  irqflags_t flags;

  flags = cpu_irq_save();

  /** 修正CPACR寄存器*/

  REG_CPACR |= (0xFu << 20);

  __DSB(); /** 等候寄存器修正完结*/

  __ISB(); /** 清空处理器流水线 */

  /** 依据设置决议是否从头启用中止 */

  cpu_irq_restore(flags);

  AS6中现已完结的作业

  开发板运用的AS6的工程模板中,程序的进口函数是Reset_Handler() 。

  该函数在调用main() 函数之前,会履行以下代码:

  #if __FPU_USED

  fpu_enable();

  #endif

  __FPU_USED在以下代码中界说:

//…

  /* 判别运用的编译器是否为GCC */

  #elif defined ( __GNUC__ )

  /* 判别是否启用浮点运算,且运算不是用软件完结的 */

  #if defined (__VFP_FP__) && !defined(__SOFTFP__)

  /* 判别方针渠道是否有FPU */

  #if (__FPU_PRESENT == 1)

  #define __FPU_USED 1

  #else

  //…

  __FPU_PRESENT 在sam4e16e.h 中界说:

  /**< SAM4E16E does provide a FPU */

  #define __FPU_PRESENT 1

  所以,只需求设置好了编译器的参数,就能够主动启用FPU了。

  PS:__GNUC__ 在GCC编译器预界说的宏,__VFP_FP__ 在GCC启用浮点运算时预界说,__SOFTFP__ 是运用软模仿浮点运算时预界说。GCC能够运用“-dM –E”参数打印出预界说的宏。

  三、 测验

  在第一次示例教程中,咱们运用了空循环来进行延时,来完结LED的闪耀作业。在这儿,咱们将这个空循环的循环体修正为对一个浮点数的运算。然后调查在是否运用硬件FPU时,LED闪耀的频率的不同。

  将延时函数修正如下:

  void Delay(int num)

  {

  volatile float f = 1.0f;

  for (volatile int i = 0; i < 1024 * 64 * num; ++i )

  f *= 1.1f;

  }

  然后别离运用“-mfloat-abi=softfp ”和“-mfloat-abi=soft ”选项编译并履行程序,调查LED闪耀的频率。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/203528.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部