国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

歷史上的今天

今天是:2025年01月31日(星期五)

2021年01月31日 | ARM-S3C2440啟動文件init.s解析

發(fā)布者:epsilon15 來源: eefocus關(guān)鍵字:ARM  S3C2440  啟動文件  init 手機看文章 掃描二維碼
隨時隨地手機看文章

簡介:Arm上電時處于ARM狀態(tài),故無論指令為ARM集或Thumb集,都先強制成ARM集,待init.s初始化完成后 ;再根據(jù)用戶的編譯配置轉(zhuǎn)換成相應(yīng)的指令模式。


=========================================

; NAME: 2440INIT.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,Sleep mode

; 2003.03.14:DonGo: Modified for 2440.

; 2009 06.24:Tinko Modified

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



;匯編不能使用include包含頭文件,所有用Get

;匯編也不認(rèn)識*.h 文件,所有只能用*.inc

GET option.inc;定義芯片相關(guān)的配置

GET memcfg.inc;定義存儲器配置

GET 2440addr.inc;定義了寄存器符號



;REFRESH寄存器[22]bit : 0- auto refresh; 1 - self refresh

BIT_SELFREFRESH EQU (1<<22) ;用于節(jié)電模式中,SDRAM自動刷新



;處理器模式常量: CPSR寄存器的后5位決定目前處理器模式 M[4:0]

USERMODEEQU 0x10

FIQMODEEQU 0x11

IRQMODEEQU 0x12

SVCMODEEQU 0x13

ABORTMODEEQU 0x17

UNDEFMODEEQU 0x1b

MODEMASKEQU 0x1f;M[4:0]

NOINTEQU 0xc0



;定義處理器各模式下堆棧地址常量

UserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800 ~_STACK_BASEADDRESS定義在option.inc中

SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800 ~

UndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00 ~

AbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000 ~

IRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000 ~

FIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000 ~



;arm處理器有兩種工作狀態(tài) 1.arm:32位 這種工作狀態(tài)下執(zhí)行字對準(zhǔn)的arm指令 2.Thumb:16位 這種工作狀

;態(tài)執(zhí)行半字對準(zhǔn)的Thumb指令

;因為處理器分為16位 32位兩種工作狀態(tài) 程序的編譯器也是分16位和32兩種編譯方式 所以下面的程序用

;于根據(jù)處理器工作狀態(tài)確定編譯器編譯方式

;code16偽指令指示匯編編譯器后面的指令為16位的thumb指令

;code32偽指令指示匯編編譯器后面的指令為32位的arm指令

;

;Arm上電時處于ARM狀態(tài),故無論指令為ARM集或Thumb集,都先強制成ARM集,待init.s初始化完成后

;再根據(jù)用戶的編譯配置轉(zhuǎn)換成相應(yīng)的指令模式。為此,定義變量THUMBCODE作為指示,跳轉(zhuǎn)到main之前

;根據(jù)其值切換指令模式

;

;這段是為了統(tǒng)一目前的處理器工作狀態(tài)和軟件編譯方式(16位編譯環(huán)境使用tasm.exe編譯

;Check if tasm.exe(armasm -16...@ADS1.0) is used.

GBLLTHUMBCODE ;定義THUMBCODE全局變量注意EQU所定義的宏與變量的區(qū)別


[ {CONFIG} = 16 ;如果發(fā)現(xiàn)是在用16位代碼的話(編譯選項中指定使用thumb指令)


THUMBCODE SETL {TRUE} ;一方面把THUMBCODE設(shè)置為TURE


CODE32 ;另一方面暫且把處理器設(shè)置成為ARM模式,以方便初始化


| ;(|表示else)如果編譯選項本來就指定為ARM模式

THUMBCODE SETL {FALSE};把THUMBCODE設(shè)置為FALSE就行了


] ;結(jié)束



MACRO;一個根據(jù)THUMBCODE把PC寄存的值保存到LR的宏

MOV_PC_LR;宏名稱

[ THUMBCODE;如果定義了THUMBCODE,則

bx lr ;在ARM模式中要使用BX指令轉(zhuǎn)跳到THUMB指令,并轉(zhuǎn)換模式.


;bx指令會根據(jù)PC最后1位來確定是否進入thumb狀態(tài)

|;否則,

movpc,lr;如果目標(biāo)地址也是ARM指令的話就采用這種方式

]

MEND;宏定義結(jié)束標(biāo)志


MACRO ;和上面的宏一樣,只是多了一個相等的條件

MOVEQ_PC_LR

[ THUMBCODE

bxeq lr

|

moveq pc,lr

]

MEND



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

;下面這個宏是用于第一次查表過程的實現(xiàn)中斷向量的重定向,如果你比較細心的話就是發(fā)現(xiàn)

;在_ISR_STARTADDRESS=0x33FF_FF00里定義的第一級中斷向量表是采用型如Handle***的方式的.

;而在程序的ENTRY處(程序開始處)采用的是b Handler***的方式.

;在這里Handler***就是通過HANDLER這個宏和Handle***建立聯(lián)系的.

;這種方式的優(yōu)點就是正真定義的向量數(shù)據(jù)在內(nèi)存空間里,而不是在ENTRY處的ROM(FLASH)空間里,

;這樣,我們就可以在程序里靈活的改動向量的數(shù)據(jù)了.

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

;;這段程序用于把中斷服務(wù)程序的首地址裝載到pc中,有人稱之為“加載程序”。

;本初始化程序定義了一個數(shù)據(jù)區(qū)(在文件最后),34個字空間,存放相應(yīng)中斷服務(wù)程序的首地址。

;每個字空間都有一個標(biāo)號,以Handle***命名。


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

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

;向量中斷模式是當(dāng)cpu讀取位于0x18處的IRQ中斷指令的時候,系統(tǒng)自動讀取對應(yīng)于該中斷源確定

;地址上的指令取代0x18處的指令,通過跳轉(zhuǎn)指令系統(tǒng)就直接跳轉(zhuǎn)到對應(yīng)地址


;函數(shù)中 節(jié)省了中斷處理時間提高了中斷處理速度標(biāo) 例如 ADC中斷的向量地址為0xC0,則在0xC0處

;代放如下碼:ldr PC,=HandlerADC 當(dāng)ADC中斷產(chǎn)生的時候系統(tǒng)會自動跳轉(zhuǎn)到HandlerADC函數(shù)中


;非向量中斷模式處理方式是一種傳統(tǒng)的中斷處理方法,當(dāng)系統(tǒng)產(chǎn)生中斷的時候,系統(tǒng)將interrupt

;pending寄存器中對應(yīng)標(biāo)志位置位 然后跳轉(zhuǎn)到位于0x18處的統(tǒng)一中斷函數(shù)中

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

;對應(yīng)中斷源的處理代碼中

;

;H|------|H|------|H|------|H|------|H|------|

; |/ / / ||/ / / ||/ / / ||/ / / ||/ / / |

; |------|<----sp|------||------||------||------|<------sp

;L|||------|<----sp L|------||-isr--||------| isr==>pc

; |||||--r0--|<----sp|---r0-|<----spL|------| r0==>r0

;(0)(1)(2)(3)(4)


MACRO

$HandlerLabel HANDLER $HandleLabel


$HandlerLabel ;標(biāo)號

sub sp,sp,#4 ;(1)減少sp(用于存放轉(zhuǎn)跳地址)

stmfd sp!,{r0};(2)把工作寄存器壓入棧(lr does not push because it return to original address)

ldrr0,=$HandleLabel;將HandleXXX的址址放入r0

ldrr0,[r0];把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0

strr0,[sp,#4];(3)把中斷服務(wù)程序(ISR)壓入棧

ldmfdsp!,{r0,pc};(4)用出棧的方式恢復(fù)r0的原值和為pc設(shè)定新值(也就完成了到ISR的轉(zhuǎn)跳)

MEND



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

;在這里用IMPORT偽指令(和c語言的extren一樣)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...

;這些變量是通過ADS的工程設(shè)置里面設(shè)定的RO Base和RW Base設(shè)定的,

;最終由編譯腳本和連接程序?qū)氤绦?

;那為什么要引入這玩意呢,最簡單的用處是可以根據(jù)它們拷貝自已

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

;Image$$RO$$Base等比較古怪的變量是編譯器生成的。RO, RW, ZI這三個段都保存在Flash中,但RW,ZI在Flash中

;的地址肯定不是程序運行時變量所存儲的位置,因此我們的程序在初始化時應(yīng)該把Flash中的RW,ZI拷貝到RAM的

;對應(yīng)位置。一般情況下,我們可以利用編譯器替我們實現(xiàn)這個操作。比如我們跳轉(zhuǎn)到main()時,使用 b__Main,


;編譯器就會在__Main和Main之間插入一段匯編代碼,來替我們完成RW,ZI段的初始化。 如果我們使用 bMain,


;那么初始化工作要我們自己做。編譯器會生成如下變量告訴我們RO,RW,ZI三個段應(yīng)該位于什么位置,但是它并


;沒有告訴我們RW,ZI在Flash中存儲在什么位置,實際上RW,ZI在Flash中的位置就緊接著RO存儲。我們知道了


;Image$$RO$$Base,Image$$RO$$Limit,那么Image$$RO$$Limit就是RW(ROM data)的開始。



IMPORT|Image$$RO$$Base| ; Base of ROM code

IMPORT|Image$$RO$$Limit|; End of ROM code (=start of ROM data)

IMPORT|Image$$RW$$Base|; Base of RAM to initialise

IMPORT|Image$$ZI$$Base|; Base and limit of area

IMPORT|Image$$ZI$$Limit|; to zero initialise



;這里引入一些在其它文件中實現(xiàn)在函數(shù),包括為我們所熟知的main函數(shù)



;IMPORT MMU_SetAsyncBusMode

;IMPORT MMU_SetFastBusMode ;hzh


IMPORTMain



;從這里開始就是正真的代碼入口了!

AREAInit,CODE,READONLY ;這表明下面的是一個名為Init的代碼段


ENTRY;定義程序的入口(調(diào)試用)

EXPORT __ENTRY;導(dǎo)出符號_ENTRY,但在那用到就還沒查明

__ENTRY


ResetEntry


;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.

;條件編譯,在編譯成機器碼前就設(shè)定好

ASSERT:DEF:ENDIAN_CHANGE;判斷ENDIAN_CHANGE是否已定義

[ ENDIAN_CHANGE;如果已經(jīng)定義了ENDIAN_CHANGE,則(在Option.inc里已經(jīng)設(shè)為FALSE )

ASSERT:DEF:ENTRY_BUS_WIDTH;判斷ENTRY_BUS_WIDTH是否已定義

[ ENTRY_BUS_WIDTH=32;如果已經(jīng)定義了ENTRY_BUS_WIDTH,則判斷是不是為32

bChangeBigEndian;DCD 0xea000007

]

;在bigendian中,地址為A的字單元包括字節(jié)單元A,A+1,A+2,A+3,字節(jié)單元由高位到低位為A,A+1,A+2,A+3

;地址為A的字單元包括半字單元A,A+2,半字單元由高位到低位為A,A+2

[ ENTRY_BUS_WIDTH=16

andeqr14,r7,r0,lsl #20;DCD 0x0007ea00也是bChangeBigEndian指令,只是由于總線不一樣而取機器碼

];的順序不一樣,先取低位->高位上述指令是通過機器碼裝換而來的


[ ENTRY_BUS_WIDTH=8

streqr0,[r0,-r10,ror #1] ;DCD 0x070000ea 也是bChangeBigEndian指令,只是由于總線不一樣而取機器碼

];的順序不一樣

|

bResetHandler;我們的程序由于ENDIAN_CHANGE設(shè)成FALSE就到這兒了,轉(zhuǎn)跳到復(fù)位程序入口

]


bHandlerUndef;handler for Undefined mode;0x04

bHandlerSWI;handler for SWI interrupt;0x08

bHandlerPabort;handler for PAbort;0x0c

bHandlerDabort;handler for DAbort;0x10

b.;reserved 注意小圓點;0x14

bHandlerIRQ;handler for IRQ interrupt;0x18

bHandlerFIQ;handler for FIQ interrupt;0x1c


;@0x20

bEnterPWDN; Must be @0x20.



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

;下面是改變大小端的程序,這里采用直接定義機器碼的方式,至說為什么這么做就得問三星了

;反正我們程序里這段代碼也不會去執(zhí)行,不用去管它

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

;通過設(shè)置CP15的C1的位7,設(shè)置存儲格式為Bigendian,三種總線方式


ChangeBigEndian ;//here ENTRY_BUS_WIDTH=16

;@0x24


[ ENTRY_BUS_WIDTH=32

DCD0xee110f10;0xee110f10 => mrc p15,0,r0,c1,c0,0

DCD0xe3800080;0xe3800080 => orr r0,r0,#0x80;//Big-endian

DCD0xee010f10;0xee010f10 => mcr p15,0,r0,c1,c0,0

;對存儲器控制寄存器操作,指定內(nèi)存模式為Big-endian

;因為剛開始CPU都是按照32位總線的指令格式運行的,如果采用其他的話,CPU別不了,必須轉(zhuǎn)化

;但當(dāng)系統(tǒng)初始化好以后,則CPU能自動識別

]

[ ENTRY_BUS_WIDTH=16

DCD 0x0f10ee11

DCD 0x0080e380

DCD 0x0f10ee01

;因為采用Big-endian模式,采用16位總線時,物理地址的高位和數(shù)據(jù)的地位對應(yīng)

;所以指令的機器碼也相應(yīng)的高低對調(diào)

]

[ 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

; 1. SDRAM should be in self-refresh mode.

; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.

; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.

; 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);

EnterPWDN

mov r2,r0;r2=rCLKCON 保存原始數(shù)據(jù) 0x4c00000c 使能各模塊的時鐘輸入

tst r0,#0x8;測試bit[3] SLEEP mode? 1=>sleep

bne ENTER_SLEEP;C=0,即TST結(jié)果非0,bit[3]=1


;//進入PWDN后如果不是sleep則進入stop


;//進入Stop mode

ENTER_STOP

ldr r0,=REFRESH;0x48000024DRAM/SDRAM refresh config

ldr r3,[r0];r3=rREFRESH

mov r1, r3

orr r1, r1, #BIT_SELFREFRESH;Enable SDRAM self-refresh

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

;//wait 16 fclks for self-refresh

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 SLEEP mode, only the reset by wake-up is available.


ldr r0,=REFRESH ;exit from SDRAM self refresh mode.

str r3,[r0]


MOV_PC_LR;back to main process



ENTER_SLEEP

;NOTE.

;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode.


ldr r0,=REFRESH

ldr r1,[r0];r1=rREFRESH

orr r1, r1, #BIT_SELFREFRESH

str r1, [r0];Enable SDRAM self-refresh

;//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

;//Wait until self-refresh is issued,which may not be needed


ldrr1,=MISCCR;IO register

ldrr0,[r1]

orrr0,r0,#(7<<17);Set SCLK0=1, SCLK1=1, SCKE=1.

strr0,[r1]


ldr r0,=CLKCON; Enter sleep mode

str r2,[r0]


b .;CPU will die here.

;//進入Sleep Mode,1)設(shè)置SDRAM為self-refresh

;//2)設(shè)置MISCCR bit[17] 1:sclk0=sclk 0:sclk0=0

;//bit[18] 1:sclk1=sclk 0:sclk1=0

;//bit[19] 1:Self refresh retain enable

;//0:Self refresh retain disable

;//When 1, After wake-up from sleep, The self-refresh will be retained.


WAKEUP_SLEEP

;Release SCLKn after wake-up from the SLEEP mode.

ldrr1,=MISCCR

ldrr0,[r1]

bicr0,r0,#(7<<17);SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:0->=SCKE.

strr0,[r1]

;//設(shè)置MISCCR


;Set memory control registers

;ldrr0,=SMRDATA

adrl r0, SMRDATA

ldrr1,=BWSCON;BWSCON Address;//總線寬度和等待控制寄存器

addr2, r0, #52;End address of SMRDATA

0

ldrr3, [r0], #4;數(shù)據(jù)處理后R0自加4,[R0]->R3,R0+4->R0

strr3, [r1], #4

cmpr2, r0

bne%B0

;//設(shè)置所有的memory control register,他的初始地址為BWSCON,初始化

;//數(shù)據(jù)在以SMRDATA為起始的存儲區(qū)


mov r1,#256

0

subs r1,r1,#1;1) wait until the SelfRefresh is released.

bne %B0

;//1) wait until the SelfRefresh is released.


ldr r1,=GSTATUS3 ;GSTATUS3 has the start address just after SLEEP wake-up

ldr r0,[r1]


mov pc,r0

;//跳出Sleep Mode,進入Sleep狀態(tài)前的PC



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



;如上所說,這里采用HANDLER宏去建立Hander***和Handle***之間的聯(lián)系

[1] [2] [3]
關(guān)鍵字:ARM  S3C2440  啟動文件  init 引用地址:ARM-S3C2440啟動文件init.s解析

上一篇:ARM研發(fā)常見問題集
下一篇:ARM嵌入式平臺的VGA接口設(shè)計(ADV7120)

推薦閱讀

當(dāng)?shù)貢r間2018年1月29日,韓國首爾,人工智能機器人索菲亞身著韓服出席由漢森機器人技術(shù)公司(Hanson Robocs)主辦的晚宴。索菲亞出自漢森公司之手,并已擁有沙特公民身份。 索菲亞是歷史上首個獲得公民身份的一名女機器人。她看起來就像人類女性,擁有仿生橡膠皮膚,可模擬62種面部表情,其“大腦”采用了人工智能和谷歌技術(shù),能識別人類面部、理解語...
傳感器是汽車的重要組成部分,2019年,將誕生多項令人驚嘆的汽車傳感器新技術(shù),為用戶帶來更舒暢的體驗。下面介紹兩項受用戶青睞的熱點汽車傳感器技術(shù),供讀者品鑒?,F(xiàn)代——轉(zhuǎn)向指紋傳感器現(xiàn)代宣布旗下Santa Fe SUV將配置一款指紋傳感器,實現(xiàn)車輛門禁解鎖及車輛起動。該款指紋掃描儀及啟動按鍵均位于車輛外部的車門手柄上。若家中多人共用一輛車,可分...
HMD Global已推遲推出下一代諾基亞旗艦智能手機,以使其有更多機會參與2020年市場競爭。這意味著它會在秋天的某個時候出現(xiàn),這使該公司有足夠的時間切換到所有競爭對手都在使用的Snapdragon 865芯片組。這種延遲還可能使HMD有足夠的時間在移動世界中首屈一指:屏下自拍相機。 有消息來源顯示,諾基亞正在測試這種尖端技術(shù),并有可能用在Nokia 9.2中。 ...
中興通訊近日在美國發(fā)布了Blade X1 5G手機。這款手機為美國虛擬網(wǎng)絡(luò)運營商 Visible 訂制的有鎖機型。Visible 隸屬于 Verizon,同樣提供分期購買手機的計劃,性價比相對高一些。中興 Blade X1手機搭載高通驍龍765G 芯片,大核最高頻率2.3GHz。手機采用 IPS 挖孔全面屏,配備背面指紋識別。攝像頭方面,手機采用后置四攝設(shè)計,主攝4800萬像素,前置...

史海拾趣

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

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