Transcript Document

嵌入式系統概論-以S3C2440核心為架構
第7章 C與組合語言程式設計LED應用
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-2/44
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-3/44
7.1 ARM編譯器所支援的虛擬指令
在ARM組合語言程式中,有一些特殊指令助記符號。
這些助記符號與指令系統的助記符號不同,在沒有
相對應的操作碼時,通常稱這些特殊指令助記符號
為虛擬指令,且其所完成的操作稱為偽操作。虛擬
指令在來源程式中的作用是為了完成組合語言程式
所需作的各種準備工作。而這些虛擬指令僅在編譯
過程中發揮作用,一旦編譯結束,虛擬指令的使命
就完成。
在ARM的組合語言程式中,有如下幾種虛擬指令:
符號定義虛擬指令、資料定義虛擬指令、編譯控制
虛擬指令、巨集指令以及其他虛擬指令。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-4/44
7.1.1 符號定義(Symbol Definition)虛擬指令
 符號定義虛擬指令是用於定義ARM組合語言程
式中的變數、對變數設定值以及定義暫存器的
別名等操作。
 常見的符號定義虛擬指令有如下幾種:





用於定義整體變數的GBLA、GBLL和GBLS。
用於定義區域變數的LCLA、LCLL和LCLS。
用於對變數設定值的SETA、SETL、SETS。
為通用暫存器列表定義名稱的RLIST。
以下,介紹這幾個指令:
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-5/44
7.1.1 符號定義(Symbol Definition)虛擬指令
 GBLA、GBLL和GBLS







語法格式:
GBLA(GBLL或GBLS)
整體變數名稱
GBLA、GBLL和GBLS虛擬指令用於定義一個ARM程式中的整體變數,
並將其初始化。其中:
GBLA虛擬指令用於定義一個整體的算術變數,並初始化為0;
GBLL虛擬指令用於定義一個整體的邏輯變數,並初始化為F(假值);
GBLS虛擬指令用於定義一個整體的字串變數,並初始化為空;
由於以上三條虛擬指令是用於定義整體變數的,因此在整個程式範圍內,
其變數名稱必須是唯一的。
 程式範例:






GBLA
Test1
GBLL
Test2
GBLS
Test3
Test1
SETA
Test2
SETL
Test3
SETS
;定義一個整體的算術變數,變數名為Test1
0xaa
;將該變數設定值為0xaa
;定義一個整體的邏輯變數,變數名為Test2
{TRUE} ;將該變數設定值為真
;定義一個整體的字串變數,變數名為Test3
“Testing”;將該變數設定值為“Testing”
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-6/44
7.1.1 符號定義(Symbol Definition)虛擬指令
 LCLA、LCLL和LCLS







語法格式:
LCLA(LCLL或LCLS) 區域變數名稱
LCLA、LCLL和LCLS虛擬指令用於定義一個ARM程式中的區域變數,並
將其初始化。其中:
LCLA虛擬指令用於定義一個區域的算術變數,並初始化為0;
LCLL虛擬指令用於定義一個區域的邏輯變數,並初始化為F(假);
LCLS虛擬指令用於定義一個區域的字串變數,並初始化為空;
以上三條虛擬指令是用於宣告區域變數的,因此在其作用範圍內,其變數名
稱必須是唯一的。
 程式範例:






LCLA
Test3
LCLL
Test4
LCLS
Test6
Test4
SETA
Test5
SETL
Test6
SETS
;宣告一個區域的算術變數,變數名為Test4
0xaa
;將該變數設定值為0xaa
;宣告一個區域的邏輯變數,變數名為Test5
{TRUE} ;將該變數設定值為真
;定義一個區域的字串變數,變數名為Test6
“Testing” ;將該變數設定值為“Testing”
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-7/44
7.1.1 符號定義(Symbol Definition)虛擬指令
 SETA、SETL和SETS







語法格式:
變數名 SETA(SETL或SETS) 運算式
虛擬指令SETA、SETL、SETS用於給一個已經定義的整體變數或區域變數設
定值。
SETA虛擬指令用於給一個數學變數設定值;
SETL虛擬指令用於給一個邏輯變數設定值;
SETS虛擬指令用於給一個字串變數設定值;
其中,變數名稱是已經定義過的整體變數或是區域變數,運算式為將要賦給變
數的值。
 程式範例:




LCLA
Test3
LCLL
Test4
Test3
SETA
Test4
SETL
;宣告一個區域的算術變數,變數名為Test3
0xaa
;將該變數設定值為0xaa
;宣告一個區域的邏輯變數,變數名為Test4
{TRUE} ;將該變數設定值為真
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-8/44
7.1.1 符號定義(Symbol Definition)虛擬指令
 RLIST


語法格式:名稱 RLIST {暫存器列表}
RLIST虛擬指令可用於對一個通用暫存器列表來定義名稱,
使用該虛擬指令定義的名稱可在ARM指令LDM/STM中使
用。在LDM/STM指令中,列表中的暫存器存取次序是根據
暫存器的編號由低到高,而與列表中的暫存器排列次序無
關。
 程式範例:

RegList
RLIST
{R0-R5,R8,R10} ;將暫存
器列表名稱定義為RegList,可在ARM指令LDM/STM中通
過該名稱存取暫存器列表。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-9/44
7.1.2 資料定義(Data Definition)虛擬指令
 資料定義虛擬指令一般用於為特定的資料所分配記
憶體單元,同時可完成已分配記憶體單元的初始化
工作。
 常見的資料定義虛擬指令有如下幾種:
 DCB
 DCQ(DCQU)
 DCW(DCWU)
 SPACE
 DCD(DCDU)
 DCFD(DCFDU)
 DCFS(DCFSU)
 MAP
 FIELD
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-10/44
7.1.2 資料定義(Data Definition)虛擬指令
DCB

用於分配一個連續的位元組記憶體單元區塊,並用指定的
資料來加以初始化。
DCW(DCWU)

於分配一個連續的半字元組記憶體單元區塊,並用指定的
資料來加以初始化。
DCD(DCDU)

用於分配一個連續的字元組記憶體單元區塊,並用指定的
資料來加以初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCFD(DCFDU)

用於為雙精度的浮點數分配一個連續的字記憶體單元區塊,
並用指定的資料來加以初始化。
DCFS(DCFSU)

用於為單精確度的浮點數分配一個連續的字記憶體單元區
塊,並用指定的資料加以初始化。
DCQ(DCQU)

用於分配一個以8位元組為單位的連續記憶體單元區塊,
並用指定的資料加以初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
SPACE

用於分配一個連續的記憶體單元區塊。
MAP

用於定義一個結構化的記憶體表的首位址。
FIELD

用於定義一個結構化的記憶體表的資料欄。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
以下,稍微介紹這幾個指令:
DCB


語法格式:標記 DCB 運算式
DCB虛擬指令用於分配一個連續的位元組記憶體單元區塊,
並用虛擬指令中指定的運算式初始化。其中,運算式可以
為0~255的數值或字串。DCB也可用“=”來取代。
程式範例:

Str
DCB “This is a test!” ;分配一個連續的位
元組記憶體單元區塊,並加以初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCW(或DCWU)



語法格式:標記 DCW (或DCWU)運算式
DCW(或DCWU)虛擬指令用於分配一個連續的半字元
組記憶體單元,並用虛擬指令中指定的運算式初始化。其
中,運算式可以為程式標記或算術運算式。。
用DCW分配的字記憶體單元是半字元組對齊的,而用
DCWU分配的字記憶體單元並不嚴格半字元組對齊。
程式範例:

DataTest
DCW
1,2,3 ;分配一個連續的
半字元組記憶體單元區塊,並加以初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCD(或DCDU)



語法格式:標記 DCD(或DCDU) 運算式
DCD(或DCDU)虛擬指令是用於分配一個連續的字元組
記憶體單元區塊,並用虛擬指令中指定的運算式加以初始
化。其中,運算式可以是程式標記或算術的運算式。DCD
也可用“&”來取代。
用DCD分配的字記憶體單元是字元組對齊的,而用DCDU
分配的字元組記憶體單元並不嚴格執行字元組對齊。
程式範例:

DataTest
DCD
4,5,6
;分配一個連
續的字記憶體單元區塊,並加以初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCFD(或DCFDU)



語法格式:標記 DCFD(或DCFDU)運算式
DCFD(或DCFDU)虛擬指令用於為雙精度的浮點數來分
配一個連續的字記憶體單元區塊,並用虛擬指令中指定的
運算式加以初始化。每個雙精度的浮點數是佔據兩個字元
組單元。
用DCFD分配的字記憶體單元是字元組對齊的,而用
DCFDU分配的字元組記憶體單元並不嚴格執行字元組對
齊。
程式範例:

FDataTest
DCFD 2E115,-5E7
;分配一個連
續的字元組記憶體單元區塊,並初始化為指定的雙精度數
值。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCFS(或DCFSU)



語法格式:標記 DCFS(或DCFSU)運算式
DCFS(或DCFSU)虛擬指令用於為單精確度的浮點數來
分配一個連續的字記憶體單元區塊,並用虛擬指令中指定
的運算式加以初始化。每個單精確度的浮點數佔據一個字
元組單元。
用DCFS分配的字記憶體單元是字元組對齊的,而用
DCFSU分配的字元組記憶體單元並不嚴格執行字元組對齊。
程式範例:

FDataTest
DCFS 2E5,-5E-7
;分配一個連
續的字元組記憶體單元區塊,並初始化為指定的單精確度
數值。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
DCQ(或DCQU)



語法格式:標記
DCQ(或DCQU) 運算式
DCQ(或DCQU)虛擬指令用於分配一個以8個位元組為
單位的連續記憶體區塊,並用虛擬指令中指定的運算式加
以初始化。
用DCQ分配的記憶體單元是字元組對齊的,而用DCQU分
配的記憶體單元並不嚴格執行字元組對齊。
程式範例:

DataTest
DCQ
100
;分配一個連
續的記憶體單元區塊,並初始化為指定的數值。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
SPACE


語法格式:標記
SPACE
運算式
SPACE虛擬指令用於分配一個連續的記憶體區塊,並初始
化為0。其中,運算式為所要分配的位元組數目。SPACE
也可用“%”來取代。
程式範例:

DataSpace
SPACE
100
;分配連續100
位元組的記憶體單元區塊,並初始化為0。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
MAP
語法格式:MAP
運算式{,基底暫存器}
MAP虛擬指令用於定義一個結構化的記憶體表的首位址。
MAP也可用“^”來取代。
 運算式可以為程式中的標記或數學運算式,基底暫存器為
可選擇項目。當基底暫存器選項不存在時,運算式的數值
即為記憶體表的首位址。反之,當該選項存在時,記憶體
表的首位址為運算式的數值與基底暫存器的總和。
 MAP虛擬指令通常與FIELD虛擬指令配合使用來定義結構
化的記憶體表。


程式範例:

MAP 0x100,R0
為0x100+R0。
;定義結構化記憶體表頭位址的值
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
FILED





語法格式:標記
FIELD
運算式
FIELD虛擬指令用於定義一個結構化記憶體表中的資料欄。
FILED也可用“#”來取代。
運算式的值為目前資料欄在記憶體表中所占用的位元組數。
FIELD虛擬指令常與MAP虛擬指令配合使用來定義結構化
的記憶體表。MAP虛擬指令定義記憶體表的首位址,
FIELD虛擬指令定義記憶體表中的各個資料欄,並可以為
每個資料欄指定一個標記供其他的指令引用。
注意到,MAP和FIELD虛擬指令僅用於定義資料結構,並
不實際分配記憶體單元。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.2 資料定義(Data Definition)虛擬指令
FILED程式範例:

MAP 0x100
;定義結構化記憶體表頭位址的值為0x100。

A
FIELD
16
;定義A的長度為16-bit組,位置為0x100

B
FIELD
32
;定義B的長度為32-bit組,位置為0x110

S
FIELD
256
;定義S的長度為256位元組,位置為0x130
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
編譯控制虛擬指令用於控制組合語言程式的執行流
程,常用的編譯控制虛擬指令包括以下幾條:




IF、ELSE、ENDIF
WHILE、WEND
MACRO、MEND
MEXIT
以下,稍微介紹這幾個指令:
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
IF、ELSE、ENDIF








語法格式:
IF
邏輯運算式
指令序列1
ELSE
指令序列2
ENDIF
IF、ELSE、ENDIF虛擬指令能根據條件的成立與否決定
是否執行某個指令序列。當IF後面的邏輯運算式為真時,
則執行指令序列1,否則執行指令序列2。其中,ELSE及
指令序列2可以沒有,此時,當IF後面的邏輯運算式為真
時,則執行指令序列1,否則繼續執行後面的指令。
IF、ELSE、ENDIF虛擬指令可以套入程式來使用。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
IF、ELSE、ENDIF程式範例:


GBLL Test
;宣告一個整體的邏輯變數,變數名為Test
 ……
 IF
Test = TRUE
指令序列1
 ELSE
指令序列2
 ENDIF
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
WHILE、WEND






語法格式:
WHILE邏輯運算式
指令序列
WEND
WHILE、WEND虛擬指令能根據條件的成立與否來決定
是否迴圈執行某個指令序列。當WHILE後面的邏輯運算
式為真,則執行指令序列,該指令序列執行完畢後,再判
斷邏輯運算式的值,若為真則繼續執行,一直到邏輯運算
式的值變成假為止。
WHILE、WEND虛擬指令可以套入程式使用。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
WHILE、WEND程式範例:


GBLA Counter
;宣告一個整體的數學變數,變數名為Counter


CounterSETA
3
;由變數Counter控制迴圈次數
 ……
 WHILECounter < 10
 指令序列
 WEND
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
MACRO、MEND



語法格式:
$標記 巨集名稱 $參數1,$參數2,……
指令序列_1





MEND
;MACRO、MEND虛擬指令可以將一整區段程式代碼定義為一
個整體的單元,稱之為巨集指令。
;設定完成後,就可以在程式中通過巨集指令來多次呼叫該區段
程式代碼。其中,$標記在巨集指令被展開時,標記會被替換為使
用者定義的符號。
;巨集指令可以使用一個或多個參數。若是當這巨集指令被展開
時,這些參數就會被相對應的數值來加以替換。
;巨集指令的使用方式與功能是與副程式有些相似的,副程式可
以提供模組化的程式設計、節省記憶體空間,並提高整個執行的
速度。但在使用副程式結構時,則需要保護相當多的變數,進而
增加了系統的開銷。因此,在程式代碼較短且需要傳遞的參數較
多時,可以使用巨集指令取代副程式。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令

指令序列_2




;包含在MACRO和MEND之間的指令序列就可稱為巨集定義體。
;在巨集定義體的第一行應宣告巨集的原型(包含巨集名稱與所
需的參數),然後就可以在組合語言程式中通過巨集名稱來呼叫
該指令序列。
;在來源程式被編譯時,編譯器將巨集呼叫展開,用巨集定義中
的指令序列代替程式中的巨集呼叫,並將實際參數的值傳遞給巨
集定義中的形式參數。
;MACRO、MEND虛擬指令可以套入程式中使用。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.3 編譯控制(Assembly Control)虛擬指令
MEXIT
語法格式:
 MEXIT
 MEXIT用於從巨集定義體中跳躍出去。

嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
還有一些其他的虛擬指令,在組合語言程式中經常
會被使用,包括以下幾條:



AREA
ALIGN
CODE16、CODE32
 ENTRY
 END
 EQU

EXPORT(或GLOBAL)
 IMPORT
 EXTERN
 GET(或INCLUDE)
 INCBIN
 RN
 ROUT
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
AREA



語法格式:AREA 區段名稱 屬性1,屬性2,……
AREA虛擬指令用於定義一個程式代碼區段或資料區段。
其中,區段名稱若以數字開頭,則該區段名稱需用“|”括
起來,如|1_test|。
屬性欄位則表示該代碼區段(或資料區段)的相關屬性,
多個屬性用逗號分隔。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
AREA

常用的屬性如下:







CODE屬性:用於定義程式代碼段,預設為READONLY。
DATA屬性:用於定義資料區段,預設為READWRITE。
READONLY屬性:指定本區段為唯讀,程式代碼區段預設為
READONLY。
READWRITE屬性:指定本區段為可讀可寫,資料區段的預設屬
性為
READWRITE。
ALIGN屬性:使用方式為ALIGN 運算式。在預設時,ELF(可執
行連接檔) 的程式代碼區段和資料區段是按字元組對齊的,運
算式的取得數值範圍是0~31之間,相對應的對齊方式為運算式的
2的冪次方。
COMMON屬性:該屬性定義一個通用的區段,不包含任何的使用
者代碼和資料。各原始檔案中同名的COMMON區段共用同一區段
記憶體單元。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
AREA



程式範例:
AREA Init,CODE,READONLY
指令序列
;該虛擬指令定義了一個程式代碼區段,區段名為Init,
屬性為唯讀
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
 ALIGN


語法格式:ALIGN {運算式{,偏移量}}
ALIGN虛擬指令可通過新增填充位元組的方式,使目前位置滿足一定
的對其方式。其中,運算式的值是用於指定對齊方式,可能的取值為
2的冪次方,如1、2、4、8、16等。若未指定運算式,時,則將目前
位置對齊到下一個字元組的位置。偏移量也為一個算術運算式,若使
用該欄位,則目前位置的對齊方式為:2的運算式次冪+偏移量。
 程式範例:



AREA Init,CODE,READONLY,ALIEN=3 ;指定後面的指令
為8個位元組對齊。
指令序列
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
 ALIGN


語法格式:ALIGN {運算式{,偏移量}}
ALIGN虛擬指令可通過新增填充位元組的方式,使目前位置滿足一定
的對其方式。其中,運算式的值是用於指定對齊方式,可能的取值為
2的冪次方,如1、2、4、8、16等。若未指定運算式,時,則將目前
位置對齊到下一個字元組的位置。偏移量也為一個算術運算式,若使
用該欄位,則目前位置的對齊方式為:2的運算式次冪+偏移量。
 程式範例:



AREA Init,CODE,READONLY,ALIEN=3 ;指定後面的指令
為8個位元組對齊。
指令序列
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
CODE16、CODE32




語法格式:CODE16(或CODE32)
CODE16虛擬指令通知編譯器,其後的指令序列為16-bit
的Thumb指令。
CODE32虛擬指令通知編譯器,其後的指令序列為32-bit
的ARM指令。
若在編譯來源程式中同時包含ARM指令和Thumb指令時,
可用CODE16虛擬指令通知編譯器其後的指令序列為16bit的Thumb指令,反之,CODE32虛擬指令則是通知編譯
器其後的指令序列為32-bit的ARM指令。因此,在使用
ARM指令和Thumb指令混合撰寫的程式代碼中,可用這
兩條虛擬指令來進行切換。但需注意到,它們只通知編譯
器其後指令的類型,但並不能對處理器進行狀態的切換。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
程式範例:

AREA Init,CODE,READONLY
 ……
 CODE32
;通知編譯器其後的指令為32-bit的ARM
指令
 LDR
R0,=NEXT+1 ;將跳躍位址放入暫存器R0
 BX
R0
;程式跳躍到新的位置執行,並將處理器
切換到Thumb工作狀態
 ……
 CODE16
;通知編譯器其後的指令為16-bit的Thumb
指令
 NEXT LDR R3,=0x3FF
 ……
 END
;程式結束
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
 ENTRY



語法格式:
ENTRY
ENTRY虛擬指令用於指定組合語言程式的入口點。在一個完整的組
合語言程式中至少要有一個ENTRY(也可以有多個,當有多個
ENTRY時,程式的真正入口點由鏈結器指定),但在一個原始檔案
裏最多只能有一個ENTRY(但可以是沒有)。
 程式範例:



AREA Init,CODE,READONLY
ENTRY
……
;指定應用程式的入口點
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
END


語法格式:END
END虛擬指令用於通知編譯器已經到了來源程式的結尾處。
程式範例:

AREA Init,CODE,READONLY
 ……
 END
;指定應用程式的結尾處
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
EQU



語法格式:名稱 EQU 運算式{,類型}
EQU虛擬指令用於為程式中的常數、標記等定義一個等效
的字元名稱,類似於C語言中的#define。其中,EQU可
用“*”來取代。
而其中的”名稱”為EQU虛擬指令定義的字元名稱。當運
算式為32-bit的常數時,可以指定運算式的資料類型,可
以有以下三種類型:CODE16、CODE32和DATA。
程式範例:


Test
EQU 50
;定義標記Test的值為50
Addr EQU 0x55,CODE32
;定義Addr的值為
0x55,且該處為32-bit的ARM指令。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
EXPORT(或GLOBAL)


語法格式:EXPORT 標記{[WEAK]}
EXPORT虛擬指令用於在程式中宣告一個整體的標記,該
標記可在其他的文件中引用。EXPORT可用GLOBAL代
替。標記在程式中區分大小寫,[WEAK]選項則宣告其他
的同名標記優先於該標記被引用。
程式範例:




AREA Init,CODE,READONLY
Stest
;宣告一個可整體被引用的標記Stest
……
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
IMPORT



語法格式:IMPORT 標記{[WEAK]}
IMPORT虛擬指令用於通知編譯器要使用的標記在其他的
原始檔案中被定義了。但若是要在目前原始檔案中引用,
且無論目前原始檔案是否引用該標記,那麼該標記均會被
加入到目前原始檔案的符號表中。
標記在程式中區分大小寫,[WEAK]選項表示當所有的原
始檔案都沒有定義這樣一個標記時,編譯器也不給出錯誤
資訊,在多數情況下將該標記置為0,若該標記為B或BL
指令引用,則將B或BL指令置為NOP操作。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
IMPORT程式範例:





AREA Init,CODE,READONLY
IMPORT
Main
;通知編譯器目前文件要引用標
記Main,但Main在其他原始檔案
中定義
……
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
EXTERN



語法格式:EXTERN 標記{[WEAK]}
EXTERN虛擬指令用於通知編譯器要使用的標記在其他的
原始檔案中定義,但要在目前原始檔案中引用,如果目前
原始檔案實際並未引用該標記的話,該標記就不會被加入
到目前原始檔案的符號表中。
標記在程式中區分大小寫,[WEAK]選項表示了當所有的
原始檔案都沒有定義這樣一個標記時,編譯器不產生錯誤
資訊,且在多數情況下將該標記設定為0。若該標記被B或
BL指令所引用的話,那麼就會將B或BL指令設定為NOP
指令來操作。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
EXTERN程式範例:




AREA Init,CODE,READONLY
EXTERN
Main ;通知編譯器目前文件要引
用標記4Main,但Main在其他原始檔案中定義
……
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
GET(或INCLUDE)




語法格式:GET
檔案名稱
GET虛擬指令用於將一個原始檔案包含到目前的原始檔案
中,並將被含括的原始檔案在目前位置進行編譯處理。我
們也可以使用INCLUDE來取代GET指令。
組合語言程式中常用的方法是在某原始檔案中定義一些巨
集指令,以EQU來定義常數的符號名稱,另外以MAP和
FIELD來定義結構化的資料類型,最後再用GET虛擬指令
將這個原始檔案含括到其他的原始檔案中。這種使用的方
法是與C語言中的“include”非常類似。
GET虛擬指令只能用於包含原始檔案,包含目標檔需要使
用INCBIN虛擬指令
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
GET(或INCLUDE)程式範例:





AREA Init,CODE,READONLY
GET a1.s
;通知編譯器目前原始檔案
包含原始檔案a1.s
GE
T
C:\a2.s
;通知編譯器目前原始檔案
包含原始檔案C:\ a2.s
……
END
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
RN


語法格式:名稱
RN
運算式
RN虛擬指令用於定義一個暫存器的別名。透過這種方式
的設定,我們可以很方便地來設定此記憶體暫存器的功能
或是特性。其中,名稱為此暫存器所要定義的別名,運算
式則為暫存器的編碼。
程式範例:

Temp
RN
R0
;將R0定義一個別名Temp
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1.4 其他常用的虛擬指令
ROUT


語法格式:{名稱}
ROUT
ROUT虛擬指令用於定義一個區域變數的作用範圍。若是
在程式中未使用該虛擬指令時,區域變數的作用範圍為所
在的AREA中,反之若是使用了ROUT後,區域變數的作
用範圍則變成目前ROUT和下一個ROUT之間。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-52/44
7.2 組合語言的語法
 {標記}
{指令或虛擬指令}
{;注解}
 ARM(Thumb)組合語言是撰寫於附加檔名為asm的文字檔
案內。而在每一行的組合語言中,大致可以分為四個欄位,
分別是標記(Label)欄,運算碼(Op Code)欄(也就是助
憶符號,MNEMONIC或是指令符號),運算元(Operand)
欄以及註解(Commant)欄。組合語言的語法以及其格式可
以參考下列所示的範例。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
標記 運算碼 運算元
註解
BL
NEXT
;跳躍到副程式NEXT處執行
……
NEXT
……
MOV PC , LR
;從副程式返回
在組合語言程式設計中,每一條指令的指令符號可
以全部用大寫、或全部用小寫,但不用許在一條指
令中大、小寫混用。同時,如果一條語句太長,可
將該長語句分為若干行來書寫,在行的末尾用“\”表
示下一行與本行為同一條語句。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
在組合語言程式中常用的符號
 在組合語言程式設計中,經常使用各種符號來代
替位址、變數和常數等,以增加程式的可讀性。
 符號的命名由程式設計者所決定的,但並不是任
意的,必須遵循以下的約定:

符號需區分為大小寫。同名的大、小寫符號將會被編譯
器認為是兩個不同的符號。

符號在其作用範圍內必須是唯一的。

自定義的符號名稱不能與系統的保留字相同。

符號名稱不應與指令或虛擬指令同名。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
程式中的變數

程式中的變數是指其值在程式的執行過程中可以改變的量。
ARM(Thumb)組合語言程式所支援的變數有算術變數、
邏輯變數和字串變數。

算術變數用於在程式的執行中所保存的算術數值,但需注
意到,算術數值的大小不應超出算術變數所能表示的範圍。
邏輯變數用於在程式的執行中所保存的邏輯數值。邏輯數
值只有兩種情況:真或假。字串變數用於在程式的執行中
所保存的一個字串。但需注意到,字串的長度不應超出字
串變數所能表示的範圍。

在ARM(Thumb)組合語言程式設計中,可使用GBLA、
GBLL、GBLS虛擬指令來宣告整體的變數。此外,使用
LCLA、LCLL、LCLS虛擬指令來宣告區域變數,並可使
用SETA、SETL和SETS對其進行初始化。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
程式中的常數

程式中的常數是指其值在程式的執行過程中不能被改變的
量。ARM(Thumb)組合語言程式所支援的常數有算術
常數、邏輯常數和字串常數。

算術常數一般為32-bit的整數,當作為無號數時,其數值
範圍為0~232-1,當作為有號數值時,其範圍為-231~
231-1之間。邏輯常數只有兩種情況:真或假。字串常數為
一個固定的字串,一般用於程式執行時的訊息提示。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
程式中的變數取代

程式中的變數可透過取代操作來取得一個常數。取代操作
符號為“$”。

如果在算術變數前面有一個替換操作符號“$”,那麼編譯
器會將該算術變數的值轉換為十六進位的字串,並將該十
六進位的字串來替換“$”後的算術變數。

如果在邏輯變數前面有一個取代操作符號“$”,那麼編譯
器會將該邏輯變數替換為它的邏輯值(真或假)。如果在
字串變數前面有一個取代操作符號“$”,那麼編譯器會將
該字串變數的值來取代替換“$”後的字串變數。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.2 組合語言的語法
程式範例:
LCLS
S1
;定義區域字串變數S1和S2
LCLS
S2
S1
SETS
“Test!”
S2
SETS
“This is a $S1”
;字串變數S2的值為“This is a Test!”
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-60/44
7.3.1 組合語言的程式結構
在ARM(Thumb)組合語言程式中,以程式區段為
一單位的程式代碼。
區段是相對獨立的指令或資料序列,具有特定的名
稱。區段可以分為程式代碼區段和資料區段。程式
代碼區段的內容為所要執行的程式代碼,而資料區
段則存放程式代碼執行時需要用到的資料。
一個組合語言程式至少應該有一個程式代碼區段,
當程式較長時,可以分割為多個代碼區段和資料區
段,多個區段在程式編譯鏈結時最終可形成一個可
執行的映像檔。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.1 組合語言的程式結構
可執行映像檔案通常由以下幾個部分所構成:



一個或多個程式代碼區段。程式代碼區段的屬性為唯讀。
零個或多個包含初始化資料的資料區段。資料區段的屬性
為可讀寫。
零個或多個不包含初始化資料的資料區段。資料區段的屬
性為可讀寫。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.1 組合語言的程式結構
鏈結器則根據系統所預設或使用者設定的規則,將各
個區段安排在記憶體中的相對應的位置上。因此,在
來源程式中,每一區段之間的相對位置與可執行的映
像檔中的每一區段的相對位置一般是不會相同。
在組合語言程式中,用AREA虛擬指令定義一個區段,
並說明所定義區段的相關屬性,本範例定義一個名為
Init的程式代碼區段,屬性為唯讀。ENTRY虛擬指令
標示出程式的入口點,接下來為指令序列,程式的末
尾為END虛擬指令。該虛擬指令告訴編譯器原始檔案
的結束。而每一個組合語言程式區段都必須有一條
END虛擬指令,指示程式代碼區段的結束。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.2 組合語言的副程式呼叫
在ARM組合語言程式中,副程式的呼叫一般是通過
BL指令來實現的。在程式中,我們可以使用指令:

BL
副程式名稱
該指令在執行時完成如下操作:





將副程式的返回位址存放在鏈結暫存器LR中
將程式計數器PC指向副程式的入口點
當副程式執行完畢時需要返回呼叫處
將存放在LR中的返回位址重新拷貝給程式計數器PC
在呼叫副程式的同時,也可以完成參數的傳遞和從副程式返
回運算的結果,通常可以使用暫存器R0~R3即可完成
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.2 組合語言的副程式呼叫
以下是使用BL指令呼叫副程式的組合語言基本結構:


rGPFCON
EQU 0x56000050
rGPFDAT
EQU 0x56000054
 rGPFUP
EQU 0x56000058
 AREA
Init,CODE,READONLY ;該虛擬指令定義
了一個程式區段,區段名稱為Init,屬性唯讀
 ENTRY
;程式的入口點 虛擬指令
 ResetEntr
;==== 設置I/O埠GPF7為輸出屬性 ====
 Ldr
r0,=rGPFCON
;將暫存器rPCONF的位
址存放到暫存器r0中
 ldr
r1,=0x4000
 str
r1,[r0]
;將r1中的資料存放到暫存器
rPCONF中
;下面3個指令,主要是除能GPF埠的提升電
阻
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.2 組合語言的副程式呼叫
以下是使用BL指令呼叫副程式的組合語言基本結構:
ldr r0,=rGPFUP
ldr r1,=0xffff
str r1,[r0]
ldr r2,=rGPFDAT;將資料埠F的資料暫存器的位址附給暫存器
r2
ledloop
ldr r1,=0xff
str r1,[r2]
;使GPE7輸出高電壓,D14燈會滅
bl delay
;呼叫延遲副程式
ldr r1,=0x0
str r1,[r2]
;使GPE7
D14燈亮
bl delay
;呼叫延遲
b ledloop
;不斷的迴圈,D14將不停的閃爍
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.2 組合語言的副程式呼叫
以下是使用BL指令呼叫副程式的組合語言基本結構:
;==== 延遲副程式 ===
delay
ldr r3,=0xbffff ;設置延遲的時間
delay1
sub r3,r3,#1
;r3=r3-1
cmp r3,#0x0
;將r3的值與0相比較
bne delay1
;比較結果不為0(r3不為0),繼續呼叫delay1,否則執行下一
條語句
mov pc,lr
;返回
END
;程式結束
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
在應用系統的程式設計中,若是所有的程式設計工
作都是透過組合語言來完成的話,可想而知其工作
量是相當繁重的。
若所有的程式設計工作都透過組合語言來完成的話,
也不利於系統升級或應用軟體的移植。
ARM系列結構是支援C以及與組合語言的混合撰寫
設計。在一個完整的程式設計的中,除了初始化部
分用組合語言完成以外,其餘主要的程式設計工作
一般都是用C語言來加以實現。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
C與組合語言的混合設計通常有以下幾種方式:

在C程式中嵌入編譯指令。

在組合語言程式和C語言程式之間進行變數的相互存取。

組合語言程式與C程式間的相互呼叫。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
在以上的幾種混合撰寫技術中,必須遵守一定的呼
叫規則,如實體暫存器的使用、參數的傳遞等,這
對於初學者來說,無疑是顯得過於繁瑣。
在實際的程式設計的應用中,使用較多的方式是這
樣的,在程式的初始化部分用組合語言完成,然後
用C語言來完成主要的程式設計工作。
而程式在執行時首先會完成初始化過程,然後跳躍
到C程式中。組合語言程式和C程式之間一般並沒有
參數的傳遞,也沒有頻繁的相互呼叫。因此,整個
程式的結構顯得相對簡單,容易理解。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
ARM程式設計中,不同程式語言只要遵守ATPCS規
則就可實現不同語言間的相互呼叫。
ATPCS是一系列用於規定應用程式之間相互呼叫的
基本規則,這個規則包括:





支援資料棧限制檢查
支援唯讀段位置無關(ROPI)
支援可讀/寫段位置無關(RWPI)
支援ARM程式和Thumb程式的混合使用
處理浮點運算。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
使用以上規定的ATPCS規則時,應用程式必須遵守
如下:




程式撰寫遵守ATPCS;
變數傳遞以中間暫存器和資料線完成;
組譯器使用-apcs開關選項。
關於其他ATPCS規則,用戶可以參考ARM處理器相關書
籍或登錄ARM公司網站。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
組合語言切換到C語言的方法

C語言中定義的函式名稱在組合語言中可作為標名使用,
因此,在組合語言中可使用程式跳躍指令直接跳躍到C語
言中所定義的標名(函式)中。
組合語言程式:
_start:
B Main
C程式:
Void Main() {
}
/*跳躍到C語言程式*/
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
組合語言中函式的實現
程式只要遵守ATPCS相應規則,就可以使用不同的源程式
編寫程式。
 程式間的相互呼叫最主要的是解決參數傳遞問題。應用程
式之間使用中間暫存器及資料棧來傳遞參數,其中,第一
個到第四個參數使用R0-R3,多於四個參數的使用資料棧
進行傳遞。這樣,接收參數的應用程式必須知道參數的個
數。但是,在應用程式被呼叫時,一般無從知道所傳遞參
數的個數。
 不同語言編寫的應用程式在呼叫時可以自定義參數傳遞的
約定,使用具有一定意義的形式來傳遞,可以很好地解決
參數個數的問題。常用的方法是把第一個或最後一個參數
作為參數個數(包括個數本身)傳遞給應用程式。

嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
下面的程式就是用組合語言寫的一個簡單函式:
asse_add:
ADD r0,
MOV pc,
r0,
lr
r1
/*r0 = r0
+r1*/
/*函式返回*/
上面的組合語言函式相當於如下的C語言函式:
int assemble_add(int x,int y);
在組合語言中可以使用指令呼叫該函式。輸入時,
r0為x參數,r1為y參數;輸出r0。該函式實現的功能
很簡單,返回參數x與y的和。
BL assemble_add
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
C語言呼叫組合語言檔案的函式

若以上面的assemble_add函式為例,在C語言中聲明該函
式在其他檔中實現:
extern int asse_add(int x, int y);

然後就可像呼叫C函式一樣呼叫該函式:
x = asse_add(10,20);
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.3 C與組合語言的混合撰寫設計
C語言中內嵌入組合語言

ARM的編譯器支援內嵌組合語言。如下,列出在C語言中,
採用內嵌組合語言的方式實現方式,且與ssemble_add具
有相同的功能:
int embed_add()int x, int y) {
__asm
{ add x,x,
y}
retrun x;
}
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.4 C與組合語言的混合撰寫設計參考程式碼
以下,首先列出一個C與組合語言的混合撰寫設計參
考程式碼範例:
AREA Init,CODE,READONLY
;該虛擬指令定義了一
個程式區段,區段名稱為Init,屬性唯讀
ENTRY
;程式的入口點標記
ResetEntry
mov sp,#0x0c7000000 ;設定堆疊指標位址
IMPORT Main
;通知編譯器要使用的Main標
記在其他的原始檔案中被定義
BL
Main
;呼叫主函式
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.4 C與組合語言的混合撰寫設計參考程式碼
/*定義一個組合語言的延遲函式,相當於C語言的
void delay(int time)。其中,r0為time的計數值*/
EXPORT delay
delay
sub r0,r0,#1
;r0=r0-1
cmp r0,#0x0
;將r3的值與0相比較
bne delay
;比較的結果不為0(r0不為0),繼
續呼叫delay,否則執行下一條指令
mov pc,lr
;返回
END
;程式結束
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.4 C與組合語言的混合撰寫設計參考程式碼
上述的組合語言檔案,一般都命名為Init.s,作為初始
S3C2440之用。
接著建立一個建立C語言檔案。其中,Main.c函式,主
要實現D14 LED不停閃爍的功能,參考程式如下:
/*埠F暫存器定義*/
#define rGPFCON (*(volatile unsigned *)0x56000050)
#define rGPFDAT (*(volatile unsigned *)0x56000054)
#define rGPFUP
(*(volatile unsigned *)0x56000058)
extern delay(int time);
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.4 C與組合語言的混合撰寫設計參考程式碼
void Main()
{
rGPFCON=0x4000; /*設置I/O埠GPF7為輸出屬性*/
rGPFUP=0xffff;
/*禁止GPF埠的提升功能*/
while(1)
/*無窮迴圈,D14 LED燈將不停的閃爍*/
{
rGPDATF=0xff;
/*使GPF7輸出高電壓,D14 LED燈會滅*/
delay(0xbffff);
/*呼叫組合語言延遲函式*/
rGPDATF=0x0;
/*使GPE7
D14 LED燈亮*/
delay(0xbffff);
/*呼叫組合語言延遲函式*/
}
}
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.3.4 C與組合語言的混合撰寫設計參考程式碼
以上的程式代碼區段完成一些簡單的初始化與延遲
功能,然後跳躍到Main()函式所標記的C程式處
執行主要的任務。
此處的Main僅為一個標記,也可使用其他名稱,與
C語言程式中的main()函式沒有關係。
這兩個程式皆可透過筆記本或是一般的文書編輯器
來編輯,並另存*.S(組合語言)與*.C(C語言)檔
案名稱。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-83/44
7.4.1 S3C2440 GPIO特性
 S3C2410X有117個複合式功能輸入/輸出埠接腳。這些接腳是:








埠A(GPA):23個 輸出埠
埠B(GPB):11個輸入/輸出埠
埠C(GPC):16個輸入/輸出埠
埠D(GPD):16個輸入/輸出埠
埠E (GPE):16個輸入/輸出埠
埠F (GPF): 8個輸入/輸出埠
埠G(GPG):16個輸入/輸出埠
埠H(GPH):11個輸入/輸出埠
 每一個埠都可以有軟體程式的設置來滿足各種系統配置和設
計需求。在啟動程式之前你必須定義每個接腳的哪個功能。
如果接腳沒有配置為複合式功能的話,這個接腳就被配置為
一般的I/O埠。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
以下,進一步介紹每一個埠所支援的各種暫存器:
埠控制暫存器(GPACON-GPHCON)


在S3C2440A中,大部分的接腳是複合式的,因此,在使用
之前都必須針對每一個埠中的每一各所以對於每個接腳來
設定騎功能。埠控制暫存器(PnCON)則是用來定義每一
個接腳的功能。
例如,如果GPF0-GPF7和GPG0-GPG7在斷電模式下被用
做喚醒信號,那麼這些埠就必須先在中斷模式下被設置。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
埠資料暫存器(GPADAT-GPHDAT)

如果埠配置為輸出埠,資料能被寫到PnDAT對應的位置。
如果埠配置為輸入埠,能從PnDAT所對應的埠位元中讀取
資料。
埠提升暫存器(GPBUP-GPHUP)

埠提升暫存器控制著每個埠組的提升暫存器的致能或除能。
當對應位為0,這個接腳的提升暫存器是允許的。當為1時,
提升暫存器是禁止的。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
MISCELLANEOUS控制暫存器

這個暫存器控制資料埠的提升暫存器,高阻抗狀態,USB
通道以及CLKOUT的選擇。
外部中斷控制暫存器(EXTINTN)

24個外部中斷可由多種方式來請求。其中,EXTINTn暫
存器可以配置外部中斷的請求信號的觸發方式為低電壓觸
發,高電壓觸發,下降邊緣觸發,上升邊緣觸發以及雙邊
緣觸發。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
在以下的實驗中,將由埠GPF4~GPF7來控制
4個LED燈,因此,主要涉及埠F的控制暫存
器包括了GPFCON,GPFDAT與GPFPU。
埠F暫存器位址和位定義如下表所列:
埠F暫存器位址和位定義表
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
埠F配置暫存器(GPFCON)
埠F配置暫存器各位元定義如下表所列:
埠F配置暫存器各位元定義表
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
埠F資料暫存器(GPFDAT)
埠F資料暫存器各位元定義如下表所列:
埠F資料暫存器各位元定義表
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
提升暫存器(GPFUP)
埠F提升暫存器各位元定義如下表所列:
埠F提升暫存器各位元定義表
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
一個完整的GPIO初始化的副函式,可以如下所列:
void Port_Init(void)
{
rGPACON = 0x7fffff;
rGPBCON = 0x000150;
rGPBUP = 0x7ff; // The pull up function is
disabled GPB[10:0]
rGPCCON = 0xaaaaaaaa;
rGPCUP = 0xffff; // The pull up function is
disabled GPC[15:0]
rGPDCON = 0xaaaaaaaa;
rGPDUP = 0xffff; // The pull up function is
disabled GPD[15:0]
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
rGPECON = 0xa02aa800; // For added AC97 setting
rGPEUP = 0xffff;
rGPFCON = 0x55aa;
rGPFUP = 0xff;
// The pull up function is disabled GPF[7:0]
rGPGCON = 0x00a2aaaa;
// GPG9 input without pull-up, hzh
rGPGUP = 0xffff;
// The pull up function is disabled GPG[15:0]
rGPHCON = 0x00faaa;
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.2埠暫存器
rGPHUP = 0x7ff;
// The pull up function is disabled GPH[10:0]
rGPJCON = 0x02aaaaaa;
rGPJUP = 0x1fff;
// The pull up function is disabled GPH[10:0]
//External interrupt will be falling edge triggered.
rEXTINT0 = 0x22222222; // EINT[7:0]
rEXTINT1 = 0x22222222; // EINT[15:8]
rEXTINT2 = 0x22222222; // EINT[23:16]
}
其中,包含了針對DMA-2440XP開發平台的PA~PG
週邊埠設定。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.3 4個LED指示燈的介面電路
為了測試埠F,我們以開發平台上的4個LED指示燈
的介面電路如下圖所示。其中,LED的點亮是以低
電位驅動的方式。
埠F所連接的4個LED電路圖
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.3 4個LED指示燈的介面電路
以下,列出與本實驗相關的函式:
點亮LED和熄滅LED函式LEDn_ON ()和
LEDn_OFF()相關定義如下:
#define
#define
#define
#define
#define
#define
#define
#define
LED1_ON()
LED2_ON()
LED3_ON()
LED4_ON()
LED1_OFF()
LED2_OFF()
LED3_OFF()
LED4_OFF()
(rGPFDAT &= ~0x10)
(rGPFDAT &= ~0x20)
(rGPFDAT &= ~0x40)
(rGPFDAT &= ~0x80)
(rGPFDAT |= 0x10)
(rGPFDAT |= 0x20)
(rGPFDAT |= 0x40)
(rGPFDAT |= 0x80)
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.3 4個LED指示燈的介面電路
主函式Main
主要程式包括了初始化系統,串列埠,並呼叫跑馬
燈顯示函式。
void Main()
{
rGPFCON=0x5500; /*設置I/O埠GPF7~GPF4為輸出性*/
rGPFUP=0xffff;
/*除能GPF埠的提升功能*/
while(1)
/*無窮迴圈,跑馬燈顯示 */
{
LED1_ON();
//LED1點亮狀態設置
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.3 4個LED指示燈的介面電路
delay(0x2ffff);
LED2_ON();
delay(0x2ffff);
LED3_ON();
delay(0x2ffff);
LED4_ON();
delay(0x2ffff);
LED1_OFF();
delay(0x2ffff);
LED2_OFF();
delay(0x2ffff);
//LED2點亮狀態設置
//LED3點亮狀態設置
//LED4點亮狀態設置
//LED1熄滅狀態設置
//LED2熄滅狀態設置
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.4.3 4個LED指示燈的介面電路
LED3_OFF();
delay(0x2ffff);
LED4_OFF();
delay(0x2ffff);
//LED3熄滅狀態設置
//LED4熄滅狀態設置
}
}
另外,還有一個Init.s組合語言檔案,與上述的程式
範例是一樣的。在此,不再列出。上完整的專案程式
請參考附贈光碟目錄的\ADS\CH7\LED檔案夾。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-
7.5.1 ADS整合開發環境的組成介紹
ARM ADS全名為ARM Developer Suite,是ARM公
司推出的新一代ARM整合開發工具。
現在ADS的最新版本是1.2,取代了早期的ADS1.1和
ADS1.0。
除了可以安裝在Windows NT4,Windows 2000,
Windows 98和Windows 95作業系統下,還支援
Windows XP和Windows Me作業系統。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1 ADS整合開發環境的組成介紹
基本上,ADS由命令列開發工具、ARM執行時
(runtime)函式庫、GUI開發環境(Code Warrior和
AXD)、實用程式和支援軟體組成。
 有了這些模組功能,使用者就可以針對ARM系列的
RISC處理器來編寫或是將自己的開發應用程式加以
除錯了。
由於篇幅的關係,我們僅針對GUI開發環境(Code
Warrior和AXD)來介紹。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
CodeWarrior for ARM是一套完整的整合開發工具,
充分發揮了ARM RISC 的優勢,使產品開發人員能
夠將尖端的系統單晶片系統技術淋漓盡致的發揮出
來。
此工具是專門為以ARM RISC為架構的處理器所設
計的,可以加速並簡化嵌入式系統開發過程中的每
一個環節,使得開發人員只需透過一個整合軟體發
展環境就能開發出ARM應用產品。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
在整個開發週期中,程式開發人員無需跳離
CodeWarrior開發環境,因此節省了在操作工具上所
花費的時間,這也使得開發人員有更多的時間與精
力投入到程式碼的撰寫上。
CodeWarrior整合開發環境(IDE)為管理和開發專案
提供了簡單多樣化的圖形使用者介面。
使用者可以使用ADS的CodeWarrior IDE為ARM和
Thumb處理器開發用C,C++,或是ARM組合語言
的程式碼。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
透過提供下面的功能,CodeWarrior IDE縮短了使用
者開發專案程式碼的週期。其中,包含了:


全方位的專案管理功能。
副程式的程式碼引導功能,讓使用者能迅速找到程式中的
副程式。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
而在CodeWarrior IDE中,所提及的目標(target)
有兩種不同的定義與使用。

目標系統(Target system)
 程式碼要執行的環境是以ARM為架構的硬體。例如,
要在S3C2440開發平台上編寫要執行在其上面的程式,
這個S3C2440開發平台就是目標系統。

產生目標(Build target)
 用於產生特定的目標檔的選項配置(包括組譯選項,編
譯選項,鏈結選項以及鏈結後的處理選項)和所用的檔
案的集合。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
CodeWarrior IDE 能夠讓使用者把來源程式碼檔案,
函式庫檔案還有其他相關的檔案以及配置設定等一
起放在一個專案裡。
每個專案可以開啟和管理產生目標設定的多個配置。
例如,要編譯一個包含除錯訊息的產生目標和一個
以ARM S3C2440為架構的硬體最佳化產生目標,那
麼產生目標就可以在同一個專案中共用檔案,同時
使用各自的設定。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
CodeWarrior IDE為使用者提供下面的功能:
 來源程式碼編輯器

它整合在CodeWarrior IDE的瀏覽器中,能夠根據語法
格式,使用不同的顏色顯示程式碼
 來源程式碼瀏覽器

保存了在源碼中定義的所有符號,能夠讓使用者在來源
程式碼中快速方便的跳躍
 搜尋與取代功能

使用者可以在多個檔案中,進行字串的搜索和取代
 檔案比較功能

可以使使用者比較路徑中的不同文字檔案的內容
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
ADS的CodeWarrior IDE是以Metrowerks
CodeWarrior IDE 4.2版本為架構所發展出來的,其
可經過適當的修改來支援ADS的工具鏈。
針對ARM的配置面板來說,為使用者提供了在
CodeWarrior IDE整合環境下配置各種ARM開發工
具的能力。
以ARM為目標平台的專案開啟精靈,可以讓使用者
以此為基礎,快速開啟ARM和Thumb專案。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
儘管大多數的ARM工具鏈已經整合在CodeWarrior
IDE,但是仍有許多功能在該整合環境中沒有實現,
這些功能大多數是和除錯相關的,因為ARM的除錯
器沒有整合到CodeWarrior IDE中。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
由於ARM除錯器(AXD)沒有整合在CodeWarrior
IDE中,這就意謂著,使用者不能在CodeWarrior
IDE中進行中斷點除錯與查看變數。
對於熟悉CodeWarrior IDE的使用者會發現,有許多
的功能已經從CodeWarrior IDE For ARM中移走,
比如快速應用程式開發範本等。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)
在CodeWarrior IDE For ARM中有很多的功能表或
是子能表是不能使用的。
下面介紹一下這些不能使用的一些選項。

View功能表下不能使用的功能表選項有:
 Processes,Expressions,Global Variable,
 Breakpoints,Registers。

Project功能表不能使用的功能表選項:
 Precompile子功能表。因為ARM編譯器不支援預編譯
的標頭檔。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.1 CodeWarrior整合開發環境(IDE)

Debug選單
 該功能表中沒有一個子功能表是可以使用的。

Browser功能表中不能使用的功能表選項:
 New Property,New Method和New Event Set。


Help menu中不能用於ADS的功能表選項有:
 CodeWarrior Help,Index,Search和Online Manuals。
有關CodeWarrior IDE中一些常用功能表的使用,將
在後面的舉例中具體說明的,在此,不在贅述。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.2 ADS除錯器
除錯器本身是一個軟體,使用者透過這個軟體使用
debug agent可以對於包含有除錯訊息的,且正在執
行的可執行程式碼進行如變數的查看,中斷點的控
制等等除錯的操作。
ADS中包含有3個除錯器:



AXD(ARM eXtended Debugger):ARM擴展除錯器
armsd(ARM Symbolic Debugger):ARM符號除錯器
與舊版本相容的Windows或Unix下的ARM除錯工具,
ADW/ADU(Application Debugger Windows/Unix)
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.2 ADS除錯器
下面對在除錯映像檔案中所涉及到的一些基
本術語做簡單的介紹。
Debug target
 在軟體發展的最初階段,可能還沒有具體的硬體
設備。
 如果要測試所開發的軟體是否達到了預期的效果,
這可以由軟體模擬器來完成。
 即使除錯器以及要測試的軟體執行在同一台PC主
機上,也可以把目標當作一個獨立的硬體來看待。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.2 ADS除錯器
 當然,也可以設計一個電路板,這個電路板上可以
包含一個或多個處理器,然後在這個電路板上可以
執行和除錯應用軟體。
 而只有當透過硬體或者是軟體模擬所得到的結果達
到了預期的效果,才算是完成了應用程式的編寫工
作。
 除錯器能夠傳送以下指令:




下載映像檔案到目標記憶體
啟動或停止程式的執行
顯示記憶體,暫存器或變數的值
允許使用者改變存儲的變數值
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.1.2 ADS除錯器
Debug agent


Debug agent執行除錯器發出的命令動作,比如:設定中斷
點,從記憶體中讀資料,把資料寫到記憶體等。
Debug agent既不是被除錯的程式,也不是除錯器。在
ARM系列中,有這幾種方式,可以實現這個功能:




Multi-ICE(Multi-processor in-circuit emulator)
ARMulator
Angel。
Multi-ICE是一個獨立的產品,是ARM公司自己的JTAG
線上模擬器,不是由ADS提供的。AXD可以在Windows
和UNIX下,進行程式的除錯,其提供了使用C,C++,和
組合語言編寫的來源程式碼提供了一個全面的Windows 和
UNIX 環境。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2 使用ADS IDE開啟專案
本章節將上述的四個LED閃爍的程式為範例,為讀
者介紹如何使用該整合開發環境(IDE),利用
CodeWarrior提供的建立專案範本來建立稍前介紹的
的專案,並學會如何進行編譯鏈結,產生包含除錯
資訊的映像檔案和可以直接燒錄的FLASH中的.bin
格式的二進位可執行檔。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
專案將所有的來源碼檔案整合在一起,並能夠決定
最終產生檔案存放的路徑,輸出的格式等。
而整體操作步驟如下所列:
1.開啟新專案
 在CodeWarrior中新建一個專案的方法有兩種,
可以在工具欄中單擊“New”按鈕,也可以在
“File”功能表中選擇“New…”功能表。此時,會
打開一個如下圖所示的對話方塊。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
在這個對話盒中,提供了7種可選擇的專案類型給使
用者來使用:

ARM Executabl Image:用於由ARM指令的程式碼產生一
個ELF格式的可執行映像檔案。
 ARM Object Library:用於由ARM指令的程式碼產生一
個armar格式的目標檔函式庫。
 Empty Project:用於開啟一個不包含任何函式庫或原始檔
案的專案。
 Makefile Importer Wizard:用於將Visual C的nmake或
GNU make檔案轉入到CodeWarrior IDE 專案檔案中。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案



Thumb ARM Executable Image:用於由ARM指令和
Thumb指令的混和程式碼產生一個可執行的ELF格式的映
像檔案。
Thumb Executable image:用於由Thumb指令開啟一個可
執行的ELF格式的映像檔案。
Thumb Object Library:用於由Thumb指令的程式碼產生
一個armar格式的目標檔庫。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
2. 設定新專案名稱






在這裏選擇ARM Executable Image
在“Project name:”中輸入專案檔案名稱。
在這範例是設定“LEDTest”,以滑鼠按下“Location:”文
本框的“Set…”按鈕流覽選擇想要將該專案存放的路徑。
指定路徑在自訂目錄下:\ADS_Example。
將這些設定好後,點選儲存(S)後,再選擇“確定”,即可
建立一個新專案名稱-LEDTest的專案,如下圖所示。
因為我們已經開啟新的目錄的選項,因此也會產生相同名
稱的子目錄出來。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
3. 新增檔案至專案中



這個時候會出現LEDTest.mcp的視窗,如左圖所示。
包含有三個標籤頁,分別為files,link order與Targets。
預設的是顯示第一個files標籤頁。透過在該標籤頁點選滑
鼠右鍵,選中“Add Files…”可以把要用到的來源檔案新
增到專案中,如右圖所示。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
對於第一個範例,包含了兩個來源檔案,Init.s與
Main.c。
選擇檔案後,以滑鼠按下“開啟”按鈕,即可新增
此檔案。
由於我們已經開啟新專案,因此還會包含一個
LEDTest.mcp專案檔案。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
 在此,需說明的是,在建立好一個專案時,預設的
目標(target)是DebugRel,還有另外兩個可用的目
標(target),分別為Realse和Debug,如下圖所示。
 DebugRel、 Realse 、 Debug這3個目標的含義分別
為:




DebugRel:使用該目標,在產生目標的時候,會為每一個
原始檔案產生除錯訊息
Debug:使用該目標為每一個原始檔案產生最完全的除錯
訊息
Release:使用該目標不會產生任何除錯訊息
在本範例中,使用預設的DebugRel目標,並勾選其他另兩
個目標。但讀者若不需要後面兩種的目標訊息,可以加以
取消。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
這兩個依序新增後,最後專案結果如下圖所
示:
將兩個原始檔案-Init.s與Main.c新增至專案中
到目前為止,一個完整的LEDTest專案已經建
立。以下,即需對此專案進行編譯和鏈結的工
作。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.1 建立一個新專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
在進行編譯和鏈結前,首先敘述一下如何進行產生
目標的配置。
以滑鼠按下Edit功能表,選擇“DebugRel Settings…”
選項(注意,這個選項會因使用者選擇的不同目標而
有所不同),或是直接按下在””DebugRel”目標的
右邊熱鍵-,就會出現如圖所示的對話方塊。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
這個對話方塊中的設定項目很多,在這裏僅介紹一
些最為常用的設定選項。
“Target”設定選項


Target Name:文本框顯示了目前的目標設定。
Linker:選項供使用者選擇要使用的鏈結器。在這裏預設
選擇的是ARM Linker。使用該鏈結器,將使用armlink鏈
結編譯器和組譯器產生的專案所相應的目標檔。這個設定
中還有兩個可選項
None不是不用任何鏈結器,如果使用它,則專案中的所有檔
都不會被編譯器或組譯器處理。
 ARM Librarian表示將編譯或組譯得到的目標檔轉換為ARM
函示庫檔案。對於本專案範例,使用預設的鏈結器為ARM
Linker。

嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
“Target”設定選項


Pre-linker:目前CodeWarrior IDE不支援該選項。
Post-Linker:選擇在鏈結完成後,還要對輸出檔進行的操
作。因為在本範例中,希望產生一個可以燒寫到Flash中的
二進制碼,所以在這裏選擇ARM fromELF,表示在鏈結
產生映像檔案後,再呼叫FromELF命令將含有除錯訊息的
ELF格式的映像檔案轉換成其他格式的檔案。在此,需設
定此選項。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
“Language Settings”設定選項
 ARM Assembler:若有包含組合來源程式碼,就
需要用到組譯器。如圖所示,各種設定的選項。
相關設定請參考ARM C Complier。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
 ARM
C Complier:預設的ARM系列結構是
ARM7TDMI,因此,我們需更改為ARM920T。
位元組順序預設就是小端模式。其他設定,就用
預設值即可,如下圖所示。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
還有一個需要注意的就是ARM C編譯器,它實際就
是呼叫命令列工具-armcc。使用預設的設定就可以
了。
由於有了CodeWarrior,開發人員可以不用再去查看
繁多的命令列選項,只要在介面中選擇或撤銷某個
選項,軟體就會自動產生相應的程式碼,為不習慣
在DOS下鍵入命令列的使用者提供了極大的方便。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
“Linker”設定選項

ARM Linker:選擇ARM Linker,出現如圖所示對話盒。
這裏詳細介紹該對話盒的主要的標籤頁選項,因為這些選
項對最後產生的檔案有著直接的影響。

Output標籤頁:Linktype中提供了3種鏈結方式。
 Partial:表示鏈結器只進行部分鏈結,經過部分鏈結產生
的目標檔,可以作為以後進一步鏈結時的輸入檔。
 Simple:是預設的鏈結方式,也是最為頻繁使用的鏈結方
式,它鏈結產生簡單的ELF格式的目標檔,使用的是鏈結
器選項中指定的位址映射方式。
 Scattered:使得鏈結器要根據scatter格式檔中指定的位址
映射,產生複雜的ELF格式的映像檔案。這個選項在一般
情況下,使用不太多。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
相關參數可以參考下圖所示的設定。因為我們所要
執行範例比較簡單,選擇Simple方式就可以了。在
選擇Simple方式後,就會出現”Simple image”選項。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案

”Simple image”選項
 RO Base:這個文本框設定包含有RO區段的載入區域
和執行區域為同一個位址。在此,需針對S3C2440開發
平台的實際SDRAM位址空間來修改這個位址,保證在
這裏填寫的位址,是程式執行時,SDRAM位址空間所
能覆蓋的位址。因此,需設定為0x30100000。
 RW Base:這個文本框設定了包含RW和ZI輸出區段的
執行區域位址。如果選擇”Split Image”選項,則鏈結
器產生的映像檔案案將包含兩個載入區域和兩個執行區
域。此時,在RW Base中所輸入的位址為包含RW和ZI
輸出區段的區域設定了載入區域和執行區域位址。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案

”Simple image”選項
 Ropi:選擇這個設定將告訴鏈結器使包含有RO輸出段
的執行域位置無關。使用這個選項,鏈結器將保證下面
的操作:



檢查各段之間的重定址是否有效
確保任何由armlink本身產生的程式碼是唯讀位置無關的
Rwpi:選擇該選項將會告訴鏈結器使包含RW和ZI輸出
區段的執行區域位置無關。如果這個選項沒有被選擇的
話,區域就被標識為絕對。每一個可寫的輸入區段必須
是與讀寫位置無關的。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案

”Simple image”選項
 Split Image:選擇這個選項會把包含RO和RW的輸出
區段的載入區域分成2個載入區域:一個是包含RO輸出
區段的區域,一個是包含RW輸出區段的區域。這個選
項要求RW Base需有數值,如果沒有設定RW Base選項
的話,則預設是-RW Base 0。

Relocatable:選擇這個選項保留了映像檔案的重定址偏
移量。這些偏移量為程式載入器提供了有用訊息。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
 Options標籤頁
 如圖所示,為Options標籤頁設定畫面。需要讀者注意
的是Image entry point文本框。它指定ELF映像檔案的
初始入口點位址值。當映像檔案被載入程式載入時,載
入程式會跳轉到該位址處執行。如果需要,使用者可以
在這個文本框中輸入下面格式的入口點,例如,本範例
位址是0x30100000。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
 ARM
fromELF:用來實現將鏈結器,編譯器或組譯
器的輸出程式碼進行格式轉換的功能。例如,將ELF
格式的可執行映像檔案案轉換成可以燒寫到ROM的
二進制格式檔。對輸出檔案進行反組譯,進而可起提
取出有關於目標檔案的大小,符號和字串表以及相關
訊息。如圖所示,為 “ARM fromELF”鏈結器設定操
作畫面設定畫面。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案


在Output format下拉清單中,為使用者提供了多種可以轉
換的目標格式,本例選擇Plain binary,這是一個二進制格
式的可執行檔案,可以燒寫至S3C2440開發平台的Flash中。
在Output file name文本框輸入希望產生的輸出檔案存放的
路徑,或是透過按下”Choose..”.按鈕,從檔案對話方塊中
選擇輸出的二進制bin檔。如果在這個文本框不輸入路徑
名稱的話,則產生的二進制bin檔案就會存放在專案所在
的目錄下。
進行好這些相關的設定後,以後在對專案進行make
的時候,CodeWarrior IDE 就會在鏈結完成後呼叫
fromELF 來處理產生的映像檔案案。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
點選CodeWarrior IDE的功能表Project下的make功
能表,就可以對專案進行編譯和鏈結了。
整個編譯鏈結過程如圖所示。此時在該目錄下的
\DebugRel\中,應該會產生LEDTest.axf 與
LEDTest.bin兩個稍後會用到的兩個檔案。
使用者可檢查是否有產生上敘兩檔案,以驗證是否
稍前的諸多設定是否正確。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.2.2 編譯和鏈結專案
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.5.3 燒錄bin檔案
為了將稍前所編譯成功的LEDTest.bin檔燒錄到開發
平台中,我們需按照下列的步驟依序執行:

兩條纜線連接:
 首先,用串列纜線將PC主機的COM1與開發平台的
UART1連起來,再用USB纜線(A接頭->B接頭)將PC主
機的USB埠與開發平台的USB裝置介面連起來,最後插
上12V電源 。

下載並執行:
 該步驟操作過程與上一章的6.3.2.1小節的執行完整的測
試程式的步驟是類似的。
 觀察實驗結果是否與程式內容相符。實驗結果應該是4
顆LED燈不停的輪流點亮。
 若無法按照程式執行,檢查相關纜線是否正確連接,再
完成此章的實驗練習
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-
7.6除錯工具- Multi-ICE
而透過上一章所使用的DNW應用程式來下載bin檔案,
需要在CodeWarrior IDE下,再跳到另一個應用程式。
除了不便外,也不具除錯的功能。
例如:設定中斷點,從記憶體中讀資料,把資料寫
到記憶體等。因此,需透過Debug agent-MultiICE(Multi-processor in-circuit emulator),
ARMulator和Angel來實現。
在此,我們以Multi-ICE來說明如何使用,以達到除
錯的功能。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
當讀者安裝完Multi-ICE工具軟體後,即可啟動
ARM Multi-ICE Server應用程式。
一開始,Multi-ICE Server可能還無法透過JTAG連
接上S3C2440核心。因此,需透過下載配置檔來啟動。
在安裝後的目錄下(\program Files\ARM\MultiICE\),包含一個配置檔single.cfg。這檔案的內容,
需根據所要使用的ARM核心來更改。
由於S3C2440的核心是ARM920T。因此,在TAP0項
目下,需變更為ARM920T。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
修改內容
;Single ARM920T
[Title]
Single ARM920T Configuration example
[tap 0]
ARM920T
[Timing]
Low=0
High=0
Adaptive=OFF
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
如圖所示,當讀者更改完,就可透過File選單,選
擇”Load Configuration”選項來下載剛剛修改完的
single.cfg。不過之前,讀者需將Multi-ICE的20-pin
JTAG排線接到開發平台的上。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
當下載完畢後,若是正確連接上,此時,就會如下
圖所示,顯示出綠色的ARM920T。若是執行時,則
會呈現紅色字樣。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
當Multi-ICE正確連結時,讀者即可進入
CodeWarrior IDE,並打開LEDTest專案檔。然後按
下熱鍵F5或是按下 除錯按鈕。此時,就會切換到
AXD除錯環境下。若是正確的話,在左邊的的視窗
中,會在Target標籤頁上,呈現出如下圖所示的畫面,
代表以正確連接。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.6除錯工具- Multi-ICE
反之,則會如圖所示,呈現錯誤訊息。而正確連接
Multi-ICE,及進入AXD開發環境後,讀者即可在視
窗的左下方看到下列的訊息。其中,包含了除錯的
Debug agent(Multi-ICE),ARM核心(ARM920T)與
除錯檔(LEDTest.axf)。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.1
7.2
7.3
7.4
7.5
7.6
7.7
大綱
ARM編譯器所支援的虛擬指令
組合語言的語法
組合語言的程式結構
GPIO程式設計與應用
ADS使用環境與實驗步驟
除錯工具- Multi-ICE
討論
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
P-
7.7 討論
本章介紹了ARM程式設計的一些基本概念,
以及在組合語言程式設計中常見的虛擬指令、
組合語言的基本語句格式等,組合語言程式的
基本結構等,同時簡單介紹了C和組合語言的
混合撰寫等問題。最後,我們以埠F所連接的
LED跑馬燈來介紹相關程式的設計撰寫。讀
者可以以此範例來作為稍後更複雜的程式撰寫
的基礎。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和
7.7 討論
問題與討論

請讀者重新編譯本章的LED閃爍的範例,並驗證是否能在
開發上執行LED閃爍的動作。

請讀者以新專案設計,並設定閃爍的延遲時間,是否符合
所設定的延遲時間長短。

請讀者設計埠F的4顆LED執行左旋,然後再右旋的動作。
但須注意到,這4顆LED的排列不是有規則的,從左至右:
LED3,LED4,LED1與LED2。
嵌入式系統概論-以S3C2440核心為架構 copyright @ 許永和