<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S3C2410啟動(dòng)代碼詳解(2)

          S3C2410啟動(dòng)代碼詳解(2)

          作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò) 收藏
          ;========================================================================================

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

          本文引用地址:http://www.ex-cimer.com/article/201611/316603.htm

          //這些變量是通過(guò)ADS的工程設(shè)置里面設(shè)定的RO Base和RW Base設(shè)定的,最終由編譯腳本和連接程序?qū)氤绦?

          //那為什么要引入這玩意呢,最簡(jiǎn)單的用處是可以根據(jù)它們拷貝自已,從把RW和ZI變量從加載域中復(fù)制到運(yùn)行域中

          //一個(gè)arm由RO,RW,ZI三個(gè)斷組成其中RO為代碼段,RW是已經(jīng)初始化的全局變量,ZI是未初始化的全局變量(對(duì)于GNU工具對(duì)應(yīng)的概念是TEXT ,DATA,BSS)。

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

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

          ;從這里開(kāi)始就是正真的代碼入口了!
          AREA Init,CODE,READONLY;這表明下面的是一個(gè)名為Init的代碼段
          ENTRY ;定義程序的入口(調(diào)試用)其中關(guān)鍵字ENTRY是指定編譯器保留這段代碼,因?yàn)?/p>

          編譯器可能會(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ù)位后就來(lái)到這了,轉(zhuǎn)跳到復(fù)位程序入口

          ]

          //=====================================================================================

          ;ARM要求中斷向量表必須放置在仿地址開(kāi)始,連續(xù)8X4字節(jié)的空間內(nèi).每當(dāng)一個(gè)中斷發(fā)生以后,ARM處理器便強(qiáng)制把PC指針置為向量表中對(duì)應(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ī)器碼的方式,至說(shuō)為什么這么做就得問(wèn)三星了
          ;反正我們程序里這段代碼也不會(huì)去執(zhí)行,不用去管它
          ;==================================================================================
          ChangeBigEndian //通過(guò)設(shè)置CP15中的C1的位7來(lái)設(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.等待自刷新生效
          0subs r1,r1,#1
          bne %B0//表示不相等則往回跳轉(zhuǎn)到標(biāo)號(hào)為0的位置,在此為上一句。

          ldr r0,=CLKCON;enter STOP mode.
          str r2,[r0]

          mov r1,#32
          0subs 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//開(kāi)始處定義的返回跳轉(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.
          0subs r1,r1,#1
          bne %B0

          ldr r1,=MISCCR
          ldrr0,[r1]
          orrr0,r0,#(7<<17) ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up
          strr0,[r1]

          ldr r0,=CLKCON
          str r2,[r0]

          b .;CPU will die here.


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

          從掉電模式喚醒的過(guò)程

          1、某個(gè)喚醒源生效將產(chǎn)生一個(gè)內(nèi)部復(fù)位信號(hào)。復(fù)位時(shí)間由一個(gè)內(nèi)部16位計(jì)數(shù)器決定,此計(jì)數(shù)器的時(shí)鐘是tRST=(65535/XTAL_frequency)。

          2、查詢GSTATUS[2]位看從掉電模式喚醒是否產(chǎn)生了一個(gè)POWER-UP。

          3、通過(guò)將MISCCR[19:17]設(shè)置為000b,釋放SDRAM信號(hào)保護(hù)。

          4、配置SDRAM控制器。

          5、等待SDRAM自我刷新完畢。大部分SDRAM需要refresh cycle of all SDRAM row。

          6、GSTATUS3,4的信息可以被用戶使用,因?yàn)镚STATUS3,4的值已經(jīng)在掉電模式下被保存了。

          7、對(duì)于EINT[3:0],檢查SRCPND寄存器;對(duì)于EINT[15:4],檢查EINTPND寄存器;對(duì)于RTC報(bào)警喚醒,檢查RTC時(shí)間,因?yàn)樵趩拘褧r(shí)SRCPND寄存器的RTC位不被置位;如果在掉電模式期間有nBATT-FLT assertion,SRCPND寄存器的相關(guān)位被置位。

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

          WAKEUP_POWER_OFF
          ;Release SCLKn after wake-up from the POWER_OFF mode.

          ldr r1,=MISCCR//MISCCR寄存器用來(lái)設(shè)置一些USB等相關(guān)的時(shí)鐘周期等
          ldrr0,[r1]
          bicr0,r0,#(7<<17)//SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H

          strr0,[r1]//通過(guò)將MISCCR[19:17]設(shè)置為000b,釋放SDRAM信號(hào)保護(hù)。

          ;Set memory control registers配置內(nèi)存控制寄存器。
          ldrr0,=SMRDATA//在程序的后面LTORGSMRDATA DATA中定義了

          //一個(gè)數(shù)據(jù)緩沖池就是用來(lái)配置相關(guān)的內(nèi)存控制寄存器的
          ldrr1,=BWSCON ;BWSCON Address
          addr2, r0, #52 ;End address of SMRDATA
          0
          ldrr3, [r0], #4
          strr3, [r1], #4
          cmpr2, r0
          bne%B0

          mov r1,#256
          0subs r1,r1,#1 ;1) wait until the SelfRefresh is released.
          bne %B0

          ldr r1,=GSTATUS3 ; GSTATUS3 has the start address just after POWER_OFF wake-up
          ldr r0,[r1]
          mov pc,r0 //從掉電模式下喚醒后,將保存在GSTATUS3 返回地址傳給PC

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

          LTORG ;聲明文字池,因?yàn)槲覀冇昧薼dr偽指令
          HandlerFIQ HANDLER HandleFIQ
          HandlerIRQ HANDLER HandleIRQ
          HandlerUndef HANDLER HandleUndef
          HandlerSWI HANDLER HandleSWI
          HandlerDabort HANDLER HandleDabort
          HandlerPabort HANDLER HandlePabort

          ;===================================================================================
          ;呵呵,來(lái)了來(lái)了.好戲來(lái)了,這一段程序就是用來(lái)進(jìn)行第二次查表的過(guò)程了.
          ;如果說(shuō)第一次查表是由硬件來(lái)完成的,那這一次查表就是由軟件來(lái)實(shí)現(xiàn)的了.
          ;為什么要查兩次表??
          ;沒(méi)有辦法,ARM把所有的中斷都?xì)w納成一個(gè)IRQ中斷異常和一個(gè)FIRQ中斷異常
          ;第一次查表主要是查出是什么異常,可我們總要知道是這個(gè)中斷異常中的什么中斷呀!
          ;沒(méi)辦法了,再查一次表唄!
          ;===================================================================================
          IsrIRQ//第二次中斷查表,因?yàn)锳RM把所有的中斷都?xì)w為一個(gè)IRQ異常,通過(guò)此處查表可知道具體中斷
          sub sp,sp,#4 ;給PC寄存器保留
          stmfd sp!,{r8-r9} ;把r8-r9壓入棧

          ldr r9,=INTOFFSET ;把INTOFFSET的地址裝入r9
          ldr r9,[r9] ;把INTOFFSET的值裝入r9
          ldr r8,=HandleEINT0 ;這就是我們第二個(gè)中斷向量表的入口的,先裝入r8
          ;===================================================================================
          ;哈哈,這查表方法夠好了吧,r8(入口)+index*4(別望了一條指令是4 bytes的喔),
          ;這不就是我們要找的那一項(xiàng)了嗎.找到了表項(xiàng),下一步做什么?肯定先裝入了!
          ;==================================================================================
          add r8,r8,r9,lsl #2
          ldr r8,[r8] ;裝入中斷服務(wù)程序的入口
          str r8,[sp,#8] ;把入口也入棧,準(zhǔn)備用舊招
          ldmfd sp!,{r8-r9,pc};施招,彈出棧,哈哈,順便把r8彈出到PC,O了,跳轉(zhuǎn)成功!



          關(guān)鍵詞: S3C2410啟動(dòng)代

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();