日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2024年11月08日(星期五)

正在發(fā)生

2019年11月08日 | ARM9學(xué)習(xí)4-S3C2410的啟動(dòng)代碼分析-For ADSv1.2

發(fā)布者:自由夢想 來源: 51hei關(guān)鍵字:ARM9  S3C2410  啟動(dòng)代碼  ADSv1 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

通常,啟動(dòng)代碼是指CPU復(fù)位后到進(jìn)入C語言的main函數(shù)之前需要執(zhí)行的那段匯編代碼.這是由于C語言程序的運(yùn)行需要具備一定的條件,比如:分配好外部數(shù)據(jù)空闿堆??臻g和中斷入口等筿另外匯編代碼可以更直接的對硬件進(jìn)行操使效率更高. 通常啟動(dòng)代碼是放在2410init.s匯編文件;特殊功能寄存器定義在2410addr.s;Memory Bank 配置在mencfg.s;還有系統(tǒng)的選項(xiàng)等在option.s文件;2410init.s不僅包括復(fù)位后執(zhí)行的代碼,還包括CPU進(jìn)入掉電模式,產(chǎn)生中斷等和處理器直接相關(guān)的,用匯編實(shí)現(xiàn)的代碼.
;=========================================
; NAME: 2410INIT.S
; DESC: C start up codes
;       Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,POWER_OFF mode
; 2003.05.19:jcs:Configure UPLL in init.s not usbmain.c
;=========================================
  //首先,啟動(dòng)代碼定義了一些常量 ,相當(dāng)于C中的INCLUDE
GET option.inc
GET memcfg.inc
GET 2410addr.inc

BIT_SELFREFRESH EQU (1<<22) //自刷新常量
//;;處理器模式常量 
USERMODE    EQU  0x10
FIQMODE     EQU  0x11
IRQMODE     EQU  0x12
SVCMODE     EQU  0x13
ABORTMODE   EQU  0x17
UNDEFMODE   EQU  0x1b
MODEMASK    EQU  0x1f  //系統(tǒng)模式
NOINT           EQU  0xc0  //屏蔽所有的中斷,即置位I,F(xiàn)位
//;The location of stacks 定義處理器各模式下堆棧地址常量 
UserStack        EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ 
SVCStack        EQU (_STACK_BASEADDRESS-0x2800)  ;0x33ff5800 ~
UndefStack      EQU (_STACK_BASEADDRESS-0x2400)  ;0x33ff5c00 ~
AbortStack       EQU (_STACK_BASEADDRESS-0x2000)  ;0x33ff6000 ~
IRQStack         EQU (_STACK_BASEADDRESS-0x1000)  ;0x33ff7000 ~
FIQStack         EQU (_STACK_BASEADDRESS-0x0)        ;0x33ff8000 ~ 
;check if tasm.exe is used.
;arm處理器有兩種工作狀態(tài) 1.arm:32位 這種工作狀態(tài)下執(zhí)行字對準(zhǔn)的arm指令 2.Thumb:16位 這種工作狀態(tài)執(zhí)行半字對準(zhǔn)的Thumb指令
;因?yàn)樘幚砥鞣譃?6位 32位兩種工作狀態(tài)程序的編譯器也是分16位和32兩種編譯方式 所以下面的程序用于根據(jù)處理器工作狀態(tài)確定編譯器編譯方式
;code16偽指令指示匯編編譯器后面的指令為16位的thumb指令
;code32偽指令指示匯編編譯器后面的指令為32位的arm指令
;這段是為了統(tǒng)一目前的處理器工作狀態(tài)和軟件編譯方式(16位編譯環(huán)境使用tasm.exe編譯)
GBLL THUMBCODE ;設(shè)置一個(gè)全局邏輯變量
[ {CONFIG} = 16 ;if config==16 這里表示你的目前處于領(lǐng)先地16位編譯方式,{CONFIG}為匯編器內(nèi)置變量
THUMBCODE SETL {TRUE} ;設(shè)置THUMBCODE 為 true
CODE32 ;轉(zhuǎn)入32位編譯模式
|      ;else
THUMBCODE SETL {FALSE} ;設(shè)置THUMBCODE 為 false

[ THUMBCODE     ;if THUMBCODE==TRUE
CODE32          ;for start-up code for Thumb mode;轉(zhuǎn)入32位編譯方式
]

;注意下面這段程序是個(gè)宏定義 很多人對這段程序不理解 我再次強(qiáng)調(diào)這是一個(gè)宏定義 所以大家要注意了下面包含的HandlerXXX HANDLER HandleXXX將都被下面這段程序展開。

;這段程序用于把中斷服務(wù)程序的首地址裝載到pc中,有人稱之為“加載程序”。其大致作用是把宏的第一個(gè)參數(shù)$HandlerLabel轉(zhuǎn)變?yōu)橐粋€(gè)標(biāo)號(hào),然后讓程序跳轉(zhuǎn)到第二個(gè)參數(shù) $HandleLabel(第二個(gè)參數(shù)應(yīng)該為一個(gè)地址)對應(yīng)的值的地址去??梢苑治龀?,sp和r0在執(zhí)行前后都沒有變化,程序就實(shí)現(xiàn)了跳轉(zhuǎn)

;本初始化程序定義了一個(gè)數(shù)據(jù)區(qū)(在文件最后),34個(gè)字空間,存放相應(yīng)中斷服務(wù)程序的首地址。每個(gè)字空間都有一個(gè)標(biāo)號(hào),以Handle***命名。

;在向量中斷模式下使用“加載程序”來執(zhí)行中斷服務(wù)程序。

;這里就必須講一下向量中斷模式和非向量中斷模式的概念

;向量中斷模式是當(dāng)cpu讀取位于0x18處的IRQ中斷指令的時(shí)候,系統(tǒng)自動(dòng)讀取對應(yīng)于該中斷源確定地址上的指令取代0x18處的指令,通過跳轉(zhuǎn)指令系統(tǒng)就直接跳轉(zhuǎn)到對應(yīng)地址

;函數(shù)中 節(jié)省了中斷處理時(shí)間提高了中斷處理速度標(biāo) 例如 ADC中斷的向量地址為0xC0,則在0xC0處放如下代碼:ldr PC,=HandlerADC 當(dāng)ADC中斷產(chǎn)生的時(shí)候系統(tǒng)會(huì)

;自動(dòng)跳轉(zhuǎn)到HandlerADC函數(shù)中

;非向量中斷模式處理方式是一種傳統(tǒng)的中斷處理方法,當(dāng)系統(tǒng)產(chǎn)生中斷的時(shí)候,系統(tǒng)將interrupt pending寄存器中對應(yīng)標(biāo)志位置位 然后跳轉(zhuǎn)到位于0x18處的統(tǒng)一中斷

;函數(shù)中 該函數(shù)通過讀取interrupt pending寄存器中對應(yīng)標(biāo)志位 來判斷中斷源 并根據(jù)優(yōu)先級(jí)關(guān)系再跳到對應(yīng)中斷源的處理代碼中

MACRO 
$HandlerLabel HANDLER $HandleLabel    //
$HandlerLabel 
sub sp,sp,#4                     ;減少sp(預(yù)留一個(gè)字,用于存放轉(zhuǎn)跳地址) 
stmfd sp!,{r0}                    ;把工作寄存器壓入棧(lr does not push because it return to original address) 
ldr     r0,=$HandleLabel    ;將HandleXXX的址址放入r0 
ldr     r0,[r0]                       ;把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0 
str     r0,[sp,#4]                  ;把中斷服務(wù)程序(ISR)壓入棧,保存在高一個(gè)地址預(yù)留的空間中,但SP沒變。 
ldmfd   sp!,{r0,pc}              ;用出棧的方式恢復(fù)r0的原值和為pc設(shè)定新值(也就完成了到ISR的轉(zhuǎn)跳) ;

                   ADS僅支持FD(滿遞減)型堆棧,故只能用stmfd和ldmfd
MEND

;========================================================================================
//在這里用IMPORT偽指令(和c語言的extren一樣)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...
//這些變量是通過ADS的工程設(shè)置里面設(shè)定的RO Base和RW Base設(shè)定的,最終由編譯腳本和連接程序?qū)氤绦? 
//那為什么要引入這玩意呢,最簡單的用處是可以根據(jù)它們拷貝自已 ,從把RW和ZI變量從加載域中復(fù)制到運(yùn)行域中
//一個(gè)arm由RO,RW,ZI三個(gè)斷組成 其中RO為代碼段,RW是已經(jīng)初始化的全局變量,ZI是未初始化的全局變量(對于GNU工具 對應(yīng)的概念是TEXT ,DATA,BSS)。

;========================================================================================
IMPORT  |Image$$RO$$Base|    ; ROM code(也就是代碼)的開始地址 
IMPORT  |Image$$RO$$Limit|    ; ROM code的結(jié)束地址 (也就是RW在加載域中的起始地址) 
IMPORT  |Image$$RW$$Base|   ; 在運(yùn)行域中要初始化的RAM的開始地址 
IMPORT  |Image$$ZI$$Base|      ; area(需要清零的RAM區(qū)域)的開始地址 
IMPORT  |Image$$ZI$$Limit|       ; area的結(jié)束地址 

;這里引入一些在其它文件中實(shí)現(xiàn)在函數(shù),包括為我們所熟知的main函數(shù)
IMPORT  Main    ; The main entry of mon program 
;從這里開始就是正真的代碼入口了! 
AREA    Init,CODE,READONLY       ;這表明下面的是一個(gè)名為Init的代碼段 
ENTRY                                            ;定義程序的入口(調(diào)試用) 其中關(guān)鍵字ENTRY是指定編譯器保留這段代碼,因?yàn)?br/>                                                       編譯器可能會(huì)認(rèn)為這是一段亢余代碼而加以優(yōu)化。鏈接的時(shí)候要確保這段代碼
                                                         被鏈接在0地址處,并且作為整個(gè)程序的入口 
;1)The code, which converts to Big-endian, should be in little endian code. 
;2)The following little endian code will be compiled in Big-Endian mode. 
;  The code byte order should be changed as the memory bus width. 
;3)The pseudo instruction,DCD can not be used here because the linker generates error. 
ASSERT :DEF:ENDIAN_CHANGE 
[ ENDIAN_CHANGE                         ;下面是大小端的一個(gè)判斷,在Option.inc里已經(jīng)設(shè)為FALSE 
     ASSERT  :DEF:ENTRY_BUS_WIDTH 
     [ ENTRY_BUS_WIDTH=32          //‘[’=IF
      b ChangeBigEndian                  ;DCD 0xea000007 
     ] 

     [ ENTRY_BUS_WIDTH=16            
      andeq r14,r7,r0,lsl #20              ;DCD 0x0007ea00 
     ] 

     [ ENTRY_BUS_WIDTH=8 
      streq r0,[r0,-r10,ror #1]             ;DCD 0x070000ea 
     ] 

     b ResetHandler ;因?yàn)樵O(shè)成FALSE,所以系統(tǒng)復(fù)位后就來到這了,轉(zhuǎn)跳到復(fù)位程序入口 
    ] 
//=====================================================================================
;ARM要求中斷向量表必須放置在仿地址開始,連續(xù)8X4字節(jié)的空間內(nèi).每當(dāng)一個(gè)中斷發(fā)生以后,ARM處理器便強(qiáng)制把PC指針置為向量表中對應(yīng)中斷類型的地址值。因?yàn)槊總€(gè)中斷只占據(jù)向量表中1個(gè)字的存儲(chǔ)空間,只能放置一條ARM指令,使程序跳轉(zhuǎn)到存儲(chǔ)器的其他地方,再執(zhí)行中斷處理 
//=====================================================================================
b HandlerUndef           ;轉(zhuǎn)跳到Undefined mode程序入口 
b HandlerSWI              ;轉(zhuǎn)跳到SWI 中斷程序入口 
b HandlerPabort          ;轉(zhuǎn)跳到PAbort(指令異常)程序入口 
b HandlerDabort          ;轉(zhuǎn)跳到DAbort(數(shù)據(jù)異常)程序入口 
b .                                ;保留 
b HandlerIRQ              ;轉(zhuǎn)跳到IRQ 中斷程序入口 
b HandlerFIQ              ;轉(zhuǎn)跳到FIQ 中斷程序入口 
;@0x20 不知道是什么意思,地址?
b EnterPWDN ; Must be @0x20.
;================================================================================== 
;下面是改變大小端的程序,這里采用直接定義機(jī)器碼的方式,至說為什么這么做就得問三星了 
;反正我們程序里這段代碼也不會(huì)去執(zhí)行,不用去管它 
;================================================================================== 
ChangeBigEndian    //通過設(shè)置CP15中的C1的位7來設(shè)置存儲(chǔ)格式為大端模式。
;@0x24 
[ ENTRY_BUS_WIDTH=32 
     DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0 
     DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80;  //Big-endian 
     DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0 

[ ENTRY_BUS_WIDTH=16 
     DCD 0x0f10ee11 
     DCD 0x0080e380 
     DCD 0x0f10ee01 

[ ENTRY_BUS_WIDTH=8 
     DCD 0x100f11ee 
     DCD 0x800080e3 
     DCD 0x100f01ee 
    ] 
DCD 0xffffffff  ;swinv 0xffffff is similar with NOP and run well in both endian mode. 
DCD 0xffffffff 
DCD 0xffffffff 
DCD 0xffffffff 
DCD 0xffffffff 
b ResetHandler 
;Function for entering power down mode,下面這段程序?yàn)檫M(jìn)入掉電模式及從掉電模式中喚醒的相關(guān)設(shè)置和處理
; 1. SDRAM should be in self-refresh mode. SDRAm應(yīng)該設(shè)置為自刷新的模式
; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh. 所有中斷必須屏蔽 for SDRAM/DRAM self-ref
; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh. LCD 控制器關(guān)閉
; 4. The I-cache may have to be turned on.   
; 5. The location of the following code may have not to be changed.
//;void EnterPWDN(int CLKCON);           //PWDN:powerdown
EnterPWDN   
mov r2,r0  ;r2=rCLKCON                 //rCLKCONr [3;2]位為電源模式標(biāo)置位。若[3]為1,表示轉(zhuǎn)為了掉電模式
tst r0,#0x8  ;POWER_OFF mode?   //按位與判斷,若[3]為1則跳轉(zhuǎn)到ENTER_POWER_OFF
bne ENTER_POWER_OFF
ENTER_STOP                              //進(jìn)入停止模式相關(guān)處理
ldr r0,=REFRESH  
ldr r3,[r0]  ;r3=rREFRESH 
mov r1, r3
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0]                                      ;Enable SDRAM self-refresh
mov r1,#16                                   ;wait until self-refresh is issued. may not be needed.等待自刷新生效
0 subs r1,r1,#1
bne %B0                                     //表示不相等則往回跳轉(zhuǎn)到標(biāo)號(hào)為0的位置,在此為上一句。
ldr r0,=CLKCON                         ;enter STOP mode.
str r2,[r0]    
mov r1,#32
0 subs r1,r1,#1                           ;1) wait until the STOP mode is in effect.
bne %B0                                   ;2) Or wait here until the CPU&Peripherals will be turned-off
                                                 ;   Entering POWER_OFF mode, only the reset by wake-up is available.
                                                   //進(jìn)入掉電 模式后,僅喚醒中斷有效
ldr r0,=REFRESH                       ;exit from SDRAM self refresh mode.
str r3,[r0]

MOV_PC_LR                            //開始處定義的返回跳轉(zhuǎn)宏
ENTER_POWER_OFF 
;NOTE.注意在rGSTATUS3寄存器中應(yīng)該保存掉電模式喚醒的返回地址,rGSTATUS3,4可在掉電下保存信息
;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.

ldr r0,=REFRESH  
ldr r1,[r0]  ;r1=rREFRESH 
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0]  ;Enable SDRAM self-refresh
mov r1,#16     ;Wait until self-refresh is issued,which may not be needed.
0 subs r1,r1,#1
bne %B0
ldr  r1,=MISCCR
ldr r0,[r1]
orr r0,r0,#(7<<17)  ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 
str r0,[r1]
ldr r0,=CLKCON
str r2,[r0]    
b .   ;CPU will die here.

;=================================================================================

[1] [2] [3]
關(guān)鍵字:ARM9  S3C2410  啟動(dòng)代碼  ADSv1 引用地址:ARM9學(xué)習(xí)4-S3C2410的啟動(dòng)代碼分析-For ADSv1.2

上一篇:對于51單片機(jī)和arm9開發(fā)板串口通信問題的分析
下一篇:ARM9學(xué)習(xí)3-調(diào)試第一個(gè)ARM匯編程序

推薦閱讀

根據(jù)國際機(jī)器人協(xié)會(huì)R的數(shù)據(jù),全球范圍內(nèi)生產(chǎn)自動(dòng)化都在崛起,2017年工業(yè)機(jī)器人年銷售量同比飆升29%到38萬臺(tái)。 目前歐洲博得機(jī)器人使用率的頭籌,美國和亞洲緊隨其后。就具體國家來說,目前全球自動(dòng)化排名最高的前十個(gè)國家和地區(qū)分別是:韓國,新加坡,德國,日本,瑞典丹麥,美國,意大利,比利時(shí)和中國臺(tái)灣。 2016年,在全球制造業(yè)每1萬名員工中,平...
pt100熱敏電阻+AD824S放大并由ATmega8單片機(jī)主控的測溫系統(tǒng)仿真原理圖如下ATmega8單片機(jī)源程序如下:/*****************************************************This program was produced by theCodeWizardAVR V2.03.4 StandardAutomatic Program Generator?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.Project : Version : Date...
還記得諾基亞 N95 嗎?這款搭載 Symbian 系統(tǒng)的雙滑蓋手機(jī)標(biāo)志著一個(gè)時(shí)代的巔峰設(shè)計(jì)。現(xiàn)在有消息稱,HMD 有意復(fù)刻 N95 手機(jī),國外博主Michael Fisher甚至?xí)癯隽藦?fù)刻機(jī)的工程原型機(jī)照片。  據(jù)悉,N95 復(fù)刻版工程原型機(jī)采用了全面屏設(shè)計(jì),并且也保留了滑動(dòng)設(shè)計(jì),不過這次采用的是側(cè)滑,側(cè)滑后可以露出隱藏的雙前攝、閃光燈和揚(yáng)聲器開孔。...
工業(yè)機(jī)器人的“三大”核心部件,是機(jī)器人進(jìn)步與發(fā)展的關(guān)鍵,直接影響機(jī)器人的發(fā)展水平,是制約機(jī)器人發(fā)展的重要瓶頸??v觀我國機(jī)器人產(chǎn)業(yè),有點(diǎn)類似從前的汽車,強(qiáng)在市場,弱在技術(shù)。此前的文章中,我們講到了核心零部件中伺服電機(jī)的現(xiàn)狀問題,《國產(chǎn)伺服電機(jī),弱在哪里?》,我們注意到,機(jī)器人的控制系統(tǒng),受重視程度似乎比其他兩方面低了許多,今天我們...

史海拾趣

小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved