cn_x 发表于 2014-9-3 16:34:12

【分享】Kinetis中使用硬件浮点——转帖

在KEIL中使用MDK-ARM开发cortex-m4
最近在学习ARM公司新推出的cortex-m4系列的ARM芯片,选用的是飞思卡尔的K60系列,它采用的就是cortex-m4核心。cortex-m4比cortex-m3多了个dsp处理单元。增加了dsp单元的优势是显而易见的:在涉及到大量的数学运算时可以采用dsp来处理,大大节约了运算时间和代码量。(K60的浮点运算单元是个可选的部件,由于我拿到的K60还不支持FPU,所以下面涉及到的浮点调试只能用仿真的方式进行)
最新的KEIL MDK-ARM开发环境已经增加了对cortex-m4的支持(我是用的是MDK-ARM Standard Version 4.20),包括仿真支持,也就是说即使你没有拿到开发板也可以来学习cortex-m4. 在器件选择中,这个版本已经增加了飞思卡尔K60系列,在新建工程时可以选择(我选择了Freescale Semiconductor--MK60X256VMD100这个器件)。下面写一下我自己的学习过程。

一、不使用K60的浮点运算单元。
在默认情况下,K60的浮点单元并没有被打开,一切浮点运算还是软件浮点。
①打开Keil uVision4,新建工程,选择保存路径,选择器件,找到Freescale Semiconductor,展开,在最下面选择MK60X256VMD100。程序问你是否添加这个系列的启动代码到工程中,选择 是(如果没有出现这个选项,可以自己在Keil的安装目录里找,自己添加,其路径为C:\Keil\ARM\Startup\Freescale\K60)。这时一个新的工程就建好了,默认增加了startup_MK60N512MD100.s这个启动文件。
②测试浮点运算。我们可以新建一个C文件,用来测试浮点运算使用的是软浮点还是硬浮点。新建c文件里的代码可以如下:
int main(void)
{
    float a=3.14259265357,b=12.98635463738,result;
    result=a*b*b;
    return result;
      }

extern void SystemInit(void)
{
    int a=1;
    while(a) a--;
}
其中void SystemInit(void)这个函数是为了满足启动文件startup_MK60N512MD100.s中对SystemInit的调用,本来是对器件的初始化,这里只是做测试用,没有实际内容。(如果要得到完整的系统初始化函数,可以到Keil路径C:\Keil\ARM\Startup\Freescale\K60下找到system_MK60N512MD100.c,K60的头文件可以去Keil官方下载:http://www.keil.com/dd/chip/5359.htm)。然后全部编译,进入调试状态,这里默认进入的是仿真调试。
在生成的汇编代码中我们可以看到以下内容:
0x000002B0 E92D41F0PUSH          {r4-r8,lr}
   3:         float a=3.14259265357,b=12.98635463738,result;
0x000002B4 480D      LDR         r0,; @0x000002EC
0x000002B6 4604      MOV         r4,r0
0x000002B8 480D      LDR         r0,; @0x000002F0
0x000002BA 4605      MOV         r5,r0
   4:         result=a*b*b;
0x000002BC 4629      MOV         r1,r5
0x000002BE 4620      MOV         r0,r4
0x000002C0 F000F8A6BL.W          _fmul (0x00000410)

可以看到,生成的汇编代码并没有使用浮点指令(一般是以V打头),进行乘法运算是调用在0x00000410处的_fmul函数来实现的,找到_fmul这个函数,可以发现进行浮点运算是用软件模拟的方式。

二、使用K60的浮点运算单元。
对于内部有浮点运算单元的K60,不使用FPU就是一种资源浪费,所以要开启它。由于默认并没有开启FPU运算,所以这里还有点小小的麻烦。
退出调试状态,在菜单中选择file--Device Database...,打开器件数据库,找到 Freescale Semiconductor--MK60X256VMD100 双击,在Options:中第一行后面添加空格,后面加入FPU2,这一行的最后变为CPUTYPE("Cortex-M4") ESEL ELITTLE FPU2,点击Update,再点击close关闭。 这样这个器件就修改好了。(注:为了防止把数据库中的器件搞乱,可以自己新建一个分类,增加一个器件,把K60这个器件的内容统统拷进这个新建的器件里,再在这个器件里面修改其属性)
器件修改完以后,可以再新建一个Keil工程,跟前面一样,选择被修改过的K60,添加启动代码,添加上面的main函数。这时我们可以打开工程属性窗口,看里面的设置:
Project--Options for Target 'Target1'...(或者直接按Alt+F7),在Target选项卡中,在Code Generation区域可以找到Floating Point Hardware下拉框,默认选择了Use FPU.
工作还没有完成,cortex-m4在默认状态下寄存器并没有打开浮点运算,还要修改启动代码。在Reset_Handler函数中,找到 LDR   R0, =__main 这个代码,在前面加入这几行:
; CPACR is located at address 0xE000ED88LDR.W R0, =0xE000ED88; Read CPACRLDR R1, ; Set bits 20-23 to enable CP10 and CP11 coprocessorsORR R1, R1, #(0xF << 20); Write back the modified value to the CPACRSTR R1,
上面这段代码设定寄存器开启了浮点运算单元,否则在执行浮点运算代码时会发生HardFault。
重新编译,进入调试状态,这时可以发现生成的汇编代码跟原来的不一样了:
   3:         float a=3.14259265357,b=12.98635463738,result;
0x000002B0 EDDF1A0EVLDR          s3,
0x000002B4 EEF00A61VMOV.F32      s1,s3
0x000002B8 EDDF1A0DVLDR          s3,
0x000002BC EEB00A61VMOV.F32      s0,s3
   4:         result=a*b*b;
0x000002C0 EE601A80VMUL.F32      s3,s1,s0
0x000002C4 EE611A80VMUL.F32      s3,s3,s0
0x000002C8 EEB01A61VMOV.F32      s2,s3

所有的浮点运算都是调用的硬件浮点运算指令,在Register观察窗口中也多了个FPU寄存器列表。

wangpengcheng 发表于 2014-9-3 16:35:12

哥,你太强悍了!好吧,我承认我水了!

wanstrive 发表于 2014-9-3 16:39:43

好吧。。。。太扎实太认真了。。。。。M0,M0+都不带FPU的......

cn_x 发表于 2014-9-3 16:40:42

wangpengcheng 发表于 2014-9-3 16:35
哥,你太强悍了!好吧,我承认我水了!

持续分享中············

湛泸骏驰 发表于 2014-9-3 16:56:20

{:lol:}{:lol:}楼主加油分享

huangzzjy22 发表于 2014-9-3 17:01:08

是不是我也该出手了

holts2 发表于 2014-9-3 17:06:53

只玩M0,想都不要想

zwei99999999 发表于 2014-9-3 17:47:47

谢谢楼主               

laotui 发表于 2014-9-3 17:51:44

楼主太高端了,看看。

zndz410 发表于 2014-9-3 17:56:34

谢谢楼主分亨。

fengyunyu 发表于 2014-9-3 18:00:43

LZ分享精神可敬

lzl000 发表于 2014-9-3 18:01:36

楼主到底有多少库存啊,分享的数不胜数啊

cn_x 发表于 2014-9-3 18:18:17

lzl000 发表于 2014-9-3 18:01
楼主到底有多少库存啊,分享的数不胜数啊

谷歌一下什么都有了

cn_x 发表于 2014-9-3 18:23:12

huangzzjy22 发表于 2014-9-3 17:01
是不是我也该出手了

该出手时就出手啊

wxfje 发表于 2014-9-3 21:29:43

还没玩过M4呢,有机会好好玩下

rockyyangyang 发表于 2014-9-3 21:42:40

顶一个            

zhaotyue 发表于 2014-9-18 08:23:01

请问一下,IAR该如何设置呢?!

32MCU 发表于 2014-9-18 09:05:12

收藏备用。

luckner 发表于 2014-9-21 09:20:06

谢谢楼主分享煭낧想知道这个DSP单元运算能力如何

太阳哥 发表于 2014-9-21 09:33:59

fpu在加上官网的dsp库,运算德提升还是很明显的

xjmlfm1 发表于 2014-9-21 10:29:07

楼主应该再做个对比,做1000次乘加运算,看开FPU和不开FPU的差别有多大,时间分别是多少。
页: [1]
查看完整版本: 【分享】Kinetis中使用硬件浮点——转帖