ARM啓動過程詳解

前言:本人因工作需要,首次接觸到了ARM單片機,但因無人指導,走了不少彎路。下面這些筆記是我在一個多月的學習過程中總結的一點心得(可能比較亂,工作忙,沒時間整理,各位朋友莫怪!),現在發到網上,與各位網友共享,希望對大家有點小小的幫助。本人購買的是上海勤研電子提供的ARM實驗板,使用三星的S3C44B0X芯片,我在學習過程寫的一些程序也參考了他們隨板提供的一些源代碼,特此致謝!

關於ARM和嵌入式我仍是個新手,下面的東東有些可能是錯的。因此僅供參考!!並希望網友給予指正。也歡迎各位網友來信共同交流。

 

 

 

系統初始化流程如下:

禁止看門狗——》在中斷控制器中屏蔽所有中斷——》系統時鐘設置——》初始化端口——》DMA設置——》cashe和總線設置——》存儲器設置,初始化SDRAM——》初始化堆棧——》設置IRQ和FIQ的入口——》地址重映射

   

    通常系統初始化有兩個階段組成,分別爲彙編和C寫成。彙編應儘量簡單一些,把更多的任務交給C來做,這樣可增加整個程序的可讀性和靈活性。必須由彙編來完成的任務有:異常中斷向量表的設置、IRQ向量表(向量模式)或ISR初始化(非向量模式)、二級ISR地址表的定義、Flash和SDRAM的設置(否則系統無法加載代碼)、堆棧設置和模式切換、拷貝RW和ZI代碼、設置系統時鐘等。而端口初始化、cashe和總線的設置、DMA配置以及其它控制器如LCD、UART、SIO、IP等可以在C中第二階段初始化程序完成,另外也可以繼續更改時鐘或存儲器配置等。下面是幾個關鍵步驟配置的注意事項。

 

看門狗設置

    watch dog即可以作爲普通的timer以產生週期性的中斷,也可以週期性的產生reset信號(如果每隔一定時間不被清除的話),以防治程序跑飛。

 

系統時鐘的初始化:

至少設置三個寄存器:LOCKTIME,PLLCON,LOCKCON。

LOCKTIME,地址0x01D8000C。用於指定PLL的初始化時間,在PLL初始化時,系統時鐘爲晶振輸入或外部時鐘直接提供,即MCLK=Fin;初始化完成後,切換,MCLK=Fout。初始值爲0xfff=4095個輸入時鐘週期。一般將其設爲初始值。

PLLCON,,地址0x01D80000。設置MDIV,PDIV,SDIV三個值,用於確定Fout和Fin的頻率分配比值:Fout = (m * Fin) / (p * 2s),其中

m = (MDIV + 8), p = (PDIV + 2), s = SDIV

典型的幾個值如下:

No.FinFoutMDIVPDIVSDIV

110Mhz40Mhz0x480x30x2

210500x2a0x30x1

310600x340x30x1

44600x340x00x1

53600x480x00x1

610750x3a0x30x1

 

 

CLKCON,地址0x01D80004。用於設置是否向外設提供時鐘,一般設爲默認值0x7ff8,即所有外設提供時鐘。

 

存儲器初始化(尤其是SDRAM):

ARM7TDMI的地址映射如下:

(在ARM體制中,所有的各種內、外存儲器,外設,寄存器,cashe,write buffer,通用IO口等全都採用統一編址)

注:0x10000000~0x100047f0爲內部cashe/sram 及其Tag和LRU的地址。

 

BANK0~BANK5爲ROM/SRAM/FLASH,

BANK6~BANK7爲SDRAM/ROM/SRAM/FLASH

要設置的寄存器如下:

BWSCON:BANK0~BANK7的UB/LB使能、Wait信號使能、數據線寬度;

BANKCON0~BANKCON5:各bank(flash或Sram)的訪問時序控制。flash或Sram主要參數如下所示:

Tacs [14:13] Address set-up before nGCSn

Tcos [12:11] Chip selection set-up nOE

Tacc [10:8] Access cycle

Toch [7:6] Chip selection hold on nOE

Tcah [5:4] Address holding time after nGCSn

Tpac [3:2] Page mode access cycle @ Page mode

PMC [1:0] Page mode configuration

不同廠家、性能、速度的器件設置有所不同。

BANKCON6~BANKCON7:主要用於SDRAM,當然也可以是Flash或SRAM。SDRAM的時序控制稍微複雜,還有:

Trcd [3:2] RAS to CAS delay

    SCAN [1:0] Column address number

當然也可用於DRAM。

 

REFRESH 地址: 0x01C80024,DRAM/SDRAM的更新控制寄存器;

MRSRB6 ~MRSRB7:DRAM/SDRAM的模式控制寄存器,這個寄存器在系統初始時,即SDRAM使用前必須被有效地的設置。

    這幾個寄存器的設置比較複雜,應仔細閱讀Samsang(page168)的數據手冊和相關存儲器的資料。

一個典型的配置如下:

ldr r0, =SMRDATA

ldmia r0, {r1-r13}

ldr r0, =0x01c80000 ; BWSCON Address

stmia r0, {r1-r13}

SMRDATA DATA

DCD 0x11222220 ; BWSCON Bank0=OM[1:0],8bits寬 Bank1~Bank5=32bit,Bank6~Bank=16bit,不使用UB/LB信號,WAIT disable; 使用little Endian存儲格式

DCD 0x000056A8; GCS0 :Tacs=2clk;Tcos=2clk;Tacc=10clk;

Toch=2clk;Tcah=2clk;Tpac=4clk;PMC=normal(1data)

DCD 0x00000700 ; GCS1 除了Access cycle爲14個clk外,其它均爲0clk

DCD 0x00000700 ; GCS2

DCD 0x00000700 ; GCS3

DCD 0x00000700 ; GCS4

DCD 0x00000700 ; GCS5

DCD 0x00018005 ; GCS6, SDRAM;RAS to CAS delay 2 clk;Column address number:9bits

DCD 0x0001002a ; GCS7, EDO DRAM(Trcd=3, Tcas="2", Tcp="1", CAN="10bit")

DCD 0x00870441 ; Refresh enable;Auto Refresh; Trp="3", Trc="5", Tchr="3";

刷新計數:1019

DCD 0x17 ; SCLK power down mode enable;Bank6&7 Size, 16MB/16MB

DCD 0x20 ; MRSR 6:CAS Latency="2clk";burst type爲線性(不支持交織訪問);

burst number:1bit(不支持促發讀寫)

DCD 0x20 ; MRSR 7(CL=2)

 

注:三星的實驗板中在nGCS0外接Flash,型號爲SST39VF160,其datasheet中有其讀寫時序的詳細說明和各種時間值的最大或最小值,但均以ns爲單位,且各時間值的名稱也與寄存器的要求不完全相同。要使Flash達到最優設置,必須讀懂其時序並按其推薦值設置寄存器。顯然這並不是件容易的事情。在本次實驗板的boot程序中,其各時序值均是最大值給出。參見memcfg.h文件。

三星的實驗板中在nGCS6外接SDRAM,型號爲IC42S16800-7T,(4096ROW*512COLUM*4Bank*16bits=128Mbits=16MB)

由上面的例子可以看出需要設置的參數爲:1.Banksize,UB/LB,WAITenable/disable,large/little Endian;

2.RAS to CAS delay, Column address number;

3.Refresh enable/disable,Auto/self refresh, SDRAM RAS pre-charge Time, SDRAM RC minimum Time, Refresh Counter;

4.power down mode,banksize;

4.CAS Latency,burst type,burst number。

 

Refresh counter的設置:Refresh period = (211-refresh_count+1)/MCLK

Ex) If refresh period is 16 us and MCLK is 60 MHz,

the refresh count is as follows;

refresh_count = 211 + 1 - 60x16 = 1089

 

上面的例子只是對Flash和SDRAM的一個經驗設置值,可能不是最優的。最優設置還必須參考器件的數據手冊。尤其是對於SDRAM的RAS to CAS delay、SDRAM RAS pre-charge Time、SDRAM RC minimum Time三個時序值。

 

特別注意:在線調試階段,在AXD軟件中必須引入對SDRAM初始化的seesion文件或ini文件,或者在command interface中敲入所需的配置命令(在load image之前完成),並且最後註釋掉reset彙編程序中的初始化SDRAM的命令。否則程序就可能跑飛。而生成要下載的flash程序代碼時,則系統reset時就必須完成此功能。

 

端口初始化

ARM的大部分信號在同一端口是功能複用的。爲此初始化時必須指定各PA~PG口的各管腳的功能。在實驗板根據外圍器件的選擇對各端口做如下配置:

PA(10bits):全部用作高端地址線;PCONA=0x3ff

PB(11bits):全部用作存儲器控制信號;PCONB=0x7ff

PC(16bits):4~7用於LCD的VD4~VD7;12,13用於UART的TXD1,RXD1(注意:這裏的UART沒有使用CTS、RTS信號,只用了TX、RX);其它全部用於通用IO口,GPC0~3用於IIS;GPC10和14用於NAND Flash;GPC15用於USB Device;GPC8、9用於LCD;GPC11暫時沒用。PCONC=0x5f55ff55.(這裏假定IO口全爲output,實際應用時再確認一下是In或是out)

PD(8bits):全部用於LCD的控制信號。PCOND=0xaaaa。

PE(9bits):8用於Endian,確定存儲器格式;1,2分別爲TXD0,RXD0;0,3~7用於通用IO口(暫定output),PE3用於蜂鳴器;PE4~7用於LED顯示。PCONE=0x05569。

PF(9bits):0、1用於IIC總線的SCK、SDA信號;其它均爲通用IO口(暫定output),其中GPF2~4用於IDE,GPF5~8用於觸摸屏。PCONF=0x09255a。

PG(8bits):全部用於外部中斷EXINT0~7。PCONG=0xffff。

注意:上述端口分配是S3C44b0x測試板(勤研電子)的分配情況。

 

另外還有下面幾個寄存器需要設置:

上拉電阻寄存器,包括一些端口和數據線;

EXTIN:設置8個外中斷的觸發方式,low,high,rising or falling edge等。

EXTINTPND:中斷待處理寄存器,用於解決EXTINT4~7共享一箇中斷源的問題。

 

 

Cache&Bus設置

通過內部寄存器可以設置cashe mode(cashe和sram),write buffer,non-cashable area,以及bus的優先級等。

通常,在一般的用戶程序中不使用cashe(即全部用作Sram),禁用write buffer,bus優先級選擇默認就可以了,即1. DRAM refresh controller-2. LCD_DMA-3. ZDMA0,1-4. BDMA0,1-5. External bus master-6. Write buffer-7. Cache & CPU。

只配置一下SYSCFG:0x0。

 

 

DMA配置

ZDMA在系統總線上,完成系統總線上器件的數據傳送,如存儲器。BDMA也有2個,橋接系統總線和外設總線,即可以完成分別位於兩條總線上的器件的數據傳送,也可完成外設總線上器件如SIO、UART、TIMER等之間數據傳送。

DMA的四種數據傳送方式。

DMA的觸發選擇:XDREQ/XDACK、S/W、H/W等。

一般地,DMA的初始化只需完成BDMA的目標地址寄存器的初始化:BDIDES0,1=0x40000000,即傳送方向爲內部存儲器到外設,初始目的地址:0x0。

 

 

 

中斷寄存器的配置和中斷向量表的設計

中斷有兩種IRQ和FIQ,後者優先級高於前者。另外,ARM系統還做了些特殊安排以使FIQ有更快的響應速度,如FIQ的ISR可以直接放在0x1c(緊跟FIQ)開始的地址單元中,免去了跳轉;屬於FIQ的中斷向量表可常駐cashe;FIQ較IRQ有更多的物理寄存器等。通常在簡單的用戶程序中,可以不使用FIQ,所有中斷都設爲IRQ(默認情況)。

ARM7有30箇中斷源,實際使用25個。其優先級如下所示:

 

一些重要的中斷設置寄存器如下:

INTCON  0x01E00000 :中斷控制。指定IRQ是否採用向量模式(一般採用非向量模式,這也是默認值)。指定CPU是否響應IRQ和FIQ。

INTPND:只讀。指定中斷源是否有中斷請求,可以同時有多箇中斷請求。當對應的ISR結束時,通過向I_ISPC和F-ISPC寫1來清除INTPND中對應的比特位,否則該中斷將連續執行。

INTMSK:各中斷源是否屏蔽。初始值時屏蔽。

INTMOD:指定各中斷源是IRQ或FIQ,默認值全爲IRQ。

I_PSLV:  0x01E00010   R/W    IRQ priority of slave register  0x1b1b1b1b

I_PMST:  0x01E00014   R/W    IRQ priority of master register  0x00001f1b

I_CSLV:  0x01E00018   R       Current IRQ priority of slave register  0x1b1b1b1b

I_CMST:  0x01E0001C  R       Current IRQ priority of master register  0x0000xx1b

I_ISPR:   0x01E00020   R      IRQ interrupt service pending register

I_ISPC:   0x01E00024   W      IRQ interrupt service clear register

F_ISPC:   0x01E00024   W      FIQ interrupt service clear register

優先級取默認值就可以了。

ISPR只讀,指示當前被響應的中斷源,沒有或只有一個被響應,儘管此時INTPND中可能有幾個中斷請求。ISR結束時,通過向ISPC對應位寫1來清除ISPR中的對應位。

在ARM7TDMI中,中斷向量表的設置有兩種模式:向量模式和非向量模式。前者只適於全IRQ的設置。採用非向量模式時,通過分析ISPR(發生中斷時,其中只有一個位爲1,其它全爲0)找到要執行的ISR的入口地址。在向量模式中,當發生IRQ時,CPU自動產生跳轉地址,如同異常中斷的使用。各IRQ的一級ISR的跳轉地址如下:

中斷有異常中斷(如:Dabort、Pabort、Undef等)和IRQ或FIQ兩種。下面以向量模式下的IRQ爲例介紹一下中斷設置。

過程如下:IRQ中斷向量表設置——>寫一級ISR——>分配二級ISR的入口地址表——>寫二級ISR——>把二級ISR的入口地址放到二級ISR的入口地址表中。這樣在開中斷的情況下,一個ISR就可以正常執行了。一個ISR的執行過程如下。

首先要在系統初始化時開中斷:INTMSK各中斷位清零且INTCON的IRQ位清零(使能)且CPSR的I比特清零(使能),缺一不可。中斷髮生時,首先由模式SYS或User切換至IRQ,同時完成現場保護(工作指針入棧、保存CPSR、PC->LR),然後PC直接跳到IRQ中斷向量表的相應地址(一級ISR的入口),緊接着跳到一級ISR並執行;一級ISR通常由彙編寫成,僅完成一個跳轉任務(有時也看一下寄存器ISPR,判斷該中斷是否被錯誤觸發,如果錯誤將直接返回),即從二級ISR的入口地址表中找到相應中斷的入口地址,其間工作現場沒有變化。二級ISR通常由c語言寫成,中斷的真正的響應程序就在此處。ISR結束時,要對INTMSK中的pending比特清零(通過置位ISPR中相應比特),否則將連續響應該中斷。然後CPU自動切換至中斷前的工作模式,並恢復現場。

 

在C語言中關鍵字”__irq”的作用:當ISR定義時有此關鍵字,則ISR結束後CPU自動從棧中恢復中斷前模式的LR,並把它賦值給PC,完成ISR的正常返回。如果無此關鍵字,則CPU只能返回到二級ISR前的中斷狀態,此時仍爲IRQ工作模式。當然也能夠繼續執行用戶程序,只是工作模式不對,此模式下再不能響應其它IRQ中斷。

事實上,CPU響應中斷並執行ISR相當於一個程序調用過程。用戶程序不必干預CPU的模式切換、現場保護、程序返回。

 

中斷向量表的設置。一級中斷向量表緊跟異常中斷向量表,位於0x20~0xc0。只讀。由於S3C44b0x沒有MMU和地址映射功能,該中斷向量表必須和異常中斷向量表一起固化到系統地址空間的0x0處,即Flash的起始處。在線調試階段也必須保證該表存在於Flash中。二級ISR的地址表一般位於RAM空間的最後256個字節處,緊跟在堆棧後,在彙編語言中由MAP語句創建(8個異常中斷和25個IRQ,共33×4=132Byte),可讀寫。同時在c中定義一組指向相同地址空間的無符號型指針,當然指針名稱必須和彙編中的定義相同。這樣在C中的ISR初始化程序中,可直接把二級ISR的入口放到地址表中。如:pISR_EINT0=(unsigned)Isr_Eint0; pISR_EINT0爲地址表中的指針,而Isr_Eint0爲ISR的名稱,也是其入口地址。二級ISR地址表和一級表不同的是,其各中斷的順序可任定,但必須保證彙編和C中的定義一致。

對於非向量模式,不使用IRQ中斷向量表,但二級ISR地址表的設置是相同的。在本測試程序中boot.s同時包含了兩種格式的設置,只要設置好INTCON中的mode比特,兩種模式都可以用。注意非向量模式,在彙編中要設置IRQ和FIQ的入口地址。因爲在非向量模式要靠IsrIRQ和IsrFIQ來定位響應的中斷源位置。

    另外,爲了保證開中斷後,程序不至於跑飛,最好編寫所有的IRQ 的ISR,該ISR可以是個空函數,確保能正常返回就行了。

 

堆棧初始化和工作模式的切換

ARM7TDMI有7種工作模式,要用到6個stack,其中SYS和User共用一個Stack。堆棧設置採用流行的FD模式(full decresment)。通常放在RAM空間的次最高段(最高的256B爲ISR的地址表),在16M的SDRAM中,各stack設置如下:

0x0cff_f000~0x0cff_fa00: Uers and SYS stack,2560B,夠大了。

0x0cff_fa01~0x0cff_fb00: SVC stack, 256B;

0x0cff_fb01~0x0cff_fc00: Undef stack, 256B;

0x0cff_fc01~0x0cff_fd00: Abort stack, 256B;

0x0cff_fd01~0x0cff_fe00: IRQ stack, 256B;

0x0cff_fe01~0x0cff_ff00: FIQ stack, 256B;

0x0cff_ff01~0x0cff_ffff: ISR地址表, 256B;

 

CPU的模式切換通常由異常中斷產生,或者在SVC或SYS模式下完成。User模式中用戶程序不能改變工作模式(除了應用異常中斷,如SWI),當然也不能改變CPSR的值(也就不能開關中斷了!)。通常如果不用嵌入式OS,單任務的用戶程序工作在SYS或SVC模式下更好一些,這樣可以更方便的使用硬件資源。如果使用SVC模式,甚至可以不設置SYS and User stack。

系統加電重起時,首先進入SVC模式,完成初始化,在調用C的main函數之前再切換到SYS或User模式。因此可以把堆棧初始化放到最後執行,並最後設置SYS stack,這樣進入main之後可以直接工作在SYS模式下。本測試程序就是如此設置的。

 

 

 

分佈式加載

ADS1.2中的ARM linker支持分佈式加載,即加載域(load)和執行域(image)的各個輸出段(RO、RW、ZI)可以有不同的地址。可以很方便的生成供在線調試和下載的elf格式的文件。通常總線調試只需設置RO base=0x0c000000;而生成下載代碼則要設置RO base=0x0,RW base=0x0c000000,並且一定要把boot.o設成first section,否則程序入口不在0x0則無法完成異常中斷和普通中斷,包括reset。至於ropi、rwpi、split的應用參見linker的有關資料。

鏈接器同時產生一組符號,給出各個域或者各個輸出段的區間的長度,裝載地址和執行地址。由於鏈接器和C庫都沒有將代碼從它的裝載區間拷貝到執行區間,或創建一個零初始化區域的功能,所以要由應用程序員利用這組符號產生的信息完成這項工作,這是在呼叫C程序之前必須完成的,舉例如下:

LDR r0, = |Load$$DRAM$$Base|

LDR r1, = |Image$$DRAM$$Base|

CMP r0, r1  檢查裝載地址和執行地址是否相同

BEQ do_zi_init  相同,則不拷貝該區間,初始化零數據區

MOV r2, r1 ; 不相同,將裝載區拷貝到執行區

LDR r4, = |Image$$DRAM$$length|

ADD r2, r2, r4

BL copy

do_zi_init

LDR r1, = |Image$$DRAM$$ZI$$Base|

MOV r2, r1

LDR r4, = |Image$$DRAM$$ZI$$length|

ADD r2, r2, r4

MOV r3, #0

BL zi_init  調用零初始化子程序

 

上例中使用了ARM Linker產生的與域有關的幾個符號

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> <script language="JavaScript1.1" src="http://pagead2.googlesyndication.com/cpa/ads?client=ca-pub-9447242586152886&cpa_choice=CAEQ9cm1_wEQABoIrVSJdtyXBh0o6bzhhwEo6bzhhwEwAA&oe=gb2312&dt=1188974542218&lmt=1188974542&format=ref_text&output=textlink&correlator=1188974542171&url=http%3A%2F%2Fwww.icwin.net%2Fbbs%2Fdispbbs.asp%3FboardID%3D61%26ID%3D4803%26keywords%3Darm%25E7%25AB%25AF%25E5%258F%25A3%25E8%25AE%25BE%25E7%25BD%25AE%25E7%25AD%2589....html&region=_google_cpa_region_&ref=http%3A%2F%2Fwww.google.cn%2Fsearch%3Fcomplete%3D1%26hl%3Dzh-CN%26inlang%3Dzh-CN%26newwindow%3D1%26q%3DUB%252FLB%25E4%25BF%25A1%25E5%258F%25B7%25E7%259A%2584%25E4%25BD%259C%25E7%2594%25A8%26meta%3D%26aq%3Dnull&cc=4&ga_vid=1143094070.1188974542&ga_sid=1188974542&ga_hid=495889518&flash=9&u_h=768&u_w=1024&u_ah=738&u_aw=1024&u_cd=32&u_tz=480&u_java=true" type="text/javascript"></script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章