Linux下arm裸机开发环境搭建与实例

来源:互联网 发布:js时间戳转换成天数 编辑:程序博客网 时间:2024/04/30 16:19

好文章,先mark一下,转自:http://blog.csdn.net/chenqiai0/article/details/8539481


折腾了很长时间,总算是弄明白怎么在linux编译运行arm裸机程序了。编译运行arm裸机程序可以考虑用arm工具链搭建编译环境,由minicom和dnw来下载程序,至于调试,还没有去耐心研究,着急来这里先备份一下,免得时间久了,忘记怎么回事。

首先是arm工具链,arm工具链的编译我就不写了,一方面很麻烦,另一方面是这方面的资料网上已经有很多了,我就不在这里多言浪费大家时间了。我这里有自己编译的arm工具链,当然,用网上现成的也不是不可以,但是最好是自己熟悉过程,免得必要的时候不会从源码配置。我将工具链上传到空间,如果需要,尽管拿去,链接地址为,使用说明看资源备注:

http://download.csdn.net/detail/girlkoo/3689485

这样,就可以开发普通的arm裸机程序了,现在开发环境是有了,编写可以编译通过的代码很是容易,但是编写真正运行正常的却不那么简单,因此,烧录工具还是必要的,我推荐是用minicom和dnw,minicom模拟与windows下的超级终端有相同的功能,这样就可以像windows下开发环境一样与vivi对话了,另外,我在网上下来多个dnw和dnw2,但是发现dnw2在某些情况下不是很稳定,当然也有听说的成分,不管怎么说,就是个工具,不管哪个,用着顺手就行,我用的是dnw,也可能是我点背,下载的几个dnw烧录大的镜像可以,但是烧录自己开发的程序,只有二三百K的小文件却老是出错,还好linux下是开放源码的,于是我就修改了一番,当然,限于水平因素,可能曲解了原作者的意图,不过巧合的是烧录小文件正常了,大的文件也可以,或许你用的时候并没有这个问题,那么请您使用原版的dnw,指出小弟缺点,如果不幸弄巧成拙求诸位不要喷我,下面是我修改后的dnw源码及使用说明,下载地址是:

http://download.csdn.net/detail/girlkoo/3689525

配置好上面两个工具后就可以开发arm2440的裸机程序了,当然移植系统可能还会用到其他牛B的工具,等用到再去研究,如果有幸小弟弄明白了,还会来这里记录下来的,下面附上两个linux下的arm裸机程序及makefile,感觉对我这样的新手来说还是有帮助的。

例子1:汇编文件led_on.S,代码如下,这里我想告诉大家的是GNU的汇编跟标准的arm汇编是有出入的,具体的大家可以搜索“linux arm 汇编”来学习了解,网友给我们提供了足够丰富的资源。

[html] view plaincopy
  1. .text 
  2. .global _start 
  3. _start: 
  4.     ldr r0,=0x56000010 
  5.     ldr r1,=0x00155555 
  6.     str r1,[r0] 
  7.     ldr r0,=0x56000014 
  8.     mov r1,#0x0 
  9.     str r1,[r0] 
  10. MAIN_LOOP: 
  11.     b MAIN_LOOP 
[html] view plaincopy
  1. .text  
  2. .global _start  
  3. _start:  
  4.     ldr r0,=0x56000010  
  5.     ldr r1,=0x00155555  
  6.     str r1,[r0]  
  7.     ldr r0,=0x56000014  
  8.     mov r1,#0x0  
  9.     str r1,[r0]  
  10. MAIN_LOOP:  
  11.     b MAIN_LOOP  

编译指令如下:

编译:arm-linux-gcc -g -c -o led_on.o led_on.S

链接:arm-linux-ld -Ttext 0x30000000 -g -o led_on.elf led_on.o

转换:arm-linux-objcopy -O binary -S led_on.elf led_on.bin

makefile可以这样写:

[html] view plaincopy
  1. led_on.bin:led_on.S 
  2.     arm-linux-gcc -g -c -o led_on.o led_on.S 
  3.     arm-linux-ld -Ttext 0x30000000 -g led_on.o -o led_on_elf 
  4.     arm-linux-objcopy -O binary -S led_on_elf led_on.bin 
  5. clean: 
  6.     rm -f led_on.bin led_on_elf *.o 
[html] view plaincopy
  1. led_on.bin:led_on.S  
  2.     arm-linux-gcc -g -c -o led_on.o led_on.S  
  3.     arm-linux-ld -Ttext 0x30000000 -g led_on.o -o led_on_elf  
  4.     arm-linux-objcopy -O binary -S led_on_elf led_on.bin  
  5. clean:  
  6.     rm -f led_on.bin led_on_elf *.o  

例子2:老师曾经跟我说arm必须用汇编引导启动,但是用C试了一下,发现没有汇编,一样能操作arm芯片,下面是让流水灯循环点亮的程序,

[html] view plaincopy
  1. #define GPBCON    (*(volatile unsigned *)0x56000010) 
  2. #define GPBDAT    (*(volatile unsigned *)0x56000014) 
  3. #define GPBUP     (*(volatile unsigned *)0x56000018)  
  4. #define MPLL100MHz      0x0007f022 
  5. #define CLKDIV2         0x02 
  6. #define rMPLLCON    (*(volatile unsigned *)0x4c000004)  
  7. #define rCLKDIVN    (*(volatile unsigned *)0x4c000014)  
  8. int main() 
  9.     int i = 0
  10.     int count = 0
  11.     int LEDS[4] = {0x1c0, 0x1a0, 0x160, 0xe0}; 
  12.  
  13.     rMPLLCON = MPLL100MHz
  14.     rCLKDIVN = CLKDIV2
  15.     GPBCON = 0x00155555
  16.     GPBUP  = GPBUP & 0xFF00; 
  17.  
  18.     while(1) 
  19.     { 
  20.         for(count = 0; count != 4; ++ count) 
  21.         { 
  22.             GPBDAT=LEDS[count]; 
  23.             for(i = 0; i<0x30000;i++ ); 
  24.         } 
  25.     } 
[html] view plaincopy
  1. #define GPBCON    (*(volatile unsigned *)0x56000010)  
  2. #define GPBDAT    (*(volatile unsigned *)0x56000014)  
  3. #define GPBUP     (*(volatile unsigned *)0x56000018)   
  4. #define MPLL100MHz      0x0007f022  
  5. #define CLKDIV2         0x02  
  6. #define rMPLLCON    (*(volatile unsigned *)0x4c000004)   
  7. #define rCLKDIVN    (*(volatile unsigned *)0x4c000014)   
  8. int main()  
  9. {  
  10.     int i = 0;  
  11.     int count = 0;  
  12.     int LEDS[4] = {0x1c0, 0x1a0, 0x160, 0xe0};  
  13.   
  14.     rMPLLCON = MPLL100MHz;  
  15.     rCLKDIVN = CLKDIV2;  
  16.     GPBCON = 0x00155555;  
  17.     GPBUP  = GPBUP & 0xFF00;  
  18.   
  19.     while(1)  
  20.     {  
  21.         for(count = 0; count != 4; ++ count)  
  22.         {  
  23.             GPBDAT=LEDS[count];  
  24.             for(i = 0; i<0x30000;i++ );  
  25.         }  
  26.     }  
  27. }  

命令行下的编译流程我就不写了,直接把makefile贴在这里吧

[html] view plaincopy
  1. led.bin:led.c 
  2.     arm-linux-gcc -g -c -o led.o led.c 
  3.     arm-linux-ld -Ttext 0x30000000 -g led.o -o led.elf -e main 
  4.     arm-linux-objcopy -O binary -S led.elf led.bin 
  5. .PYTHON:clean 
  6. clean: 
  7.     rm *.o led.elf led.bin 
[html] view plaincopy
  1. led.bin:led.c  
  2.     arm-linux-gcc -g -c -o led.o led.c  
  3.     arm-linux-ld -Ttext 0x30000000 -g led.o -o led.elf -e main  
  4.     arm-linux-objcopy -O binary -S led.elf led.bin  
  5. .PYTHON:clean  
  6. clean:  
  7.     rm *.o led.elf led.bin  

这里我想提醒一下,纯C的makefile与汇编的makefile是有点区别的,由于C的主函数是main,但是arm执行环境并不知道是main,因此需要显式的指定arm入口函数-e main,其他的就没什么可说的了,多文件编译可以使用推导,我相信到这里大家都能自己编写多文件的makefile了,我就不多说了,如果有朋友对此有疑问可以联系qq630905224,我想大家一块讨论,共同进步还是好的,好了,浪费大家时间了。

 

转于:http://blog.csdn.net/girlkoo/article/details/6878897

原创粉丝点击