Chinaunix首页 | 论坛 | 博客
  • 博客访问: 241059
  • 博文数量: 27
  • 博客积分: 358
  • 博客等级: 一等列兵
  • 技术积分: 291
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-25 17:35
文章分类

全部博文(27)

文章存档

2015年(1)

2014年(4)

2013年(6)

2012年(4)

2011年(12)

分类: 嵌入式

2011-04-28 15:09:30

环境:Windows7 旗舰版;Keil MDK-ARM V4.20
前段时间使用了KEIL开发cortex-M4系列的ARM,在我的上篇日志中说明了如何在KEIL中开启cortex-M4的DSP浮点运算单元(见http://blog.chinaunix.net/space.php?uid=7921647&do=blog&id=267417)。这篇日志写一下keil下的最小启动代码,用以搭建一个最小的C语言环境,写在这里以备以后查看。
新建一个KEIL工程,ARM选择cortex-m4(带DSP运算单元),整个工程主要包括3个文件:head.s main.c start.sct
①head.s 启动文件,汇编代码
  1. IMPORT main
  2. AREA startup,CODE
  3. THUMB
  4. DCD 0x20000000 ;MSP,主堆栈起始地址,注意是向下增长
  5. DCD reset ;复位地址,复位后PC被赋予这个值
  6. reset PROC
  7. ENTRY
  8. ; CPACR is located at address 0xE000ED88
  9. LDR.W R0, =0xE000ED88
  10. ; Read CPACR
  11. LDR R1, [R0]
  12. ; Set bits 20-23 to enable CP10 and CP11 coprocessors
  13. ORR R1, R1, #(0xF << 20)
  14. ; Write back the modified value to the CPACR
  15. STR R1, [R0] ;上面的这一段是开启硬件浮点运算DSP,否则后面如果出现硬件浮点代码会fault
  16. LDR R0,=main ;获取main函数的地址
  17. BL main ;跳转到main执行
  18. B .
  19. ENDP
  20. END
上面的这个启动代码非常简单,只是用来测试用,没有实用价值。实际上代码所在的区域应该用来填写中断向量的(如果不重定向中断向量表的话)。

②main.c C程序测试代码
  1. int main()
  2. {
  3.     float a=1;
  4.     float b=1;
  5.     float c;
  6.     c=a*b;
  7.     return (int)c;
  8. }
这段代码使用了float,可以用来测试cortex-m4的DSP运算单元。

③分散加载文件start.sct
  1. ROMLOAD 0x0 0x4000
  2. {
  3. EXEC_RO 0x0
  4. {
  5. head.o(startup, +first)
  6. *(+RO)
  7. }
  8. RAM 0x1FFF8000
  9. {
  10. *(+RW,+ZI)
  11. }
  12. }

工程的设置中,只更改了linker选项,在Misc controls中增加了“-o start.axf --no_startup”选项,所以,等效的linker命令行就是(--cpu Cortex-M4.fp *.o --strict --scatter "start.sct"  -o start.axf --no_startup),括号中的内容,不包括括号。这里有个--no_startup需要说明一下,在不添加这个选项时,Keil会“自作聪明”的在生成的汇编代码中添加一些代码,这些代码也许是我们并不想要的,所以增加这个--no_startup选项后就不再有这些代码了。


最终生成的汇编代码如下所示:
  1. 0x00000000 0000 MOVS r0,r0
  2. 0x00000002 2000 MOVS r0,#0x00
  3. 0x00000004 0009 MOVS r1,r1
  4. 0x00000006 0000 MOVS r0,r0
  5. reset:
  6. 0x00000008 F8DF0010 LDR.W r0,[pc,#16] ; @0x0000001C
  7. 0x0000000C 6801 LDR r1,[r0,#0x00]
  8. 0x0000000E F4410170 ORR r1,r1,#0xF00000
  9. 0x00000012 6001 STR r1,[r0,#0x00]
  10. 0x00000014 4802 LDR r0,[pc,#8] ; @0x00000020
  11. 0x00000016 F000F805 BL.W main (0x00000024)
  12. 0x0000001A E7FE B 0x0000001A
  13. 0x0000001C ED88E000 STC P0,C14,[r8,#0x00]
  14. 0x00000020 0025 MOVS r5,r4
  15. 0x00000022 0000 MOVS r0,r0
  16. main:
  17. 0x00000024 EEF71A00 VMOV.F32 s3,#0x3F800000
  18. 0x00000028 EEB00A61 VMOV.F32 s0,s3
  19. 0x0000002C EEF71A00 VMOV.F32 s3,#0x3F800000
  20. 0x00000030 EEF00A61 VMOV.F32 s1,s3
  21. 0x00000034 EE601A20 VMUL.F32 s3,s0,s1
  22. 0x00000038 EEB01A61 VMOV.F32 s2,s3
  23. 0x0000003C EEFD1AC1 VCVT.S32.F32 s3,s2
  24. 0x00000040 EE110A90 VMOV r0,s3
  25. 0x00000044 4770 BX lr
从生成的汇编代码可以看到,代码非常简洁了,没有出现我们不想要的代码;而且浮点运算使用的是硬件代码,形如VMOV.F32 s3,#0x3F800000
阅读(6362) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~