ucosII任务切换是怎样实现的

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

UC/OS-II学习笔记之——任务切换是怎样实现的问题是,

o Uc/OS-II如何切换任务?通过任务调度器OS_Sched(),那么谁在调用这个函数?

o CPU在这里肯定有作用,因为任务切换必然涉及到CPU寄存器的入栈和出栈,

那么这一块工作是如何完成的?

书上讲:为了做到任务切换,运行OS_TASK_SW(),人为模仿一次中断。中断服务子程序或陷阱处理(trap hardler),也称作事故处理(exception handler),必须给汇编语言函数OSCtxSw()提供中断向量[1.92]。

那么,“人为模仿一次中断”是什么意思?

是指:OS_TASK_SW()触发了一个中断,由中断完成了任务切换?

阅读源代码,查找答案……

#define OS_TASK_SW()OSCtxSw()//这是一个宏调用,定义在os_cpu.h,Os_cpu_a.asm中定义了OSCtxSw

NVIC_INT_CTRL EQU0xE000ED04

NVIC_PENDSVSET EQU0x10000000

;******************************************************************************

;PERFORM A CONTEXT SWITCH(From task level)

;void OSCtxSw(void)

;

;Note(s):1)OSCtxSw()is called when OS wants to perform a task context switch.This function

;triggers the PendSV exception which is where the real work is done.

;******************************************************************************

OSCtxSw

LDR R0,=NVIC_INT_CTRL;Trigger the PendSV exception(causes context switch) LDR R1,=NVIC_PENDSVSET

STR R1,[R0]

BX LR

注释说明该段汇编代码触发了一个PendSV的异常。

在《cortex-M3权威指南》中搜索关键词“PendSV”,可悬挂请求pend able request,在《2.9中断和异常》表7.1“系统异常清单”所列举的异常类型中,定义PendSV为“为系统设备而设的可悬挂请求”[2.109]

(中断优先级PendSV>SysTick>外部中断)

那么,这个PendSV异常的作用到底是什么?

PendSV典型使用场合是上下文切换(任务间切换)。上下文被触发的条件是:[2.125] o系统滴答定时器(SYSTICK)中断(轮转调度中需要)

o执行一个系统调用(TASK level code)

个中事件的流水账记录如下:

(1)任务A呼叫SVC来请求任务切换(例如,等待某些工作完成)

(2)OS接收到请求,做好上下文切换的准备,并且悬起一个PendSV异常。

(3)当CPU退出SVC后,它立即进入PendSV,从而执行上下文切换。

(4)当PendSV执行完毕后,将返回到任务B,同时进入线程模式。

(5)发生了一个中断,并且中断服务程序开始执行

(6)在ISR执行过程中,发生SysTick异常,并且抢占了该ISR。

(7)OS执行必要的操作,然后悬起PendSV异常以作好上下文切换的准备。

(当SysTick退出后,回到先前被抢占的ISR中,ISR继续执行

(9)ISR执行完毕并退出后,PendSV服务例程开始执行,并且在里面执行上下文切换

(10)当PendSV执行完毕后,回到任务A,同时系统再次进入线程模式

中断正在执行,禁止上下文切换。否则中断被延时,而延时时间不可预知——这是实时系统不能容忍的。

早期解决办法,无中断执行时,才执行上下文切换(切换期间无法响应中断)。弊端在于任务切换可能被拖延的很久。[2.126]

PendSv可以解决这个问题,OS会悬起一个PendSv,PendSv异常处理函数处理上下文切换请求——

(1).如果还有未处理完的ISR(图7.17后半段SysTick触发了上下文切换),PendSv被悬起,延迟上下文切换请求,直到处理完ISR后才执行上下文切换;

(2).如果没有任何ISR(图7.17前半段),则立刻调用PendSV异常处理函数完成上下文切换。

需要把PendSv编程为最低优先级的异常。也就是说,PendSv可以像普通中断一样被悬起,OS可以利用它缓期执行一个异常(PendSV)——在其它重要任务完成之后才执行动作(上下文切换)。

悬挂PendSv的方法是:往NVIC的PendSv悬起寄存器中写1。悬起后,如果优先级不够高,则将缓期执行。ICSR(Interrupt Control and State Register0xE000ED04)[bit28]

具体的程序调试:

执行系统函数(悬起PendSV异常的手段之一)OSTimeDlyHMSM(),调用OSTimeDly(),调用task scheduler OS_Sched(),终于执行这个宏调用,调用执行OSCtxSw(),(go to definition of OSCtxSw却不能跳转到汇编代码!),汇编代码把1写入中断控制及状态寄存器寄存器ICSR[bit28]从而悬起一个PendSV异常,这是上图7.17中的步骤2,

Void OS_Sched(void)//任务调度器

{

关中断;

if(没有中断&&没有关调度器)

OS_TASK_SW();//在这里悬起PendSV异常,开中断前先在PendSV Handler设置断点开中断;

}

执行完开中断语句后,程序立刻跳到PendSV异常处理函数PendSV Handler(在此处),这个跳转是如何完成的?具体的入栈、出栈涉及到CPU的哪些寄存器,操作是如何完成的?

执行完PendSV Handler后跳转到空闲任务,实现了任务切换:

相关文档
最新文档