在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 分析ARM啟動代碼和中斷處理過程

            分析ARM啟動代碼和中斷處理過程

            作者: 時間:2016-11-25 來源:網(wǎng)絡 收藏

            加載域就是用Ultraedit打開看到的程序最原始的狀態(tài),而運行時域則是程序在執(zhí)行時按照你設 定的方式排布的狀態(tài),顯然,上面設置的兩個地址是針對運行時域來設置的,程序要滿足上面的設置才能正確連接。也就是程序開始階段(加載域狀態(tài))是不能正確 連接的,不過開始時不需要用到Rw里的數(shù)據(jù),程序是可以運行的,因此必須在需要用到Rw數(shù)據(jù)之前把它拷貝到上面設置的位置上,這就是bootloader 里初始化用戶程序的執(zhí)行環(huán)境部分的作用,把數(shù)據(jù)移動到正確的位置!
            拷貝完Rw里的數(shù)據(jù)之后,所有的符號都可以正確連接,這時跳轉到main函數(shù)里 去執(zhí)行程序就可以了。2410的這段啟動代碼沒有進行Ro的拷貝,所以如果你把程序燒在0x0地址,那么Ro就必須設置成0x0,如果你設置成 0x30000000,那么Ro就必須設置成0x30000000,如果Rw不設置,它將默認跟在Ro后面,否則就執(zhí)行上面的搬遷代碼,挪到正確的位置 上。由于本系統(tǒng)是采用NandFlash啟動的,最初的啟動代碼必須要在0x0處的SRAM里執(zhí)行,所以,如果要把這段啟動代碼當作NandFlash的 啟動代碼的話,Ro就必須設成0x0。

            6).中斷處理過程
            要使用中斷,首先需要清掉程序狀態(tài)寄存器CPSR里的IRQ位,這個很容易被忽略了。再之后才是考慮與中斷有關的相應寄 存器.

            這個幾個寄存器比較容易弄混了:
            SRCPND/SUBSRCPND:只要中斷產(chǎn)生的條件滿足,例如外部電平,定時溢出等 等,SRCPND/SUBSRCPND的相應位就會被置位,它不管其他地方的設置如何,所以某一時刻可能有幾個位同時被置位了(幾個中斷同時產(chǎn)生)。
            INTMSK/INTSUBMSK: 這個是中斷屏蔽位,清零表示允許中斷請求,默認是禁止了所有的中斷請求。
            INTPND:它表示處理器接下來就要去處理的那個中斷,某一時刻只可能 有一個位被置位。這個寄存器置位的必要條件是SRCPND/SUBSRCPND已經(jīng)是1,而且INTMSK/INTSUBMSK相應位已經(jīng)清零。
            SRCPND/SUBSRCPND 和INTPND都不會自動清零,要程序向相應的位寫1才能清零,這個有點奇怪。

            2410不支持中斷嵌套,中斷產(chǎn)生后處理器進入到IRQ模 式,只有在等到這個中斷處理完之后才能響應下一次中斷。
            如果同時產(chǎn)生多個中斷,就涉及到了中斷優(yōu)先級的問題。SRCPND寄存器對應的32個中斷 源總共被分為6個組,每個組由一個ARBITER(0~5)對其進行管理。中斷必須先由所屬組的ARBITER(0~5)進行第一次優(yōu)先級判斷然后再到 ARBITER6進行第二次判斷??梢愿牡闹皇墙M里的優(yōu)先級順序。
            PRIORITY的各個位被分為兩種類型,一種是ARB_MODE,另一種為 ARB_SEL,拿ARBITER0來說,這個組一共包含了四種中斷源:EINT0~EINT3,分別對應Req0~Req3,很明顯ARB_SEL0就 是決定了這四種中斷的優(yōu)先順序,如果這個組里的兩個中斷同時產(chǎn)生,將會把排在前面的先傳遞給ARBITER06進行第二次判斷。ARB_MODE0置1代 表開啟優(yōu)先級次序旋轉,當該位置為1之后,ARB_SEL0的值會在每處理完一次中斷后順次改變。

            中斷處理流程
            啟動代碼開始是一 個異常向量表,這個向量表是固定的,由處理器決定,必須要放在0x0地址那個地方,這個跟51單片機的中斷向量表相類似。
            b ResetHandler
            b HandlerUndef ;handler for Undefined mode
            b HandlerSWI ;handler for SWI interrupt
            b HandlerPabort ;handler for PAbort
            b HandlerDabort ;handler for DAbort
            b . ;reserved
            b HandlerIRQ ;handler for IRQ interrupt
            b HandlerFIQ ;handler for FIQ interrupt
            當產(chǎn)生IRQ中斷時,PC首先無條件地來到0x18這個地址處,這個 0x18就是處理器決定的IRQ中斷的入口地址,所以要在這個地址處放一條跳轉指令b HandlerIRQ,PC接著跳轉到HandlerIRQ地址標號處,這里存放著一個宏語句:
            HandlerIRQ HANDLER HandleIRQ
            按照上面說的宏展開,其實是執(zhí)行這么一段語句:
            sub sp,sp,#4 ;留下堆棧的第一個位置
            stmfd sp!,{r0} ;保護R0因為后面要用R0傳遞值
            ldr r0,=HandleIRQ;將HandleIRQ這個地址標號的值傳如R0
            ldr r0,[r0] ;取存放在HandleIRQ里的那個值
            str r0,[sp,#4] ;把取到的值壓入棧
            ldmfd sp!,{r0,pc} ;恢復R0并把PC指向HandleIRQ里存放的地址值
            HandleIRQ里存放是什么值呢?代碼最后有個這樣的表,這個表就是在SDRAM 里的另外一張異常向量表,這張表可以根據(jù)需要修改_ISR_STARTADDRESS的值來隨意更改它的位置。
            ^ _ISR_STARTADDRESS
            HandleReset # 4
            HandleUndef # 4
            HandleSWI # 4
            HandlePabort # 4
            HandleDabort # 4
            HandleReserved # 4
            HandleIRQ # 4
            HandleFIQ # 4
            這里實現(xiàn)結構化一片地址空間的目的,可見在 HandleIRQ這里預留了4個字節(jié)的空間,但是這個空間里現(xiàn)在放的是什么東西呢?
            在代碼的初始化過程中有這么一段代碼:
            ldr r0,=HandleIRQ ; Setup IRQ handler
            ldr r1,=IsrIRQ
            str r1,[r0]
            原 來是把IsrIRQ所在的地址值放到這個地方,那就是宏實現(xiàn)了把PC指向IsrIRQ的目的。程序來到IsrIRQ:
            IsrIRQ
            sub sp,sp,#4;預留堆棧
            stmfd sp!,{r8-r9};保護R8,R9

            ldr r9,=INTOFFSET;找出產(chǎn)生哪種中斷
            ldr r9,[r9]
            ldr r8,=HandleEINT0
            add r8,r8,r9,lsl #2
            ldr r8,[r8]
            str r8,[sp,#8]
            ldmfd sp!,{r8-r9,pc} ;將PC指向相應的中斷處理地址
            假如產(chǎn)生了EINT0中斷來到了這里, 那么PC將會跳轉到HandleEINT0里存放的地址值,與上面的相同,程序里有這個表:
            HandleEINT0 # 4
            HandleEINT1 # 4
            HandleEINT2 # 4
            HandleEINT3 # 4
            HandleEINT4_7 # 4
            .
            .
            .
            這個表在2410addr.h頭文件里也有對應的定義,指向的是同樣的一塊地方:
            .
            .
            .
            #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
            #define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
            #define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
            .
            .
            .
            問 題是HandleEINT0存放的又是什么值呢?這就需要在初始化EINT0的時候寫上這么一句:
            pISR_EINT0 = (unsigned )_IsrEINT0Service;
            也就是把 EINT0的中斷處理函數(shù)的地址寫到HandleEINT0地址處存放,那么到此PC就可以跳轉到_IsrEINT0Service里去了,這里完成你所 需要的中斷處理過程。

            本文引用地址:http://www.biyoush.com/article/201611/321101.htm

            上一頁 1 2 下一頁

            評論


            技術專區(qū)

            關閉