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