首先内容可能会引用出多的资料,这里表示感谢,不对的也可以指出。
1.很多时候一直困惑,stm32的MSP和PSP到底什么时候用哪个栈呢,都知道这是影子寄存器,同一时刻只用其中一个寄存器,到底是用哪个呢,这个好办,我们就看R13寄存器到底等于MSP还是PSP,和哪个相等就表示当前正在用哪个
比如这张图,看到R13就是等于MSP,表明现在就是用MSP这个寄存器,意味着现在就是用的主栈。这是在调试状态下看到的,那实际跑freeRTOS的时候在线程里到底是MSP还是PSP呢,
翻过很多人的博客关于这个描述,很多都是说什么OS内核和中断下使用MSP,这句话我估计是comtex-m3权威指南里的一句话,被很多人引用,但是看这句话依然有困惑,在使用freeRTOS的时候调用free的接口的时候,到底是用MSP还是PSP呢,比如我调用free的获取信号量接口,free是不是OS,那这个代码是不是OS代码,请问是用的MSP还是PSP,还是一头雾水。
当然有部分文章就直接了当地说,除了中断使用MSP,其它全部使用PSP,这就比较明确了,不会让人有疑惑,比如下面这个。
我见过不少文章是这么明确的说的,那到底是不是呢,很简单,还是在调试环境下看。
这里我用的是rtt的工程,我估计大同小异,在idle线程打个断点,看R13寄存器就是PSP寄存器啊,idle线程肯定是OS的代码啊,所以在中断里使用MSP,除此之外都使用PSP我认为这个说法更准确。
2.CONTROL寄存器
提到MSP,PSP就免不了提control寄存器了,因为它往往和PSP MSP之间的切换相关联,特权模式还是线程模式相关联,而特殊寄存器又得特权模式下访问和写入。
这也是权威指南的内容了。也是很官方很难懂啊,什么是handle什么是特权级,什么是用户级,
反正我认为进中断一定是特权级了,应该也是handle(不是很确定,八九不离十吧)
这是网上的一张图。
所以我的理解就是中断是handle模式,除此之外就是线程模式。
handle下一定是特权模式,但是线程模式可以是特权还是非特权模式。
我知道这样说又很笼统了,那在rtos下,中断以外的代码包括rtos内核代码到底是运行在特权还是非特权呢。
想想要想操作特殊寄存器就得在特权模式下,那freeRTOS进临界区就是通过修改PRIMASK寄存器来实现的啊,这么看,正常代码就是在特权下,说白了用户模式还是handle模式都是特权模式,我们并未使用线程非特权模式。如何佐证呢,我只是在调试环境下看control寄存器的值吧。
以上分别是在idle线程和中断里打的断点,可见control寄存器的最低位都是0,手册里最低位0就表示线程特权级,也是个缺省值。
3.PSP和MSP如何切换呢。
上面这张图,看到control寄存器的值是0x02 ,表明现在是使用PSP,这个也符合现象。
如何切换PSP和MSP,按照官方说法是两种办法。
翻遍RTT的代码,也没有找到control寄存器的操作,因此我认为第二种的可能性大。
看RTT的这个线程切换函数里不就是修改了LR寄存器的值吗,所以是通过修改LR寄存器来实现MSP和PSP的切换,自始至终没有去改control寄存器的值。