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

          新聞中心

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

          分析ARM啟動(dòng)代碼和中斷處理過程

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

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

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

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

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

          中斷處理流程
          啟動(dòng)代碼開始是一 個(gè)異常向量表,這個(gè)向量表是固定的,由處理器決定,必須要放在0x0地址那個(gè)地方,這個(gè)跟51單片機(jī)的中斷向量表相類似。
          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
          當(dāng)產(chǎn)生IRQ中斷時(shí),PC首先無條件地來到0x18這個(gè)地址處,這個(gè) 0x18就是處理器決定的IRQ中斷的入口地址,所以要在這個(gè)地址處放一條跳轉(zhuǎn)指令b HandlerIRQ,PC接著跳轉(zhuǎn)到HandlerIRQ地址標(biāo)號(hào)處,這里存放著一個(gè)宏語句:
          HandlerIRQ HANDLER HandleIRQ
          按照上面說的宏展開,其實(shí)是執(zhí)行這么一段語句:
          sub sp,sp,#4 ;留下堆棧的第一個(gè)位置
          stmfd sp!,{r0} ;保護(hù)R0因?yàn)楹竺嬉肦0傳遞值
          ldr r0,=HandleIRQ;將HandleIRQ這個(gè)地址標(biāo)號(hào)的值傳如R0
          ldr r0,[r0] ;取存放在HandleIRQ里的那個(gè)值
          str r0,[sp,#4] ;把取到的值壓入棧
          ldmfd sp!,{r0,pc} ;恢復(fù)R0并把PC指向HandleIRQ里存放的地址值
          HandleIRQ里存放是什么值呢?代碼最后有個(gè)這樣的表,這個(gè)表就是在SDRAM 里的另外一張異常向量表,這張表可以根據(jù)需要修改_ISR_STARTADDRESS的值來隨意更改它的位置。
          ^ _ISR_STARTADDRESS
          HandleReset # 4
          HandleUndef # 4
          HandleSWI # 4
          HandlePabort # 4
          HandleDabort # 4
          HandleReserved # 4
          HandleIRQ # 4
          HandleFIQ # 4
          這里實(shí)現(xiàn)結(jié)構(gòu)化一片地址空間的目的,可見在 HandleIRQ這里預(yù)留了4個(gè)字節(jié)的空間,但是這個(gè)空間里現(xiàn)在放的是什么東西呢?
          在代碼的初始化過程中有這么一段代碼:
          ldr r0,=HandleIRQ ; Setup IRQ handler
          ldr r1,=IsrIRQ
          str r1,[r0]
          原 來是把IsrIRQ所在的地址值放到這個(gè)地方,那就是宏實(shí)現(xiàn)了把PC指向IsrIRQ的目的。程序來到IsrIRQ:
          IsrIRQ
          sub sp,sp,#4;預(yù)留堆棧
          stmfd sp!,{r8-r9};保護(hù)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指向相應(yīng)的中斷處理地址
          假如產(chǎn)生了EINT0中斷來到了這里, 那么PC將會(huì)跳轉(zhuǎn)到HandleEINT0里存放的地址值,與上面的相同,程序里有這個(gè)表:
          HandleEINT0 # 4
          HandleEINT1 # 4
          HandleEINT2 # 4
          HandleEINT3 # 4
          HandleEINT4_7 # 4
          .
          .
          .
          這個(gè)表在2410addr.h頭文件里也有對應(yīng)的定義,指向的是同樣的一塊地方:
          .
          .
          .
          #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
          #define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
          #define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
          .
          .
          .
          問 題是HandleEINT0存放的又是什么值呢?這就需要在初始化EINT0的時(shí)候?qū)懮线@么一句:
          pISR_EINT0 = (unsigned )_IsrEINT0Service;
          也就是把 EINT0的中斷處理函數(shù)的地址寫到HandleEINT0地址處存放,那么到此PC就可以跳轉(zhuǎn)到_IsrEINT0Service里去了,這里完成你所 需要的中斷處理過程。

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

          上一頁 1 2 下一頁

          關(guān)鍵詞: ARM啟動(dò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); })();