天天看點

GNU-ARM程式開發(二)----GNU下的跑馬燈

我們一般在Windows下的MDK環境或者是ADS環境下開發裸機程式

下面來體驗一下Linux下GNU-ARM的裸奔程式開發

GNU ARM裸奔程式的開發步驟如下:

1)編寫程式(彙編/C程式)

2)編寫連結腳本

3)編譯、彙程式設計式檔案,生産目标檔案(.o)

4)利用連結腳本連結目标檔案,生産可執行檔案(elf格式)

5)利用格式轉換工具(objcopy)将elf格式檔案轉換為bin格式

6)燒寫

這裡彙編指令就略過了。

彙編行結構

[标号:]  彙編語句 @注釋

标号

标号隻能由a~z,A~Z,0~9,“.”,“_”等字元組成;

“.” 标号 :特殊的标

“_”表示目前位置的運作位址 ;

注釋

@   從符合開始到行結尾

#  整行注釋

彙程式設計式中的分段

彙編系統預定義的段名

.text   @代碼段

.data   @已經初始化的全局變量和靜态變量

.bss   @是未初始化的全局變量和靜态變量

自定義一個段

.section  自定義段名 

彙程式設計式中的關鍵字

.extern symbol

聲明symbol的定義在其他源檔案中

.global symbol

聲明symbol是全局可見的

.include "filename"

在目前源檔案中插入filename的内容

.set symbol, expression

設定symbol的值為expression

GNU的僞指令跟MDK的僞指令不同;但是兩個編譯器都能夠識别ARM指令;

GNU編譯環境下的僞操作可分為以下幾類:

常量編譯控制僞操作

彙程式設計式代碼控制僞操作

宏及條件編譯控制僞操作

其他僞操作

 常量編譯控制僞操作

GNU-ARM程式開發(二)----GNU下的跑馬燈

彙程式設計式代碼控制僞操作

GNU-ARM程式開發(二)----GNU下的跑馬燈

宏及條件編譯控制僞操作

GNU-ARM程式開發(二)----GNU下的跑馬燈

其他僞操作

GNU-ARM程式開發(二)----GNU下的跑馬燈

連接配接腳本檔案

elf格式檔案:

GNU編譯器生成的目标檔案預設為elf格式;

elf檔案由若幹段(section)組成;

目标代碼中包含如下段:

.text: 包含程式的指令代碼;

.data: 包含固定的資料,如常量、字元串;

.bss: 包含未初始化的變量、數組等;

連接配接器的任務就是将多個目标檔案的.text、.data和.bss等段連接配接在一起,而連接配接腳本檔案是告訴連接配接器從什麼位址開始放置這些段。

連結腳本

内置預設連接配接腳本:

如果采用預設腳本,則生成的目标代碼需要作業系統才能加載運作(作業系統上的應用程式采用預設腳本)。

自定義連結腳本:

為了能在嵌入式系統上直接運作,需要編寫自己的連接配接腳本檔案。

連結腳本格式

連結器腳本由一系列指令組成;

“SECTIONS”指令:描述輸出檔案的記憶體布,SECTIONS段的基本格式如下:

 SECTIONS

 {

 段名 : {段内容}

 }

ENTRY(symbol) :設定入口點,參數是一個符号名;

OUTPUT_FORMAT(bfdname):輸出檔案的BFD格式;

OUTPUT_ARCH(bfdarch) :指定平台架構;

對于ARM,bfdname=elf32-littlearm,bfdarch=arm

LED跑馬燈程式連結腳本:

led.lds:

1 OUTPUT_FORMAT(elf32-littlearm)
      2 OUTPUT_ARCH(arm)
      3 ENTRY(_start)
      4 
      5 SECTIONS
      6 {
      7 >---. = 0x0;
      8 >---. = ALIGN(4);
      9 >---.text : {
     10 >--->---led.o (.text)
     11 >--->---delay.o (.text)
     12 >---}
     13 
     14 >---. = ALIGN(4);
     15 >---.data : {
     16 >--->---*(.data)
     17 >---}
     18 >---
     19 >---. = ALIGN(4);
     20 >---.bss : {
     21 >--->---*(.bss)
     22 >---}
     23 
     24 }
           

編譯連結過程

Arm-linux-ld –Txxx.lds xx.o –o xxxx.elf

–T 直接指定代碼段

xxx.lds 為連接配接腳本

arm-linux-objcopy被用來複制一個目标檔案的内容到另一個檔案中,可用于不同源檔案的之間的格式轉換

Arm-linux-objcopy –O binary –S elf_file bin_file

-O bfdname 輸出的格式

-F bfdname 同時指明源檔案,目的檔案的格式

-R sectionname 從輸出檔案中删除掉所有名為sectionname的段

-S 不從源檔案中複制重定位資訊和符号資訊到目标檔案中

-g 不從源檔案中複制調試符号到目标檔案中

makefile:

1 led.bin:led.o delay.o led.lds
      2 >---arm-linux-ld -Tled.lds led.o delay.o -o led.elf
      3 >---arm-linux-objcopy -O binary -S led.elf led.bin
      4 
      5 led.o:led.s
      6 >---arm-linux-gcc -c led.s -o led.o>
      7 
      8 delay.o:delay.s
      9 >---arm-linux-gcc -c delay.s -o delay.o
     10 
     11 clean:-
     12 >---rm -rf *.o *.elf *.bin
     13 
           

led.s:

.text
.extern delay
.global _start
_start:
	@set GPBCON
	ldr r0,=0x56000010
	ldr r1,[r0]
	bic r1,r1,#0xc00
	orr r1,r1,#0x15400
	str r1,[r0]
	@set GPBUP
	ldr r0,=0x56000018
	ldr r1,[r0]
	orr r1,r1,#0x20
	str r1,[r0]
loop:

    ldr r0,=0x56000014

    ldr r3,=0x1e0
    str r3,[r0]

    bl delay

    ldr r3,=0xfd0
    str r3,[r0]

    bl delay

    ldr r3,=0xfb0
    str r3,[r0]

    bl delay

    ldr r3,=0xf70
    str r3,[r0]

    bl delay

    ldr r3,=0xef0
    str r3,[r0]

    bl delay
	b loop


.end
           

delay.s:

1 
      2 .text
      3 .global delay
      4 delay:
      5 >---ldr r2,=0x2000000
      6 delay_loop:
      7         sub r2,r2,#1
      8         cmp r2,#0x0
      9         bne delay_loop
     10         mov pc,lr
     11 
     12 .end
           

最後,把make出來的bin燒到闆上。

假如用jtag可以燒到0位址。此時cup頻率是12mhz,delay.s下的ldr r2,=0x20000,此時開發闆上的bootloader已經挂了,是以不推薦用這種方法。

假如用dnw下到記憶體裡運作,此時的cup頻率是400mhz,delay.s下的ldr r2,=0x2000000,ok

繼續閱讀