Linux下arm裸機開發環境搭建與實例


好文章,先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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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 plain copy
 
  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM