μC/OS-Ⅲ系统的任务切换和任务调度

μC/OS-Ⅲ系统的任务切换和任务调度
一、任务切换


         在操作系统中当任务需要从一个任务切换到另外一个任务时,要将当前任务的现场保存到当前任务的堆栈中(当前任务现场主要指CPU相关寄存器),然后回复新任务的现场并执行新任务。这个叫做上下文切换(context switch),也可以叫任务切换。


        上下文切换会给系统带来一定的负担。CPU寄存器越多,负担越重。切换时间取决于有多少寄存器需要切换。


         在μC/OS-Ⅲ中,任务切换属于与处理器相关需要移植的部分。这部分代码放在几个特殊的文件中:os_cpu.h、os_cpu_c.c和os_cpu_a.asm。


         在μC/OS-Ⅲ中,任务切换有两个函数:任务级切换函数---OSCtxSw()和中断级切换函数---OSIntCtxSw()。这两个函数大体功能相同,区别在于中断级任务切换函数由于仅被中断调度器调用,所以在被调用前已经进行了现场保存(进入中断时需进行现场保存),因此不需要任务级切换的现场保存内容,只需要回复新任务现场即可。任务切换原理书中介绍非常清楚,在此不再详述,具体内容参见本书第一版8.1、8.2节P111。


二、任务调度


        μC/OS-Ⅲ采用可剥夺调度算法,总是执行进入就绪态的优先级最高的任务。


        μC/OS-Ⅲ允许在同一优先级下有多个任务,这些任务间使用时间片轮转调度算法(即相同优先级的任务,每个任务运行一段固定的时间)。


       在程序调用某些μC/OS-Ⅲ服务函数时,调度器会启动,这些时间点又叫调度点。


        μC/OS-Ⅲ有两个调度器:在任务级代码使用OSSched(),在中断服务程序结束时调用OSIntExit()。二者的不同在于OSIntExit()在执行时会进行中断嵌套相关处理,并在任务切换时调用中断级任务切换,而OSSched()不处理中断嵌套,调用任务级任务切换。

-----------------------------------------------------------------------------------------------------------

1,任务调度:任务调度器(scheduler,dispatcher),在下列调度点时,调度器会自动启动:

a,任务释放信号里给另一个任务或者想另外一个任务发消息时。任务调用发布服务OSxxPost()时,如果用户指定禁止调度的参数OS_OPT_POST_NO_SCHED(),则不启动调度任务。

b,任务调用延时函数OSTimeDly(),或者OSTimeDlyHMSM(),当任务被插到等待延时的列表中后,启动scheduler。

c,任务等待事件发生而事件还没有发生,任务调用OSxxxPend()函数。

d,任务取消等待,当任务从某一内核对象(信号量,消息队列等)的等待列表中移除时,启动scheduler。

e,创建和删除任务时,启动scheduler。

f,删除一个内核对象

任务改变自身优先级或者其他任务的优先级

任务通过调用OSTaskSuspend()将自身挂起

任务接触挂起某一调用OSTaskSuspend()挂起的任务

退出所有的嵌套中断

通过OSSchedUnlock()给调度器解锁

任务调用OSSchedRoundRobinYield()放弃其执行时间片

用户调用OSSched()

2,任务切换是指将保存当前任务的现场到当前任务的堆栈中,主要是CPU的相关寄存器,然后恢复新任务的现场并执行新任务,任务切换的时间取决于有多少寄存器需要保存和恢复。在任务级执行任务切换时,OSSched()被调用,来确定新的将要切换到的任务;而当在中断服务程序当中进行任务切换时,有OSIntExit()来完成;OSSched()切换部分的工作有OSCtxSw()完成,而OSIntExit()中任务的切换工作由OSIntCtxSw()完成。OSIntCtxSw()仅需执行任务切换的后半部分,因为系统在中断服务程序是CPU的寄存器已经得到保存。

3,中断是一种硬件机制,用于通知CPU一个异步时间发生了,中断服务程序处理该异步事件,处理过程中可能有更高优先级的任务进入就绪状态,这样当中断服务程序结束后,将直接执行该就绪的高优先级任务且不再返回。

4,关闭全部中断后,CPU将忽略所有的中断请求,但是中断管理器会将这些中断请求锁存,并在CPU重新打开中断后立即产生中断请求。CPU通常有两种中断的模式:

所有中断映射(vector)到一个公用的中断服务程序。

每个中断映射到各自的中断服务程序。

5,应注意区别中断服务程序和用户中断服务程序区别开,中断服务程序是指中断响应到中断返回之间的程序,除了包括用户中断服务程序,还包括开关中断,CPU寄存器出入栈等。

6,中断服务程序中,OSIntNestingCtr变量记录当前中断嵌套的层数。中断结束后,需调用OSIntExit()函数通知内核,同事OSIntNestingCtr变量递减,当递减到0时,说明当前中断服务程序即将退出并返回到任务级代码。

7,uC/OS-III对中断发布消息或信号的处理有两种,直接发布或延时发布,在OS_cfg.h中将OS_CFG_ISR_POST_DEFERED_EN设置为0,使用直接发布模式;设置为1,使用延迟发布模式。要弄清楚两种模式之间的不同。关闭中断会增加中断处理延迟,可能到时后续中断请求的丢失,在实时多任务的内核的一个重要指标就是中断关闭的总时间。在实时多任务系统中在运行临界代码时需要关中断,执行完临界代码段后又要开中断,关闭中断的时间越长,系统的中断等待时间也越长。

如果使用直接发布模式,系统必须关闭中断以保护临界代码。如果采用延迟发布的模式,中断服务程序不是调用系统的发布函数向任务发送消息和信号,而是将发布函数调用和相应的参数写入到专用队列中,该队列成为中断队列(Interrput Queue),然后使中断队列处理任务(Interrupt Queue Handler Task)进入就绪态,这个任务是uC/OS的内部任务,并具有最高的优先级0.

,8,时钟节拍来对任务进行整数个节拍的延迟,并为等待时间的任务提供超时判断,时钟节拍中断必须调用OSTimeTick()函数。时钟节拍中断服务程序首先调用接入函数OSTimeTickHook(),这个函数允许移植者在时钟节拍中断到来后进行额外的操作,比如在介入函数中读取传感器的值,保证采样时刻的均匀,又比如在介入函数总更新脉宽调制(PWM)寄存器,保证输出的精度。


9,同时等待多个内核对象,uC/OS-III系统仅允许同时等待多个信号量和过个消息队列,而不允许等待多个事件标志组或互斥性信号量。OSPendMulti();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值