Chinaunix首页 | 黑桃棋牌官方网下载 | 博客
  • 博客访问: 12009
  • 博文数量: 1
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2019-06-10 16:35
  • 文章分类
    文章存档

    2019年(1)

    我的朋友
    最近访客

    分类: 嵌入式

    2019-06-10 16:36:31

    以前曾经使用GNU的 arm-linux-* 工具链在命令行模式下写过ARM的代码,前段时间安装了Keil的mdk-arm 开发工具,心血来潮想试试在命令行下能不能开发ARM,结果成功了。我所测试的代码非常简单,只是一个实验,具有实用价值的代码没有测试过。
    当然,如果有了图形界面的IDE再使用命令行开发,是多此一举、舍近求远了,这只是个人爱好吧。
    我的环境:
    windows7旗舰版;Keil arm-mdk V4.2;Cygwin(已经安好了make等基本工具)
    模拟开发的器件是arm最近推出的cortex-m4(带DSP处理单元).

    整个工程只包含4个文件:启动文件head.s、C文件main.c、分散加载文件start.sctMakefile。下面是各个文件的内容。

    head.s
    1.      1          IMPORT main
    2.      2          AREA startup,CODE
    3.      3          THUMB
    4.      4          DCD 0x20000000
    5.      5          DCD reset

    6.      6  reset   PROC
    7.      7          ENTRY
    8.      8          ; CPACR is located at address 0xE000ED88
    9.      9          LDR.W R0, =0xE000ED88
    10.     10          ; Read CPACR
    11.     11          LDR R1, [R0]
    12.     12          ; Set bits 20-23 to enable CP10 and CP11 coprocessors
    13.     13          ORR R1, R1, #(0xF << 20)
    14.     14          ; Write back the modified value to the CPACR
    15.     15          STR R1, [R0]

    16.     16          push {r0-r1}

    17.     17          LDR R0,=main
    18.     18          BL main
    19.     19          B .
    20.     20          ENDP
    21.     21          ALIGN
    22.     22          END
    其中的第8-15行是开启FPU处理单元的代码(针对有FPU的处理器),第16行用来测试堆栈的情况;第6行和第20行的PROC、ENDP告诉编译器这是个执行程序段(以便编译器在编译时把跳转地址的bit 0变为单数,例如第5行变成reset所在的地址+1,这是因为cortex-m4只支持thumb代码,在向thumb代码跳转时PC地址bit0必须为1)。

    main.c
    1.      1 int main()
    2.      2 {
    3.      3 float a=3.14159;
    4.      4 float b=2.987;
    5.      5 float c;
    6.      6 c=a*b*b;
    7.      7 return (int)c;
    8.      8 }
    这里使用了浮点运算,以测试是否能正确编译浮点运算为FPU的硬件指令。

    start.sct
    1. 1 ROMLOAD 0x0 0x4000
    2. 2 {
    3. 3 EXEC_RO 0x0
    4. 4 {
    5. 5 head.o(startup, +first)
    6. 6 *(+RO)
    7. 7
    8. 8 }
    9. 9 RAM 0x1FFF8000
    10. 10 {
    11. 11 *(+RW,+ZI)
    12. 12 }
    13. 13 }
    分散加载文件,把启动代码放到最开始。

    Makefile
    1. 1 main.bin:main.c head.s
    2. 2 armcc --cpu cortex-m4.fp -O0 --apcs=interwork --li -g -c -I "C:\Keil\ARM\CMSIS\Include" main.c -o main.o
    3. 3 armasm --cpu cortex-m4.fp --li --apcs=interwork -I "C:\Keil\ARM\CMSIS\Include" head.s -o head.o
    4. 4 armlink --cpu cortex-m4.fp --no_startup --libpath "C:\Keil\ARM\RV31\LIB" --scatter start.sct head.o main.o -o main.axf
    5. 5 fromelf --bin --output main.bin main.axf
    6. 6 fromelf main.axf -c|sed -n '/Section #1/,$$p'|sed '/Section #2/,$$d'>_main.list
    7. 7 #dos2unix _main.list
    8. 8 clean:
    9. 9 rm *.o *.axf *.list *.bin
    第4行这里有个--no_startup需要说明一下,在不添加这个选项时,Keil会“自作聪明”的在生成的汇编代码中添加一些代码,这些代码也许是我们并不想要的,所以增加这个--no_startup选项后就不再有这些代码了。第6行后面的sed是从调试信息中过滤出我们所需要看的部分,其它的被滤除。

    四个文件都具备后,在当前目录下执行make指令(会有两个警告信息,可以忽略),便可生成main.axf的调试映像了,可以在keil中调试;_main.list是生成的反汇编代码,内容如下:
    1. ** Section #1 'EXEC_RO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    2.         Size   : 88 bytes (alignment 4)
    3.         Address: 0x00000000

    4.         $d
    5.         startup
    6.                 0x00000000:     20000000        ... DCD    536870912
    7.                 0x00000004:     00000009        .... DCD     9
    8.         $t
    9.         $v0
    10.         reset
    11.                 0x00000008:     f8df0014        .... LDR.W   r0,[pc,#20] ; [0x20] = 0xe000ed88
    12.                 0x0000000c:     6801            .h LDR     r1,[r0,#0]
    13.                 0x0000000e:     f4410170        A.p.    ORR       r1,r1,#0xf00000
    14.                 0x00000012:     6001            .` STR     r1,[r0,#0]
    15.                 0x00000014:     b403            .. PUSH   {r0,r1}
    16.                 0x00000016:     4803            .H LDR     r0,[pc,#12] ; [0x24] = 0x29
    17.                 0x00000018:     f000f806        .... BL         main ; 0x28
    18.                 0x0000001c:     e7fe            .. B             0x1c ; reset + 20
    19.         $d
    20.                 0x0000001e:     0000            .. DCW   0
    21.                 0x00000020:     e000ed88        .... DCD     3758157192
    22.                 0x00000024:     00000029        )... DCD     41
    23.         $t
    24.         .text
    25.         main
    26.                 0x00000028:     eddf1a09        ....    VLDR     s3,[pc,#36] ; [0x50] = 0x40490fd0
    27.                 0x0000002c:     eef00a61        ..a.    VMOV.F32 s1,s3
    28.                 0x00000030:     eddf1a08        ....    VLDR     s3,[pc,#32] ; [0x54] = 0x403f2b02
    29.                 0x00000034:     eeb00a61        ..a.    VMOV.F32 s0,s3
    30.                 0x00000038:     ee601a80        `...    VMUL.F32 s3,s1,s0
    31.                 0x0000003c:     ee611a80        a...    VMUL.F32 s3,s3,s0
    32.                 0x00000040:     eeb01a61        ..a.    VMOV.F32 s2,s3
    33.                 0x00000044:     eefd1ac1        ....    VCVT.S32.F32 s3,s2
    34.                 0x00000048:     ee110a90        ....    VMOV     r0,s3
    35.                 0x0000004c:     4770            pG BX       lr
    36.         $d
    37.                 0x0000004e:     0000            .. DCW   0
    38.                 0x00000050:     40490fd0        ..I@    DCD     1078530000
    39.                 0x00000054:     403f2b02        .+?@    DCD     1077881602


    阅读(10929) | 评论(0) | 转发(0) |
    0

    上一篇:没有了

    下一篇:没有了

    给主人留下些什么吧!~~
    评论热议
    请登录后评论。

    登录 注册