本文大量参考了《CM3核心指南》,记录一下在实现简易系统过程中遇到困扰我比较久的问题

img

主堆栈指针(MSP),或写作 SP_main。这是缺省的堆栈指针,它由 OS 内核、异常服务

例程以及所有需要特权访问的应用程序代码来使用。

进程堆栈指针(PSP),或写作 SP_process。用于常规的应用程序代码(不处于异常服

用例程中时)。

CM3有两个堆栈指针

而我们操作系统用到的是MSP,用户任务代码用到的是PSP,而堆栈指针的切换一直困扰了我很久。

img

其实他的实现是由LR指针中的一个特殊值来实现的,这个特殊值一般在进入异常时内核自动计算完成,通过把LR[31:4]的位全置为1做为EXC_RETURN的标志,而在中断中对[3:0]位修改则可完成MSP和PSP的切换

img

img

下一个问题是,进入了PendSV后,会调度哪个任务,为何会自动进入那个任务。

这个问题和任务的堆栈初始化有关

首先有一个知识是CM3在进入一个异常时会自动把下图中的寄存器入栈(我们使用的PSP,R4-R11要手动入栈)。

img

我们在返回时切换到了PSP堆栈指针,那么我们只要把PSP指针指向我们要执行的任务的堆栈就行了,CM3会自动出栈,PC指针就指向了我们设置的task即任务函数的第一条指令。

img

最后就是PendSV触发了

img

27位置1则触发PendSV中断,即下图操作

img

要周期性的调度则用Systick周期调用触发就可以了

不过要先把PendSV的优先级设置得比Systick低。

img

最后修改:2022 年 04 月 28 日
如果觉得我的文章对你有用,请随意赞赏