1. 下面的代碼看的不是很明白,百為stm32開發板光盤\測試程序\CortexM3\Mode_Privilege\project,堆是程序員分配和使用的,棧是編譯器指定的,存放函數參數,臨時變量。
1 #include "stm32f10x_lib.h" 2 #define SP_PROCESS_SIZE 0x200 /* Process stack size */ 3 #define SP_PROCESS 0x02 /* Process stack */ 4 #define SP_MAIN 0x00 /* Main stack */ 5 #define THREAD_MODE_PRIVILEGED 0x00 /* Thread mode has privileged access */ 6 #define THREAD_MODE_UNPRIVILEGED 0x01 /* Thread mode has unprivileged access */ 7 8 ErrorStatus HSEStartUpStatus; 9 vu8 PSPMemAlloc[SP_PROCESS_SIZE]; 10 vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0; 11 12 /* Private function prototypes -----------------------------------------------*/ 13 void RCC_Configuration(void); 14 void NVIC_Configuration(void); 15 16 17 int main(void) 18 { 19 #ifdef DEBUG 20 debug(); 21 #endif 22 23 //時鍾配置 24 RCC_Configuration(); 25 26 //中斷向量表配置 27 NVIC_Configuration(); 28 29 //STM32有一個主堆棧指針MSP,和線程堆棧指針PSP,把進程堆棧指針指向這個數組的高地址,因為堆棧指針是向下增長的 30 /* Switch Thread mode Stack from Main to Process -----------------------------*/ 31 /* Initialize memory reserved for Process Stack */ 32 for(Index = 0; Index < SP_PROCESS_SIZE; Index++) 33 { 34 PSPMemAlloc[Index] = 0x00; 35 } 36 //系統上電,是在線程模式,特權級別下,所以可以修改CONTROL寄存器,這個寄存器選擇特權級和用戶級,還有系統選哪個堆棧指針 37 /* Set Process stack value */ 38 __MSR_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE); 39 //選擇線程堆棧作為線程模式的堆棧,有點繞口 40 /* Select Process Stack as Thread mode Stack */ 41 __MSR_CONTROL(SP_PROCESS); 42 43 /* Get the Thread mode stack used */ 44 if((__MRS_CONTROL() & 0x02) == SP_MAIN) 45 { 46 /* Main stack is used as the current stack */ 47 CurrentStack = SP_MAIN; 48 } 49 else 50 { 51 /* Process stack is used as the current stack */ 52 CurrentStack = SP_PROCESS; 53 54 /* Get process stack pointer value */ 55 PSPValue = __MRS_PSP(); 56 } 57 58 /* Switch Thread mode from privileged to unprivileged ------------------------*//切換線程模式到非特權 59 /* Thread mode has unprivileged access */ 60 __MSR_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS); 61 /* Unprivileged access mainly affect ability to: 62 - Use or not use certain instructions such as MSR fields 63 - Access System Control Space (SCS) registers such as NVIC and SysTick */ 64 65 /* Check Thread mode privilege status */ //檢查當前是特權還是用戶級別 66 if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED) 67 { 68 /* Thread mode has privileged access */ 69 ThreadMode = THREAD_MODE_PRIVILEGED; 70 } 71 else 72 { 73 /* Thread mode has unprivileged access*/ 74 ThreadMode = THREAD_MODE_UNPRIVILEGED; //應該是用戶級別 75 } 76 77 /* Switch back Thread mode from unprivileged to privileged -------------------*/ //切換到特權模式 78 /* Try to switch back Thread mode to privileged (Not possible, this can be 79 done only in Handler mode) */ 80 __MSR_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS); 81 82 /* Generate a system call exception, and in the ISR switch back Thread mode 83 to privileged */ 84 __SVC(); //產生中斷,進入handler模式,特權級別 85 86 /* Check Thread mode privilege status */ 87 if((__MRS_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED) 88 { 89 /* Thread mode has privileged access */ 90 ThreadMode = THREAD_MODE_PRIVILEGED; //應該是特權級別 91 } 92 else 93 { 94 /* Thread mode has unprivileged access*/ 95 ThreadMode = THREAD_MODE_UNPRIVILEGED; 96 } 97 98 while (1) 99 { 100 } 101 }
2. 暫時不明白這個程序什么用途,只是學習的過程中遇到了,拿出來研究一下。
Cortex-M3處理器支持兩種處理器的操作模式,還支持兩級特權操作。
兩種操作模式分別為:處理者模式(handler mode)和線程模式(thread mode)。引入兩個模式的本意,是用於區別普通應用程序的代碼和異常服務例程的代碼——包括中斷服務例程的代碼。Cortex-M3的另一個側面則是特權的分級——特權級和用戶級。這可以提供一種存儲器訪問的保護機制,使得普通的用戶程序代碼不能意外地,甚至是惡意地執行涉及到要害的操作。處理器支持兩種特權級,這也是一個基本的安全模型。
3. 在CM3運行主應用程序時(線程模式),既可以使用特權級,也可以使用用戶級;但是異常服務例程必須在特權級下執行。復位后,處理器默認進入線程模式,特權極訪問。在特權級下,程序可以訪問所有范圍的存儲器(如果有MPU,還要在MPU規定的禁地之外),並且可以執行所有指令。
在特權級下的程序可以為所欲為,但也可能會把自己給玩進去——切換到用戶級。一旦進入用戶級,再想回來就得走“法律程序”了——用戶級的程序不能簡簡單單地試圖改寫CONTROL寄存器就回到特權級,它必須先“申訴”:執行一條系統調用指令(SVC)。這會觸發SVC異常,然后由異常服務例程(通常是操作系統的一部分)接管,如果批准了進入,則異常服務例程修改CONTROL寄存器,才能在用戶級的線程模式下重新進入特權級。事實上,從用戶級到特權級的唯一途徑就是異常:如果在程序執行過程中觸發了一個異常,處理器總是先切換入特權級,並且在異常服務例程執行完畢退出時
4.如果根據下表和上面解釋重新看代碼的話,應該很清楚了。
5. 在看下CONTROL寄存器介紹
6. 如此一來,基本搞明白了。