
本帖最后由 baiyongbin2009 于 2014-12-19 16:41 编辑 $ K. w' g6 ?' o# L: w1 K 特别说明:2 h. T# r! q$ ? 1. 本教程是安富莱电子原创。. n% q4 E9 {* K( ~ 2. 安富莱STM32F407开发板资料已经全部开源,开源地址:地址链接; w; o8 b6 ?" k ~# n+ ^ 3. 当前共配套300多个实例,4套用户手册。 第5章 任务切换设计 6 X# B/ i( r( o) a3 K/ f2 u 本期教程带领大家学习简易任务切换的设计,主要是学习SVC(Supervisor Call)和PendSV(Pendable Service Call)的使用,并在此基础上设计一个简单的时间片调度器。本期教程要涉及到一些汇编的知识,不过不用担心,用户只需了解一些简单的汇编命令就可以了,最重要的还是理解任务是如何实现切换的。 5.1 中断的响应序列 5.2 SVC异常 5.3 PendSV异常 5.4 实验例程说明 5.5 实验总结 5.1 中断的响应序列 由于SVC和PendSV中断需要用汇编来实现,用汇编来实现就得了解发生中断事件后,处理器内核是如何响应这个过程的。总的来说,当CM3/CM4开始响应一个中断时,会按照如下过程响应中断事件: l 入栈:不带浮点寄存器的情况下会有8个寄存器的值压入栈,带浮点寄存器的情况下会有26个寄存器压入栈。 l 取向量:从向量表中找出对应的服务程序入口地址。 l 选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC。 5.1.1 入栈 响应异常的第一个行动,就是自动保存现场的必要部分:依次把xPSR,PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈中(如果程序中做了浮点运算,还有18个浮点寄存器需要入栈):如果当响应异常时,当前的代码正在使用PSP,则压入PSP,也就是使用进程堆栈;否则就压入MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈。 下表是带有浮点寄存器和不带有浮点寄存器的异常堆栈,地址由上到下递减。 ![]() 注意左侧的浮点寄存器列表,在寄存器FPSCR上面是一个保留寄存器,在给任务堆栈分配大小时要考虑到这个寄存器,同时要注意这些寄存器的存储顺序。上面的寄存器是自动入栈的,还有寄存器R4-R11以及浮点寄存器S16-S31需要手动入栈的。这里有三个知识点,大家要注意: l 双字对齐的堆栈工作模式(大家可以查阅Cortex-M3权威指南中文版9.1.1小节进行了解,Cortex-M4现在最新的r0p1版,不知道此功能是否自动打开,后面查阅相关资料了,再做详细介绍)。 l 为什么R0-R3以及R12可以自动的入栈,而R4-R11是手动入栈?原因就在于ARM上,有一套的C函数调用标准约定(《C/C++ Procedure Call Standard for the ARM Architecture》,AAPCS,Ref5)。各种原因就在它上面:它使得中断服务例程能用C语言编写,编译器优先使用入栈了的寄存器来保存中间结果(当然,如果程序过大也可能要用到R4-R11,此时编译器负责生成代码来push它们)。 l 为什么R0-R3, R12是最后被压进去的?这样可以更容易地使用SP基址来索引寻址,(这也方便了LDM等多重加载指令。因为LDM必须加载地址连续的一串数据,而现在R0-R3, R12的存储地址连续了)。这种顺序也舒展了参数的传递过程:使之可以方便地通过读取入栈了的R0-R3取出 (主要为系统软件所利用,多见于SVC与PendSV中的参数传递)。 5.1.2 取向量 当数据总线(系统总线)正在进行入栈操作时,指令总线(I-Code总线)执行另一项重要的任务:从向量表中找出正确的异常向量,然后在服务程序的入口处预取指。由此可以看到各自都有专用总线的好处:入栈与取指这两个工作能同时进行。 5.1.3 更新寄存器 在入栈和取向量操作完成之后,执行服务例程之前,还要更新一系列的寄存器: l SP:在入栈后会把堆栈指针(PSP或MSP)更新到新的位置。在执行服务例程时,将由MSP负责对堆栈的访问。 l PSR:更新IPSR位段(地处PSR的最低部分)的值为新响应的异常编号。 l PC:在取向量完成后,PC将指向服务例程的入口地址。 l LR:在出入ISR的时候,LR的值将得到重新的诠释,这种特殊的值称为“EXC_RETURN”(这个在上期教程有讲解)在异常进入时由系统计算并赋给LR,并在异常返回时使用它。 以上是在响应异常时通用寄存器的变化。另一方面,在NVIC中,也会更新若干个相关有寄存器。例如,新响应异常的悬起位将被清除,同时其活动位将被置位。 |
, l& g t8 {- q8 p* S
5.2.2 SVC触发方式
5.2.3 SVC的使用
5.3.2 裸机中使用PendSV
5.4.2 实验二:任务切换设计(时间片调度不带浮点)
. ~8 [3 r# M: @6 w& K
(续)5.4.2 实验二:任务切换设计(时间片调度不带浮点)6 G5 U8 |$ @, e$ K/ }
3 {9 o" i: O z* |9 [