本文大量参考了《CM3核心指南》,记录一下在实现简易系统过程中遇到困扰我比较久的问题
主堆栈指针(MSP),或写作 SP_main。这是缺省的堆栈指针,它由 OS 内核、异常服务例程以及所有需要特权访问的应用程序代码来使用。进程堆栈指针(PSP),或写作 SP_process。用于常规的应用程序代码(不处于异常服用例程中时)。
CM3有两个堆栈指针
而我们操作系统用到的是MSP,用户任务代码用到的是PSP,而堆栈指针的切换一直困扰了我很久。
其实他的实现是由LR指针中的一个特殊值来实现的,这个特殊值一般在进入异常时内核自动计算完成,通过把LR[31:4]的位全置为1做为EXC_RETURN的标志,而在中断中对[3:0]位修改则可完成MSP和PSP的切换
下一个问题是,进入了PendSV后,会调度哪个任务,为何会自动进入那个任务。
这个问题和任务的堆栈初始化有关
首先有一个知识是CM3在进入一个异常时会自动把下图中的寄存器入栈(我们使用的PSP,R4-R11要手动入栈)。
我们在返回时切换到了PSP堆栈指针,那么我们只要把PSP指针指向我们要执行的任务的堆栈就行了,CM3会自动出栈,PC指针就指向了我们设置的task即任务函数的第一条指令。
最后就是PendSV触发了
27位置1则触发PendSV中断,即下图操作
要周期性的调度则用Systick周期调用触发就可以了
不过要先把PendSV的优先级设置得比Systick低。
原文:https://www.cnblogs.com/dwk8/p/12048603.html