STM32堆棧指針疑問


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. 如此一來,基本搞明白了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM