以下裸機程式基於gt2440,編譯器為arm-linux-gcc-4.4.3。
程式結構:程式由sdram.s和main.c兩個檔案組成,sdram.s檔案完成一些初始化工作,如時鐘初始化,記憶體控制器初始化,拷貝第二階段**到sdram等;main.c負責迴圈點亮、熄滅四個led。
程式流程:上電時,cpu自動跳到復位異常向量入口,在復位異常處理裡首先關閉看門狗,接著初始化系統時鐘,初始化記憶體控制器,拷貝第二階段**到sdram,最後跳轉到sdram裡執行main()函式。
sdram.s:
1#define mem_reg_start 0x48000000
2#define sdram_base 0x3000000034
#define locktime 0x4c000000
5#define mpllcon 0x4c000004
6#define upllcon 0x4c000008
7#define clkdivn 0x4c000014
8#define camdivn 0x4c000018910
#define wtcon 0x53000000
1112
13.section .text
14.global _start
15_start:
16b reset
1718
@復位異常處理
19reset:
20@關閉看門狗
21bl disable_watchdog
22@初始化時鐘
23bl init_clock
24@初始化記憶體控制器
25bl init_sdram
26@拷貝第二階段**到sdram
27bl copy_to_sdram
2829
ldr pc,=on_sdram
30on_sdram:
31@設定棧指標
32ldr sp,=0x34000000
33@跳到main()函式
34bl main
35loop:
36b loop @死迴圈
3738
39disable_watchdog:
40ldr r0,=wtcon
41bic r1,r0,#0x20
42str
r1,[r0]
4344
movpc,lr
4546
init_clock:
47ldr r0,=locktime
48ldr r1,=0x00ffffff
49str
r1,[r0]
50@時鐘分頻1:
4:851
ldr r0,=clkdivn
52ldr r1,=0x05
53str
r1,[r0]
54@非同步匯流排模式
55 mrc p15,0,r1,c1,c0,0
56orr r1,r1,#0xc0000000
57 mcr p15,0,r1,c1,c0,0
58@fclk=400mhz,hclk=100mhz,pclk=50mhz
59ldr r0,=mpllcon
60ldr r1,=0x5c011
61str
r1,[r0]
62@upll=48mhz
63ldr r0,=upllcon
64ldr r1,=0x38022
65str
r1,[r0]
6667
movpc,lr
6869
copy_to_sdram:
70 ldr r0,=2048
@要拷貝的**的起始位址 (源位址)
71ldr r1,=sdram_base @要拷貝到的位址(目的位址)
72add r3,r0,#2*1024 @拷貝大小(2k)73
copy_loop:
74 ldr r2,[r0],#4
75str r2,[r1],#4
76cmp
r0,r3
77bne copy_loop
7879
movpc,lr
8081
init_sdram:
82ldr r0,=mem_reg_start
83adrl r1,mem_cfg_val
84add r2,r0,#52 //13個暫存器,每個佔4位元組(13*4)85
mem_cfg_loop:
86 ldr r3,[r1],#4
87str r3,[r0],#4
88cmp
r0,r2
89bne mem_cfg_loop
9091
movpc,lr
9293
@暫存器配置值
94 .align 4
95mem_cfg_val:
96.long 0x22011110 //bwscon
97.long 0x00000700 //bankcon0
98.long 0x00000700 //bankcon1
99.long 0x00000700 //bankcon2
100.long 0x00000700 //bankcon3
101.long 0x00000700 //bankcon4
102.long 0x00000700 //bankcon5
103.long 0x00018005 //bankcon6
104.long 0x00018005 //bankcon7
105.long 0x008c04f4 //refresh(hclk=100mhz)
106.long 0x000000b1 //banksize
107.long 0x00000030 //mrsrb6
108 .long 0x00000030 //mrsrb7
main.c:
1#define gpbcon (*(volatile unsigned long *)0x56000010)
2#define gpbdat (*(volatile unsigned long *)0x56000014)
3#define gpbup (*(volatile unsigned long *)0x56000018)45
#define ngpb_output ((1<<10)|(1<<12)|(1<<14)|(1<<16))67
//延時函式
8void
delay()915
16//
main函式
17int main(void)18
2930
return0;
31 }
makefile:
1 objs :=sdram.s main.c23sdram.bin:$(objs)
4 arm-linux-gcc -c -o sdram.o sdram.s
5 arm-linux-gcc -c -o main.o main.c
6 arm-linux-ld -tsdram.lds -o sdram_elf
7 arm-linux-objcopy -o binary -s sdram_elf sdram.bin89
clean:
10 rm -f sdram_elf sdram.bin *.o
1sections
24 sdram 0x30000000 : at(2048
) 5 }
ARM 裸機 02 ARM裸機開發流程
執行在不同平台上的程式,開發過程不盡相同。為了更好地理解 arm 裸機的開發流程,我們先和比較熟悉的 windows linux 應用程式開發對比。不同平台程式開發流程對比示意 編譯嵌入式程式的平台稱為宿主機,譬如執行 ubuntu 系統的 pc。執行嵌入式程式的平台稱為目標機,譬如 arm 開發板...
ARM裸機開發快速體驗
一。linux平台 自己寫makefile 自己寫lds指令碼 自己搭建除錯環境 二。裸機開發流程 1 編寫裸機程式 2 除錯裸機程式 3 編譯 鏈結 格式轉換成二進位制映像 1.安裝交叉工具鏈 把課程裡面的工具包拷貝到linux,解壓arm linux gcc到根目錄 c 交叉工具在usr loc...
ARM裸機開發(五)SPI
以下裸機程式基於gt2440,編譯器為arm linux gcc 4.4.3。程式結構 本程式只有乙個spi.s檔案。程式流程 首先上電復位進入復位異常,在復位異常裡依次呼叫子程式關閉看門狗 初始化系統時鐘 初始化串列埠,最後呼叫spi傳送資料,spi傳送的資料在程式裡指定,對於本程式傳送資料為乙個...