什么是栈?
在谈M3堆栈之前我们先回忆一下数据结构中的栈。栈是一种先进后出的数据结构(类似于枪支的弹夹,先放入的子弹最后打出,后放入的子弹先打出)。M3内核的堆栈也不例外,也是先进后出的。
栈的作用?
局部变量内存的开销,函数的调用都离不开栈。
了解了栈的概念和基本作用后我们来看M3的双堆栈
cortex-M3内核使用了双堆栈,即MSP和PSP,这极大的方便了OS的设计。
MSP的含义是Main_Stack_Pointer,即主栈
PSP的含义是 Process_Stack_Pointer,即任务栈
SP:SP是堆栈指针,指向最后一个被压入元素的地址。
M3的压栈和弹栈过程:
压栈:SP先自减4,然后将待压入的数据存放到SP所指的地址
弹栈:从SP指针所指的地址读出数据,然后SP指针自增4。
为什么压栈SP自减,弹栈SP自增呢?这是因为M3内核堆栈生长方向是向下的。为什么压栈和弹栈分别是减4加4呢?这是因为M3是32bit的内核。
M3内核何时使用MSP何时使用PSP?
M3双堆栈的意思是有两个堆栈,但是任何时刻只能使用其中之一。那什么时候使用MSP,什么时候使用PSP呢?也就是说SP寄存器中的值在某一时刻到底是使用MSP的值还是PSP的值?这是根据CONTROL寄存器的bit1来决定的。当CONTROL的bit1为0使用MSP(默认方式);当CONTROL的bit1为1使用PSP。
总结:CONTROL的bit1为0,SP = MSP
CONTROL的bit1为1,SP = PSP
M3复位后处于线程模式特权级,默认使用MSP。
通过配置CONTROL寄存器的bit1位就可以决定SP使用MSP还是PSP。
在裸机开发中,CONTROL的bit1始终是0,也就是说裸机开发中全程使用程MSP,并没有使用PSP。在执行后台程序(大循环程序)SP使用的是MSP,在执行前台程序(中断服务程序)SP使用的是MSP。
在OS开发中,当运行中断服务程序的时候CONTROL的bit1是0,SP使用的是MSP;当运行线程程序的时候CONTROL的bit1是1,SP使用的是PSP。