Cortex M3基礎_第1頁
Cortex M3基礎_第2頁
Cortex M3基礎_第3頁
Cortex M3基礎_第4頁
Cortex M3基礎_第5頁
已閱讀5頁,還剩57頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Cortex M3基礎 寄存器組 特殊功能寄存器組 操作模式 異常和中斷 向量表 存儲器保護單元 堆棧區(qū)的操作 復位序列提綱寄存器組CM3 擁有通用寄存器R0 R15 以及一些特殊功能寄存器。R0 R12 是最“通用目的”的,但是絕大多數(shù)的16 位指令只能使用R0 R7(低組寄存器),而32 位的Thumb 2指令則可以訪問所有通用寄存器。特殊功能寄存器有預定義的功能,而且必須通過專用的指令來訪問。1. 通用目的寄存器R0-R7R0 R7 也被稱為低組寄存器。所有指令都能訪問它們。它們的字長全是32 位,復位后的初始值是不可預料的。2. 通用目的寄存器R8-R12R8 R12 也被稱為高組寄存

2、器。這是因為只有很少的16 位Thumb 指令能訪問它們,32位的指令則不受限制。它們也是32 位字長,且復位后的初始值是不可預料的。3. 堆棧指針R13 R13 是堆棧指針。在CM3 處理器內核中共有兩個堆棧指針,于是也就支持兩個堆棧。當引用R13(或寫作SP)時,你引用到的是當前正在使用的那一個,另一個必須用特殊的指令來訪問(MRS,MSR 指令)。這兩個堆棧指針分別是: 主堆棧指針(MSP),或寫作SP_main。這是缺省的堆棧指針,它由OS 內核、異常服務例程以及所有需要特權訪問的應用程序代碼來使用。 進程堆棧指針(PSP),或寫作SP_process。用于常規(guī)的應用程序代碼(不處于異

3、常服用例程中時)。要注意的是,并不是每個應用都必須用齊兩個堆棧指針。簡單的應用程序只使用MSP就夠了。堆棧指針用于訪問堆棧,并且PUSH 指令和POP 指令默認使用SP。在Cortex M3 中,有專門的指令負責堆棧操作PUSH 和POP。它倆的匯編語言語法如下例所演示PUSH R0 ; *(-R13)=R0。R13 是long*的指針POP R0 ; R0= *R13+請注意后面C 程序風格的注釋,ortex M3 中的堆棧以這種方式來使用的,這就是所謂的“向下生長的滿?!保ū菊潞竺嬖谥v到堆棧內存操作時還要展開論述)。因此,在PUSH 新數(shù)據(jù)時,堆棧指針先減一個單元。通常在進入一個子程序后,

4、第一件事就是把寄存器的值先PUSH 入堆棧中,在子程序退出前再POP 曾經(jīng)PUSH 的那些寄存器。另外,PUSH 和POP 還能一次操作多個寄存器,如下所示:subroutine_1PUSH R0-R7, R12, R14 ; 保存寄存器列表 ; 執(zhí)行處理POP R0-R7, R12, R14 ; 恢復寄存器列表BX R14 ; 返回到主調函數(shù)在程序中為了突出重點,你可以使用SP 表示R13。在程序代碼中,both MSP 和PSP 都被稱為R13/SP。不過,我們可以通過MRS/MSR 指令來指名道姓地訪問具體的堆棧指針。MSP,亦寫作SP_main,這是復位后缺省使用堆棧指針,服務于操作系

5、統(tǒng)內核和異常服務例程;而PSP,亦寫作SP_process,典型地用于普通的用戶線程中。寄存器的PUSH 和POP 操作永遠都是4 字節(jié)對齊的也就是說他們的地址必須是0 x4,0 x8,0 xc,。這樣一來,R13 的最低兩位被硬線連接到0,并且總是讀出0(Read As Zero)。4. 連接寄存器R14R14 是連接寄存器(LR)。在一個匯編程序中,你可以把它寫作both LR 和R14。LR 用于在調用子程序時存儲返回地址。例如,當你在使用BL(分支并連接,Branch and Link)指令時,就自動填充LR 的值。main ;主程序BL function1 ; 使用“分支并連接”指令

6、呼叫function1; PC= function1,并且LR=main 的下一條指令地址Function1 ; function1 的代碼BX LR ; 函數(shù)返回(如果function1 要使用LR,必須在使用前PUSH,否則返回時程序就可能跑飛了譯注)盡管PC 的LSB 總是0(因為代碼至少是字對齊的),LR 的LSB 卻是可讀可寫的。這是歷史遺留的產(chǎn)物。在以前,由位0 來指示ARM/Thumb 狀態(tài)。因為其它有些ARM 處理器支持ARM 和Thumb 狀態(tài)并存,為了方便匯編程序移植,CM3 需要允許LSB 可讀可寫。5. 程序計數(shù)器R15 R15 是程序計數(shù)器,在匯編代碼中你也可以使用名

7、字“PC”來訪問它。因為CM3 內部使用了指令流水線,讀PC 時返回的值是當前指令的地址+4。比如說:0 x1000: MOV R0, PC ; R0 = 0 x1004如果向PC 中寫數(shù)據(jù),就會引起一次程序的分支(但是不更新LR 寄存器)。CM3 中的指令至少是半字對齊的,所以PC 的LSB 總是讀回0。然而,在分支時,無論是直接寫在分支時,無論是直接寫PC 的值還是使用分支指令,都必須保證加載到的值還是使用分支指令,都必須保證加載到PC 的數(shù)值是奇數(shù)(即的數(shù)值是奇數(shù)(即LSB=1),用以表明這是在),用以表明這是在Thumb 狀態(tài)下執(zhí)行。倘狀態(tài)下執(zhí)行。倘若寫了若寫了0,則視為企圖轉入,則視

8、為企圖轉入ARM 模式,模式,CM3 將產(chǎn)生一個將產(chǎn)生一個fault 異常。異常。二、特殊功能寄存器組Cortex M3 中的特殊功能寄存器包括: 程序狀態(tài)寄存器組(PSRs 或曰xPSR) 中斷屏蔽寄存器組(PRIMASK, FAULTMASK,以及BASEPRI) 控制寄存器(CONTROL)它們只能被專用的MSR 和MRS 指令訪問,而且它們也沒有存儲器地址。MRS , ;讀特殊功能寄存器的值到通用寄存器MSR , ;寫通用寄存器的值到特殊功能寄存器1.程序狀態(tài)寄存器(PSRs 或PSR)程序狀態(tài)寄存器在其內部又被分為三個子狀態(tài)寄存器: 應用程序 PSR(APSR) 中斷號 PSR(IP

9、SR) 執(zhí)行 PSR(EPSR)通過MRS/MSR 指令,這3 個PSRs 即可以單獨訪問,也可以組合訪問(2 個組合,3 個組合都可以)。當使用三合一的方式訪問時,應使用名字“xPSR”或者“PSR”。2. PRIMASK, FAULTMASK 和BASEPRI這三個寄存器用于控制異常的使能和除能。名字功能描述PRIMASK這是個只有1 個位的寄存器。當它置1 時,就關掉所有可屏蔽的異常,只剩下NMI和硬fault 可以響應。它的缺省值是0,表示沒有關中斷。FAULTMASK這是個只有1 個位的寄存器。當它置1 時,只有NMI 才能響應,所有其它的異常,包括中斷和fault,通通閉嘴。它的缺

10、省值也是0,表示沒有關異常。BASEPRI這個寄存器最多有9 位(由表達優(yōu)先級的位數(shù)決定)。它定義了被屏蔽優(yōu)先級的閾值。當它被設成某個值后,所有優(yōu)先級號大于等于此值的中斷都被關(優(yōu)先級號越大,優(yōu)先級越低)。但若被設成0,則不關閉任何中斷,0 也是缺省值。對于時間 關鍵任務而言,PRIMASK 和BASEPRI 對于暫時關閉中斷是非常重要的。而FAULTMASK 則可以被OS 用于暫時關閉fault 處理機能,這種處理在某個任務崩潰時可能需要。因為在任務崩潰時,常常伴隨著一大堆faults。在系統(tǒng)料理“后事”時,通常不再需要響應這些fault人死帳清。總之FAULTMASK 就是專門留給OS 用

11、的。要訪問PRIMASK, FAULTMASK 以及BASEPRI,同樣要使用MRS/MSR 指令,如:MRS R0, BASEPRI ;讀取BASEPRI 到R0 中MRS R0, FAULTMASK ;似上MRS R0, PRIMASK ;似上MSR BASEPRI, R0 ;寫入R0 到BASEPRI 中MSR FAULTMASK, R0 ;似上MSR PRIMASK, R0 ;似上只有在特權級下,才允許訪問這3 個寄存器。其實,為了快速地開關中斷,CM3 還專門設置了一條CPS 指令,有4 種用法CPSID I ;PRIMASK=1, ;關中斷CPSIE I ;PRIMASK=0, ;

12、開中斷CPSID F ;FAULTMASK=1, ;關異常CPSIE F ;FAULTMASK=0 ;開異常3.控制寄存器(CONTROL)控制寄存器用于定義特權級別,還用于選擇當前使用哪個堆棧指針。位功能CONTROL1堆棧指針選擇0=選擇主堆棧指針MSP(復位后缺省值)1=選擇進程堆棧指針PSP在線程或基礎級(沒有在響應異常譯注),可以使用PSP。在handler 模式下,只允許使用MSP,所以此時不得往該位寫1。CONTROL00=特權級的線程模式1=用戶級的線程模式Handler 模式永遠都是特權級的。CONTROL1在Cortex M3 的handler 模式中,CONTROL1總是

13、0。在線程模式中則可以為0 或1。僅當處于特權級的線程模式下,此位才可寫,其它場合下禁止寫此位。改變處理器的模式也有其它的方式:在異常返回時,通過修改LR 的位2,也能實現(xiàn)模式切換。這將在第5章中展開論述。CONTROL0僅當在特權級下操作時才允許寫該位。一旦進入了用戶級,唯一返回特權級的途徑,就是觸發(fā)一個(軟)中斷,再由服務例程改寫該位。CONTROL 寄存器也是通過MRS 和MSR 指令來操作的:MRS R0, CONTROLMSR CONTROL, R0三、操作模式Cortex M3 支持2 個模式和兩個特權等級。當處理器處在線程狀態(tài)下時,既可以使用特權級,也可以使用用戶級;另一方面,h

14、andler模式總是特權級的。在復位后,處理器進入線程模式特權級。在線程模式用戶級下,對系統(tǒng)控制空間(SCS)的訪問將被阻止該空間包含了配置寄存器s 以及調試組件的寄存器s。除此之外,還禁止使用MSR 訪問剛才講到的特殊功能寄存器除了APSR 有例外。誰若是以身試法,則將fault 伺候。在特權級下的代碼可以通過置位CONTROL0來進入用戶級。而不管是任何原因產(chǎn)生了任何異常,處理器都將以特權級來運行其服務例程,異常返回后將回到產(chǎn)生異常之前的特權級。用戶級下的代碼不能再試圖修改CONTROL0來回到特權級。它必須通過一個異常handler,由那個異常handler 來修改CONTROL0,才能

15、在返回到線程模式后拿到特權級。把代碼按特權級和用戶極分開對待,有利于使架構更加安全和健壯。例如,當某個用戶代碼出問題時,不會讓它成為害群之馬,因為用戶級的代碼是禁止寫特殊功能寄存器和NVIC中寄存器的。另外,如果還配有MPU,保護力度就更大,甚至可以阻止用戶代碼訪問不屬于它的內存區(qū)域。為了避免系統(tǒng)堆棧因應用程序的錯誤使用而毀壞,你可以給應用程序專門配一個堆棧,不讓它共享操作系統(tǒng)內核的堆棧。在這個管理制度下,運行在線程模式的用戶代碼使用PSP,而異常服務例程則使用MSP。這兩個堆棧指針的切換是全自動的,就在出入異常服務例程時由硬件處理。第8 章將詳細討論此主題。如前所述,特權等級和堆棧指針的選擇

16、均由CONTROL 負責。當CONTROL0=0 時,在異常處理的始末,只發(fā)生了處理器模式的轉換,如下圖所示。但若CONTROL0=1(線程模式+用戶級),則在中斷響應的始末,both 處理器模式和特權等極都要發(fā)生變化,如下圖所示。CONTROL0只有在特權級下才能訪問。用戶級的程序如想進入特權級,通常都是使用一條“系統(tǒng)服務呼叫指令(SVC)”來觸發(fā)“SVC 異?!?,該異常的服務例程可以選擇修改CONTROL0。四、異常與中斷Cortex M3 支持大量異常,包括16 4 1=11 個系統(tǒng)異常,和最多240 個外部中斷簡稱IRQ。具體使用了這240 個中斷源中的多少個,則由芯片制造商決定。由外

17、設產(chǎn)生的中斷信號,除了SysTick 的之外,全都連接到NVIC 的中斷輸入信號線。典型情況下,處理器一般支持16 到32 個中斷,當然也有在此之外的。作為中斷功能的強化,NVIC 還有一條NMI 輸入信號線。NMI 究竟被拿去做什么,還要視處理器的設計而定。在多數(shù)情況下,NMI 會被連接到一個看門狗定時器,有時也會是電壓監(jiān)視功能塊,以便在電壓掉至危險級別后警告處理器。NMI 可以在任何時間被激活,甚至是在處理器剛剛復位之后。下表列出了Cortex M3 可以支持的所有異常。有一定數(shù)量的系統(tǒng)異常是用于fault 處理的,它們可以由多種錯誤條件引發(fā)。NVIC 還提供了一些fault 狀態(tài)寄存器,

18、以便于fault 服務例程找出導致異常的具體原因。五、向量表當一個發(fā)生的異常被CM3 內核接受,對應的異常handler 就會執(zhí)行。為了決定handler 的入口地址,CM3 使用了“向量表查表機制”。這里使用一張向量表。向量表其實是一個WORD(32 位整數(shù))數(shù)組,每個下標對應一種異常,該下標元素的值則是該異常handler 的入口地址。向量表的存儲位置是可以設置的,通過NVIC 中的一個重定位寄存器來指出向量表的地址。在復位后,該寄存器的值為0。因此,在地址0 處必須包含一張向量表,用于初始時的異常分配。舉個例子,如果發(fā)生了異常11(SVC),則NVIC 會計算出偏移移量是11x4=0 x

19、2C,然后從那里取出服務例程的入口地址并跳入。0 號異常的功能則是個另類,它并不是什么入口地址,而是給出了復位后MSP 的初值。六、棧內存操作在Cortex M3 中,除了可以使用PUSH 和POP 指令來處理堆棧外,內核還會在異常處理的始末自動地執(zhí)行PUSH 與POP 操作。本節(jié)讓我們來檢視一下具體的動作,第9 章則討論異常處理時的自動棧操作。1. 堆棧的基本操作籠統(tǒng)地講,堆棧操作就是對內存的讀寫操作,但是其地址由SP 給出。寄存器的數(shù)據(jù)通過PUSH 操作存入堆棧,以后用POP 操作從堆棧中取回。在PUSH 與POP 的操作中,SP 的值會按堆棧的使用法則自動調整,以保證后續(xù)的PUSH 不會

20、破壞先前 PUSH 進去的內容。堆棧的功能就是把寄存器的數(shù)據(jù)放入內存,以便將來能恢復之當一個任務或一段子程序執(zhí)行完畢后恢復。正常情況下,PUSH 與POP 必須成對使用,而且參與的寄存器,不論是身份還是先后順序都必須完全一致。當PUSH/POP 指令執(zhí)行時,SP 指針的值也根著自減/自增。2. Cortex-M3 堆棧的實現(xiàn)Cortex M3 使用的是“向下生長的滿?!蹦P汀6褩V羔楽P 指向最后一個被壓入堆棧的32位數(shù)值。在下一次壓棧時,SP 先自減4,再存入新的數(shù)值。POP 操作剛好相反:先從SP 指針處讀出上一次被壓入的值,再把SP 指針自增4。在進入ISR 時,CM3 會自動把一些寄存

21、器壓棧,這里使用的是進入ISR 之前使用的SP指針(MSP 或者是PSP)。離開ISR 后,只要ISR 沒有更改過CONTROL1,就依然使用先前的SP 指針來執(zhí)行出棧操作。3.再論Cortex-M3 的雙堆棧機制我們已經(jīng)知道了CM3 的堆棧是分為兩個:主堆棧和進程堆棧,ONTROL1決定如何選擇。當CONTROL1=0 時,只使用MSP,此時用戶程序和異常handler 共享同一個堆棧。這也是復位后的缺省使用方式。當CONTROL1=1 時,線程模式將使用PSP,此時,進入異常時的自動壓棧使用的是進程堆棧,進入異常handler 后才自動改為MSP,退出異常時切換回PSP,并且從進程堆棧上彈

22、出數(shù)據(jù)。在特權級下,可以指定具體的堆棧指針,而不受當前使用堆棧的限制,示例代碼如下:MRS R0, MSP ; 讀取主堆棧指針到R0MSR MSP, R0 ; 寫入R0 的值到主堆棧中MRS R0, PSP ; 讀取進程堆棧指針到R0MSR PSP, R0 ; 寫入R0 的值到進程堆棧中通過讀取PSP 的值,OS 就能夠獲取用戶應用程序使用的堆棧,進一步地就知道了在發(fā)生異常時,被壓入寄存器的內容,而且還可以把其它寄存器進一步壓棧(使用STMDB和LDMIA的書寫形式)。OS 還可以修改PSP,用于實現(xiàn)多任務中的任務上下文切換。六、復位序列在離開復位狀態(tài)后,CM3 做的第一件事就是讀取下列兩個32 位整數(shù)的值: 從地址 0 x0000,0000 處取出MSP 的初始值。 從地址 0 x0000,0004 處取出PC 的初始值這個值是復位向量,LSB 必須是1。然后從這個值所對應的地址處取指。請注意,這與傳統(tǒng)的ARM 架構不同其實也和絕大多數(shù)的其它單片機不同。傳統(tǒng)的ARM 架構總是從0 地址開始執(zhí)行第一條指令。它們的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論