简述在任务准备就绪运行挂起任务表查找具有最高优先级别的准备就绪运行挂起任务任务的过程

ucos 任务就绪表及任务调度
我的图书馆
ucos 任务就绪表及任务调度
http://blog.csdn.net/suiyuan/article/details/2013
1:任务就绪表
操作系统为就绪的任务分配CPU的使用权是操作系统的核心工作,操作系统必要能够判断系统的
那些任务是出于就绪状态,同时对就绪的任务进行调度执行。
在任务的各种状态中,OS总是从就绪的任务列表选取将要运行的任务。在ucos中,系统使用二进制的位图来记录
系统中处于就绪状态的任务,用二进制的0和1来表示此任务是否出于就绪状态。
在ucos中定义全局变量OSRdyTbl来表示任务就绪表
#if OS_LOWEST_PRIO &= 63
OS_EXT &INT8U & & & & & & OSRdyG & & & & & & & & & & & &/* Ready list group & & & & & & & & & & & & */
OS_EXT &INT8U & & & & & & OSRdyTbl[OS_RDY_TBL_SIZE]; & & & /* Table of tasks which are ready to run & &*/
OS_EXT &INT16U & & & & & &OSRdyG & & & & & & & & & & & &/* Ready list group & & & & & & & & & & & & */
OS_EXT &INT16U & & & & & &OSRdyTbl[OS_RDY_TBL_SIZE]; & & & /* Table of tasks which are ready to run & &*/
其中OS_RDY_TBL_SIZE定义为:
#if OS_LOWEST_PRIO &= 63
#define &OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) & /* Size of event table & & & & & & & & & & & & */
#define &OS_RDY_TBL_SIZE & ((OS_LOWEST_PRIO) / 8 + 1) & /* Size of ready table & & & & & & & & & & & & */
#define &OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 16 + 1) &/* Size of event table & & & & & & & & & & & & */
#define &OS_RDY_TBL_SIZE & ((OS_LOWEST_PRIO) / 16 + 1) &/* Size of ready table & & & & & & & & & & & & */
当OS_LOWEST_PRIO &= 63时,任务就绪表对大能表示的二进制位数为32(4*8),则表示ucos最多能记录出于就绪状态的任务数。
其中OSRdyTbl定义为INT8U,上面的每一个bit表示此优先级的对应的任务的就绪状态,当为1时表示就绪,当为0时此任务非就绪。任务就绪表中的每一个元素中的bit位的编号代表任务的优先级。就绪表中的一个元素可以表示8个任务的就绪状态。因此就绪表中的8个元素就可以表示64(8*8)个任务的就绪状态,将就绪表中的每一个元素所代表的8个任务视为一个任务组。在上面的代码中定义了:OSRdyGrp,OSRdyGrp中的每一个bit代表了处于就绪状态的任务组。
上面的表对应的是当前系统中任务的个数为64的情况,OSRdyGrp中的那个bit为1,则表示此位对应的就绪表元素中
有出于就绪状态的任务。
上面的文字说明的是如何根据一个任务的优先级来确定在就绪表中的位置,现在看看相关的代码。
&在任务的TCB中定义了所谓的X和Y变量,从上面的代码中可以知道,Y:代表的是在哪一个就绪表中元素中,X:代表的是在就绪表元素Y中的哪一个bit上。其中OSRdyGrp与Y进行与操作将告诉组中的哪一个元素组中有任务处于就绪状态。有了X和Y的值,就可以在任务就绪表中取得最高优先级的任务ID标识。在ucos中使用以下方式:
2: 任务调度
从字面意思是就是调度,但是调度什么了?在多任务的操作系统中就是调度任务。在多任务系统中,令CPU终止当前正在运行的任务转而去运行另一个任务的工作叫任务切换,而按某种规则进行切换的工作叫任务的调度。
在ucos中任务调度由任务调度器来完成,任务的调度的主要工作有:
1:在任务就绪表中取出优先级最高的就绪任务。
2:实现任务的切换。
在ucos中有俩种类型的调度器:1:任务级的调度器,2:中断级的调度器。任务级的调度由函数:OS_Sched (void)来实现。中断级的调度由:OSIntExit (void)来实现。
在ucos中对任务的管理是通过任务控制块来完成,因此在进行任务切换之前就必须获取到当前就绪及正在运行的任务的TCB,
在前面看到过全局变量:
OS_EXT &OS_TCB & & & & & *OSTCBCur; & & & & &/* Pointer to currently running TCB & & & & */
OS_EXT &OS_TCB & & & & & *OSTCBHighRdy; & & &/* Pointer to highest priority TCB R-to-R & */
OS_EXT &INT8U & & & & & &&OSPrioCur; & & & & /* Priority of current task & & & & & & & & & & & &*/
OS_EXT &INT8U & & & & & &&OSPrioHighRdy; & & /* Priority of highest priority task & & & & & & & */
在任务调度器函数中:判断当前任务的优先级ID与就绪任务中的优先级ID是否不等,如果不等的话,则进行任务的切换。之后根据优先级ID在全局的OSTCBPrioTbl任务TCB中取出对于此ID的任务TCB,
即OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
*********************************************************************************************************
* & & & & & & & & & & & & & & & & & & & & & & &SCHEDULER
* Description: This function is called by other uC/OS-II services to determine whether a new, high
* & & & & & & &priority task has been made ready to run. &This function is invoked by TASK level code
* & & & & & & &and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
* Arguments &: none
* Returns & &: none
* Notes & & &: 1) This function is INTERNAL to uC/OS-II and your application should not call it.
* & & & & & & &2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
*********************************************************************************************************
void &OS_Sched (void)
#if OS_CRITICAL_METHOD == 3 & & & & & & & & & & & & & &/* Allocate storage for CPU status register & & */
& & OS_CPU_SR &cpu_sr = 0;
& & OS_ENTER_CRITICAL();
& & if (OSIntNesting == 0) { & & & & & & & & & & & & & /* Schedule only if all ISRs done and ... & & & */
& & & & if (OSLockNesting == 0) { & & & & & & & & & & &/* ... scheduler is not locked & & & & & & & & &*/
& & & & &&& OS_SchedNew();
& & & & & & if (OSPrioHighRdy&!= OSPrioCur) { & & & & &/* No Ctx Sw if current task is highest rdy & & */
& & & & & & & & OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN & 0
& & & & & & & & OSTCBHighRdy-&OSTCBCtxSwCtr++; & & & & /* Inc. # of context switches to this task & & &*/
& & & & & & & & OSCtxSwCtr++; & & & & & & & & & & & & &/* Increment context switch counter & & & & & & */
& & & & & & & & OS_TASK_SW(); & & & & & & & & & & & & &/* Perform a context switch & & & & & & & & & & */
& & & & & & }
& & OS_EXIT_CRITICAL();
在上面的代码中OS_SchedNew()函数就是在就绪任务中找出优先级最高的任务的ID即OSPrioHighRdy的值是最高优先级任务的优先级ID。
*********************************************************************************************************
* & & & & & & & & & & & & & & &FIND HIGHEST PRIORITY TASK READY TO RUN
* Description: This function is called by other uC/OS-II services to determine the highest priority task
* & & & & & & &that is ready to run. &The global variable 'OSPrioHighRdy' is changed accordingly.
* Arguments &: none
* Returns & &: none
* Notes & & &: 1) This function is INTERNAL to uC/OS-II and your application should not call it.
* & & & & & & &2) Interrupts are assumed to be disabled when this function is called.
*********************************************************************************************************
static &void &&OS_SchedNew(void)
#if OS_LOWEST_PRIO &= 63 & & & & & & & & & & & & /* See if we support up to 64 tasks & & & & & & & & & */
& & INT8U &
& & y & & & & & & = OSUnMapTbl[OSRdyGrp];
& &&OSPrioHighRdy&= (INT8U)((y && 3) + OSUnMapTbl[OSRdyTbl[y]]);
#else & & & & & & & & & & & & & & & & & & & & & &/* We support up to 256 tasks & & & & & & & & & & & & */
& & INT8U &
& & INT16U *
& & if ((OSRdyGrp & 0xFF) != 0) {
& & & & y = OSUnMapTbl[OSRdyGrp & 0xFF];
& & } else {
& & & & y = OSUnMapTbl[(OSRdyGrp && 8) & 0xFF] + 8;
& & ptbl = &OSRdyTbl[y];
& & if ((*ptbl & 0xFF) != 0) {
& & & & OSPrioHighRdy = (INT8U)((y && 4) + OSUnMapTbl[(*ptbl & 0xFF)]);
& & } else {
& & & & OSPrioHighRdy = (INT8U)((y && 4) + OSUnMapTbl[(*ptbl && 8) & 0xFF] + 8);
3:任务切换
上面的函数OS_Sched()为任务级的任务切换函数,在函数当(OSPrioHighRdy != OSPrioCur)的时候,将会执行
OS_TASK_SW(); & /* Perform a context switch */
其中任务切换就是:种植当前在整在运行的任务(OSTCBCur),转而执行另一个任务(OSTCBHighRdy)的过程.
#define &OS_TASK_SW() & & & & OSCtxSw()
其中OSCtxSw为汇编代码。
在cortex-M3中有一个系统时钟tick,周期性的为系统提供系统时钟。
是一个中断处理函数,周期性的执行,在其代码中有函数。void &OSIntExit (void),其函数内容和OS_SchedNew
void &OSIntExit (void)
#if OS_CRITICAL_METHOD == 3 & & & & & & & & & & & & & & & &/* Allocate storage for CPU status register */
& & OS_CPU_SR &cpu_sr = 0;
& & if (OSRunning == OS_TRUE) {
& & & & OS_ENTER_CRITICAL();
& & & & if (OSIntNesting & 0) { & & & & & & & & & & & & & &/* Prevent OSIntNesting from wrapping & & & */
& & & & & & OSIntNesting--;
& & & & if (OSIntNesting == 0) { & & & & & & & & & & & & & /* Reschedule only if all ISRs complete ... */
& & & & & & if (OSLockNesting == 0) { & & & & & & & & & & &/* ... and not locked. & & & & & & & & & & &*/
& & & & & & & & OS_SchedNew();
& & & & & & & & if (OSPrioHighRdy != OSPrioCur) { & & & & &/* No Ctx Sw if current task is highest rdy */
& & & & & & & & & & OSTCBHighRdy &= OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN & 0
& & & & & & & & & & OSTCBHighRdy-&OSTCBCtxSwCtr++; & & & & /* Inc. # of context switches to this task &*/
& & & & & & & & & & OSCtxSwCtr++; & & & & & & & & & & & & &/* Keep track of the number of ctx switches */
& & & & & & & & & & OSIntCtxSw(); & & & & & & & & & & & & &/* Perform interrupt level ctx switch & & & */
& & & & & & & & }
& & & & & & }
& & & & OS_EXIT_CRITICAL();
;********************************************************************************************************
; & & & & & & & & & & & & & & & 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.
;********************************************************************************************************
& & LDR & & R0, =NVIC_INT_CTRL & & & & & & & & & & & & & & & & &; Trigger the PendSV exception (causes context switch)
& & LDR & & R1, =NVIC_PENDSVSET
& & STR & & R1, [R0]
& & BX & & &LR
从上面的解析可以知道,上面的代码触发 PendSV exception异常,其PendSV中断处理函数才是实际的任务切换工作。
;********************************************************************************************************
; & & & & & & & & & & & & & & & & & & & & HANDLE PendSV EXCEPTION
; & & & & & & & & & & & & & & & & & & void OS_CPU_PendSVHandler(void)
; Note(s) : 1) PendSV is used to cause a context switch. &This is a recommended method for performing
; & & & & & & &context switches with Cortex-M3. &This is because the Cortex-M3 auto-saves half of the
; & & & & & & &processor context on any exception, and restores same on return from exception. &So only
; & & & & & & &saving of R4-R11 is required and fixing up the stack pointers. &Using the PendSV exception
; & & & & & & &this way means that context saving and restoring is identical whether it is initiated from
; & & & & & & &a thread or occurs due to an interrupt or exception.
; & & & & & 2) Pseudo-code is:
; & & & & & & &a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
; & & & & & & &b) Save remaining regs r4-r11
; & & & & & & &c) Save the process SP in its TCB, OSTCBCur-&OSTCBStkPtr = SP;
; & & & & & & &d) Call OSTaskSwHook();
; & & & & & & &e) Get current high priority, OSPrioCur = OSPrioHighR
; & & & & & & &f) Get current ready thread TCB, OSTCBCur = OSTCBHighR
; & & & & & & &g) Get new process SP from TCB, SP = OSTCBHighRdy-&OSTCBStkP
; & & & & & & &h) Restore R4-R11 fr
; & & & & & & &i) Perform exception return which will restore remaining context.
; & & & & & 3) On entry into PendSV handler:
; & & & & & & &a) The following have been saved on the process stack (by processor):
; & & & & & & & & xPSR, PC, LR, R12, R0-R3
; & & & & & & &b) Processor mode is switched to Handler mode (from Thread mode)
; & & & & & & &c) Stack is Main stack (switched from Process stack)
; & & & & & & &d) OSTCBCur & & &points to the OS_TCB of the task to suspend
; & & & & & & & & OSTCBHighRdy &points to the OS_TCB of the task to resume
; & & & & & 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
; & & & & & & &know that it will only be run when no other exception or interrupt is active, and
; & & & & & & &therefore safe to assume that context being switched out was using the process stack (PSP).
;********************************************************************************************************
OS_CPU_PendSVHandler
& & CPSID & I & & & & & & & & & & & & & & & & & & & & & & & & & ; Prevent interruption during context switch
& & MRS & & R0, PSP & & & & & & & & & & & & & & & & & & & & & & ; PSP is process stack pointer
& & CBZ & & R0, OS_CPU_PendSVHandler_nosave & & & & & & & & & & ; Skip register save the first time
& & SUBS & &R0, R0, #0x20 & & & & & & & & & & & & & & & & & & & ; Save remaining regs r4-11 on process stack
& & STM & & R0, {R4-R11}
& & LDR & & R1, =OSTCBCur & & & & & & & & & & & & & & & & & & & ; OSTCBCur-&OSTCBStkPtr = SP;
& & LDR & & R1, [R1]
& & STR & & R0, [R1] & & & & & & & & & & & & & & & & & & & & & &; R0 is SP of process being switched out
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & ; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
& & PUSH & &{R14} & & & & & & & & & & & & & & & & & & & & & & & ; Save LR exc_return value
& & LDR & & R0, =OSTaskSwHook & & & & & & & & & & & & & & & & & ; OSTaskSwHook();
& & BLX & & R0
& & POP & & {R14}
& & LDR & & R0, =OSPrioCur & & & & & & & & & & & & & & & & & & &; OSPrioCur = OSPrioHighR
& & LDR & & R1, =OSPrioHighRdy
& & LDRB & &R2, [R1]
& & STRB & &R2, [R0]
& & LDR & & R0, =OSTCBCur & & & & & & & & & & & & & & & & & & & ; OSTCBCur &= OSTCBHighR
& & LDR & & R1, =OSTCBHighRdy
& & LDR & & R2, [R1]
& & STR & & R2, [R0]
& & LDR & & R0, [R2] & & & & & & & & & & & & & & & & & & & & & &; R0 is new process SP; SP = OSTCBHighRdy-&OSTCBStkP
& & LDM & & R0, {R4-R11} & & & & & & & & & & & & & & & & & & & &; Restore r4-11 from new process stack
& & ADDS & &R0, R0, #0x20
& & MSR & & PSP, R0 & & & & & & & & & & & & & & & & & & & & & & ; Load PSP with new process SP
& & ORR & & LR, LR, #0x04 & & & & & & & & & & & & & & & & & & & ; Ensure exception return uses process stack
& & CPSIE & I
& & BX & & &LR & & & & & & & & & & & & & & & & & & & & & & & & &; Exception return will restore remaining context
[转]&[转]&[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(3041)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'任务就绪表(OS_TCB)
blogAbstract:'
uC/OS是通过查表法找到准备就绪的优先级最高的任务,下面将说明查表的过程。为了实现就绪任务的快速查找,uC/OS采用了一种奇特的方式。既然uC/OS中每一个任务的优先级是唯一的,不存在相同优先级的两个任务,所以可以根据优先级来唯一的确定任务。uC/OS支持64个任务,也就是由64个优先级0-63,二进制中可以用6位来表示,然后根据高三位将64个任务分为8个准备就绪表数组OSRdyTbl[7],每组又根据低3位包含8个任务,也就是把64个任务构成一个8*8的矩阵(这个矩阵图书上是有的)。在这个矩阵中,8个行向量分别有OS_RdyTbl[0]~OS_RdyTbl[7]表示,而OS_RdyTbl[]这个数组的每个元素是一个8bit的数,它的每一位代表一个任务的是否就绪状态,若每组有任务处于就绪态,则相应的比特置1;假设任务3和任务5处于就绪态,则OSRdyTbl[0]=0x28,其中',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:7,
publishTime:2,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}文档分类:
学号-姓名-嵌入式实时操作系统课后习题.doc
下载后只包含 1 个 DOC 格式的文档,没有任何的图纸或源代码,
您的浏览器不支持进度条
下载文档到电脑,查找使用更方便
还剩?页未读,继续阅读
该用户其他文档
下载所得到的文件列表学号-姓名-嵌入式实时操作系统课后习题.doc
文档介绍:
北京师范大学珠海分校信息技术学院
课后习题测试
课程名称:µC/OS-II嵌入式实时操作系统任课教师:__杨博雄__
姓名_________________ 学号_________________ 班级__________________
简述嵌入式操作系统与普通操作系统的区别?请你用身边中一个有关嵌入式应用系统举例说明嵌入式操作系统在其中的作用和地位?
什么是任务控制块链表?简述在任务就绪表中查找具有最高优先级别的就绪任务的过程?
µC/OS-II的中断服务程序合适返回被中断的任务?何时不返回被中断的任务?
什么叫优先级反转?这种现象会在什么情况下发生?有什么危害?
能否使用全局变量来实现任务间的通信?如果可以,它有什么缺点?
什么叫内存分区?什么叫内存块?内存分区与内存块之间有什么关系?
内容来自淘豆网www.taodocs.com转载请标明出处.
文件大小:0 KB
下载次数:任务调度器实现及源代码分析_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
任务调度器实现及源代码分析
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 百度查找的优先级别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信