Cortex-m3 任务切换小实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itworld123/article/details/84915496
---------------------------------------------
-- 时间:2018-12-09
-- 创建人:Ruo_Xiao
-- 邮箱:[email protected]
---------------------------------------------

一、声明

本人在“网易云课堂”报名了李述铜老师的《自己动手从0到1写嵌入式操作系统》课程,在《内核编程实践》这堂课中讲解了任务切换的基本方法。对于核心函数“PendSV_Handler”的自己的理解我将记录在下面,由于该课程是付费课程,该工程的源码我觉得不能随便贴上,故只在这里粘贴必要的“PendSV_Handler”的源码,以供自己和该课程的学员参考,本人不会将该贴用于商业用途。如若我有侵权行为请告知,我会及时删除该贴。

二、源码

三、功能

1、该函数的功能是初步理解任务切换的本质,即:保存当前任务所使用的寄存器(R4~R11)的值到内存,中断或者异常服务例程执行完之后,再恢复中断或者异常之前任务的寄存器的值,从而继续执行该任务。

2、第8行~第13行代码是当前任务所使用的寄存器保存到内存。

3、第16行~第18行代码,我理解的是更新栈指针,即:R1。这里的R1相当于SP。

四、解释

1、开始执行该函数时,各个变量的地址及内容如下:

blockPtr                   地址:0x2000 0000  , 内容 : 0x2000 0008

blockPtr->stackPtr  地址 :0x2000 0008  , 内容 :0x2000 1018

2、第8行:LDR     R0, =blockPtr

这里blockPtr相当于符号,该代码的含义是将blockPtr的地址传给R0,即:R0 = &blockPtr = 0x2000 0000 。

3、第9行:LDR     R0, [R0]

该代码的含义是R0 = *R0,也就是R0 = R0中的内容,即:R0 = blockPtr = &(bolckPtr->stackPtr) = 0x2000 0008。

4、第10行:LDR     R0, [R0]

该代码的含义同上,即:R0 = bolckPtr->stackPtr = &stackBuffer[1024]= 0x20001018。

执行完该句,R0就指向了stackBuffer[1024]

5、第13行:STMDB   R0!, {R4-R11}

该代码的含义是将R11~R4的值逐个存储在stackBuffer[1023]~stackBuffer[1016]中。

过程如下:

(1)R0 = R0 - 4 , 将R11压入*R0中。

(2)R0 = R0 - 4 , 将R10压入*R0中。    ……

(3)R0 = R0 - 4, , 将R4压入*R0中。

结果如下:

执行到这里,就完成了将R4~R11压入内存中的使命。

6、第16行~17行,含义同第8行~第9行。

7、第18行:    STR     R0, [R1]

该代码的含义是将R0的值压入*R1中,即:bolckPtr->stackPtr = R0 = 0x20000FF8。

这里0x20000FF8是第13行执行完成之后,R0的值由0x2000 1018 - 0x0000 0020 (4*8的十六进制) = 0x20000FF8。

8、第21~22行,相当于执行是其他任务,任务内容是R4 = R4 + 1,,R5 = R5 + 1。

9、第25行:LDMIA   R0!, {R4-R11}

将R0所执行的内存中的数据依次压入R4~R11中。

过程如下:

将*R0中的内容压入R4中,R0 = R0 + 4;

将*R0中的内容压入R5中,R0 = R0 + 4;  ……

将*R0中的内容压入R11中,R0 = R0 + 4;

执行完之后,R0中的内容恢复到0x2000 1018,即:指向了stackBuffer[1024]

10、第28行:BX      LR

异常返回。

整个函数执行完成之后,实现了保存寄存器入栈,执行其他任务,弹栈恢复寄存器的值,从而完成任务切换功能。

(SAW:Game Over!)

猜你喜欢

转载自blog.csdn.net/itworld123/article/details/84915496