第2章 uCOS-II中的任务.ppt_第1页
第2章 uCOS-II中的任务.ppt_第2页
第2章 uCOS-II中的任务.ppt_第3页
第2章 uCOS-II中的任务.ppt_第4页
第2章 uCOS-II中的任务.ppt_第5页
已阅读5页,还剩142页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,1 任务的基本概念,任务概述 任务状态 系统任务,1)任务概述,从程序设计角度看,uc/os-ii中的任务是一个线程,其代码通常是一个无限循环结构/超循环结构,看起来像其它c函数一样。,void mytask(void *pdata) for (;) do something; waiting; do something; ,从任务的存储结构看,任务由三个部分组成: 任务控制块、任务代码与任务堆栈,1)任务概述,1)任务概述,1)任务概述,c/os ii 支持64个任务,每个任务有一个特定的优先级。 任务的优先级别用数字表示,0表示的任务的优先级最高,数字越大表示的优先级越低。 通过常数os_lowest_prio (在os_cfg.h中)定义系统的最低优先级别,同时限定系统能容纳的最多任务数量。 建议用户不要使用优先级为0、1、2、3、os_lowest_prio-3、 os_lowest_prio-2、 os_lowest_prio-1、 os_lowest_prio-0的任务。最低的两个已被目前版本的系统占用,将来版本可能会用到其它的。,2)任务状态,睡眠态(dormant): 任务驻留在程序空间,还没有交给c/os-管理,还没有配备任务控制块,还没有创建。把任务交给c/os-是通过调用下述两个函数之一来完成的:ostaskcreate()或ostaskcreateext()。 就绪态(ready): 任务一旦建立,就进入就绪态准备运行。一个任务可以通过调用ostaskdel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。,2)任务状态,运行态(running): 正在使用cpu的状态称运行态。就绪的任务只有当所有优先级高于自己的任务转为等待状态,或者是被删除了,才能进入运行态。 等待态(waiting):等待某事件发生的状态. 正在运行的任务可以通过调用ostimedly()或ostimedlyhmsm()进入等待状态 调用ossempend()、osmboxpend()或osqpend()进入等待状态(waiting)。,2)任务状态,中断服务态(isr): 正在运行的任务被中断(除非中断是关闭的)时就进入了中断服务态(isr)。,2)任务状态,3)系统任务,空闲任务(idle task) c/os-总要建立一个空闲任务,这个任务在没有其它任务进入就绪态时投入运行。这个空闲任务ostaskidle()永远设为最低优先级,即os_lowest_pri0。 空闲任务ostaskidle()什么也不做,只是在不停地给一个32位的名叫osidlectr的计数器加1,统计任务使用这个计数器以确定现行应用软件实际消耗的cpu时间。 空闲任务不可能被应用软件删除,3)系统任务,3)系统任务,统计任务ostaskstat() 任务ostaskstat()是负责统计运行时间的任务,如果用户将系统定义常数os_task_stat_en(见文件os_cfg.h)设为1,这个任务就会建立。一旦得到允许,统计任务每秒运行一次(os_core.c)以计算当前的cpu利用率。也即计算应用程序使用了多少cpu时间,用百分比表示,这个值放在一个有符号8位整数oscpusage中,精确度是1个百分点。,第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,2 任务堆栈,堆栈创建 堆栈增长方向 堆栈检验 堆栈的初始化,2 任务堆栈-创建,1)堆栈创建 堆栈是在存储器中按数据“后进先出(lifo)的原则组织的连续存储空间。为满足任务切换和响应中断时保存cpu寄存器中的内容及任务私有数据的需要,每个任务都应该配有自己的堆栈。 uc/os-ii中堆栈的数据类型为为os_stk(typedef unsigned int os_stk )。 用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)。,2 任务堆栈-创建,动态分配堆栈,静态分配堆栈 static os_stk mytaskstackstack_size; 或 os_stk mytaskstackstack_size;,2 任务堆栈-增长方向,2)堆栈增长方向 c/os-支持的堆栈既可以向上增长(低地址往高地址) 也可以向下增长。用户在调用ostaskcreate()或ostaskcreateext()的时候必须知道堆栈是怎样增长的,因为用户必须得把堆栈的栈顶传递给以上两个函数, 当堆栈向上增长时,将os_stk_growth置为0,需将堆栈的最低内存地址传递给任务创建函数。,2 任务堆栈-增长方向,当堆栈向下增长时,置os_stk_growth为1,需要将堆栈的最高内存地址传递给任务创建函数,,堆栈向下增长(os_stk_growth=1),ostaskcreate(task, pdata, ,对两个方向增长的堆栈都提供支持的代码,2 任务堆栈-增长方向,2 任务堆栈-检验,3)堆栈检验,ostaskstkchk() 有时候确定任务实际所需的堆栈空间大小是很有必要的。因为这样用户就可以避免为任务分配过多的堆栈空间,从而减少自己的应用程序代码所需的ram(内存)数量。 c/os-提供的ostaskstkchk()函数可以为用户提供这种有价值的信息。,stack checking,ostaskstkchk()顺着堆栈的栈底开始计算空闲的堆栈空间大小。任务所用的堆栈的空间大小等于ostaskcreateext()中定义的堆栈尺寸减去储存值为0的连续堆栈入口数目。,2 任务堆栈-检验,2 任务堆栈-检验,用户应该使自己的应用程序运行足够长的时间,并且经历最坏的堆栈使用情况,这样才能得到正确的数值。一旦ostaskstkchk()提供给用户最坏情况下堆栈的需求,用户就可以重新设置堆栈的最后容量了。为了适应系统以后的升级和扩展,用户应该多分配10100的堆栈空间。在堆栈检验中,用户所得到的只是一个大致的堆栈使用情况,并不能说明堆栈使用的全部实际情况。,2 任务堆栈-初始化,4)任务堆栈的初始化 当处理器启动一个任务时,处理器的各寄存器总是需要预置一些与待运行任务相关的初始数据,如指向任务代码的指针、指向任务堆栈的指针、程序状态字psw等,这些初始数据从何而来? 系统在创建一个新任务时,应该把启动该任务所需的初始数据(指向任务代码的指针、指向任务堆栈的指针、程序状态字psw等)事先存放到这个任务的堆栈中。 任务堆栈初始化函数ostaskstkinit()完成上述工作(其在ostaskcreate()创建任务时被调用)。,2 任务堆栈-初始化,#if os_version = 251 os_stk *ostaskstkinit (void (*task)(void *pd), void *pdata, os_stk *ptos, int16u opt) #else void *ostaskstkinit (void (*task)(void *pd), void *pdata, void *ptos, int16u opt) #endif unsigned int *stk ; opt = opt; /* opt is not used, prevent warning */ stk = (unsigned int *)ptos; /* load stack pointer */,ostaskstkinit (),2 任务堆栈-初始化,/* build a context for the new task */ *-stk = (unsigned int) task; /* pc */ *-stk = (unsigned int) task; /* lr */ *-stk = 0; /* r12 */ *-stk = 0; /* r11 */ *-stk = 0; /* r10 */ *-stk = 0; /* r9 */ *-stk = 0; /* r8 */ *-stk = 0; /* r7 */ *-stk = 0; /* r6 */,2 任务堆栈-初始化,*-stk = 0; /* r5 */ *-stk = 0; /* r4 */ *-stk = 0; /* r3 */ *-stk = 0; /* r2 */ *-stk = 0; /* r1 */ *-stk = (unsigned int) pdata; /* r0 */ *-stk = (svc32mode|0x0); /* cpsr irq, fiq disable*/ *-stk = (svc32mode|0x0); /* spsr irq, fiq disable */ return (void *)stk); ,第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,3 任务控制块,1)任务控制块结构 2)任务控制块链表 3)任务控制块初始化,1) 任务控制块结构,任务控制块(task control blocks, os_tcbs)是c/os-用来存储任务堆栈指针、当前状态、优先级及任务链表指针等一些与任务管理有关的属性的结构类型数据。 任务控制块是任务的身份证,每个任务都有一个属于自已的任务控制块,当任务的cpu使用权被剥夺时,任务的属性/环境被保存在任务控制块中,而当任务重新得到cpu使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。 os_tcbs全部驻留在ram中。 os_tcbs 在任务建立的时候被初始化.,任务控制块结构成员,ostcbstkptr:指向当前任务堆栈栈顶的指针。 ostcbextptr:指向用户定义的任务控制块扩展的指针。用户可以扩展任务控制块而不必修改c/os-的源代码,只在函数ostaskcreateext()中使用,使用时将os_task_creat_en设为1. ostcbstkbottom:指向任务堆栈栈底的指针。递减栈指针指向任务使用的栈空间的最低地址;递增型栈则指向栈空间的最高地址。ostaskstkchk()可用其检验栈空间的使用情况以确定任务实际需要的栈空间。在ostaskcreateext()函数中使用,即需将os_task_create_ext_en设为1。,任务控制块结构成员,ostcbstksize:堆栈尺寸。 栈中可容纳的指针元数目/入口地址,不是用字节表示的栈容量总数。例 设栈中可以保存1,000个入口地址,则: 若每个地址宽度为32位,实际栈容量是4,000字节。 若每个地址宽度为16位,总栈容量是2,000字节。 在osstakchk()中调用,须将os_task_creat_ext_en设为1。,任务控制块结构成员,ostcbopt :ostaskcreateext()中的选项,c/os-目前只支持3个选择项: os_task_otp_stk_chk- stk检查 os_task_opt_stk_clr-清零 os_task_opt_save_fp-浮点运算,任务控制块结构成员,ostcbid:存储任务的识别码。 ostcbnext和ostcbprev:任务控制块os_tcbs双向链接,将任务控制块链接起来。该链表在时钟节拍函数ostimetick()中使用,用于刷新各个任务的任务延迟变量ostcbdly,每个任务的任务控制块os_tcb在任务建立的时候被链接到链表中,在任务删除的时候从链表中被删除。双向连接的链表使得任一成员都能被快速插入或删除,任务控制块结构成员,ostcbeventptr :指向事件控制块的指针。 ostcbmsg:指向传给任务的消息的指针。 ostcbdly:任务延时的时钟节拍数。当需要把任务延时若干时钟节拍时,或者需要把任务挂起一段时间以等待某事件的发生时需要用到这个变量。如果这个变量为0,表示任务不延时,或者表示等待事件发生的时间没有限制 .,任务控制块结构成员,ostcbstat:任务状态字,可取下列值: os_stat_rdy: 处于就绪状态 os_stat_sem: 处于等待信号量状态 os_stat_mbox:处于等待邮箱状态 os_stat_q: 处于等待消息队列状态 os_stat_suspend:处于被挂起状态 os_stat_mutex:处于等待互斥信号量状态,任务控制块结构成员,ostcbprio:任务优先级。高优先级任务的ostcbprio值小,低优先级任务的 ostcbprio值大 ostcbx、ostcby、ostcbbitx与ostcbbity: 与优先级有关的量,用于加速任务进入就绪态的过程或进入等待事件发生状态的过程。这些值是在任务建立时算好的,或者是在改变任务优先级时算出的 。,任务控制块结构成员,任务控制块结构成员,ostcbdelreq:一个布尔量,用于表示该任务是否需要删除。,2)任务控制块链表,任务控制块空闲链表:用于管理空闲任务的控制块的链表。 系统初始化时,初始化函数osinit()将创建一个任务控制块空闲缓冲池,其中有一定数量的空任务控制块,并将其链接成一个单向链表,即空闲链表,并用ostcbfreelist 指向表头。 当建立一个任务时,即将空闲链表表头指针ostcbfreelist指向的空任务控制块赋给该任务,然后将ostcbfreelist指向链表中的下一个空任务控制块,2)任务控制块链表,任务控制块空闲链表(list of free os_tcbs),2)任务控制块链表,任务控制块使用链表(双向),使用链表用于管理已建立任务的控制块,3)任务控制块初始化,任务控制块初始化函数ostcbinit()做三件事: 1、从空任务控制块链表中获取一个任务控制块; 2、用任务的属性值对任务控制块各个成员进行赋值; 3、把这个任务控制块链入到任务控制块使用链表的头部。,3)任务控制块初始化-ostcbinit(),/从空闲的os_tcb缓冲池中获得一个os_tcb,/如果os_tcb池中有空闲的os_tcb,它就被初始化了,/一旦os_tcb被分配,该任务的创建者就已经完全拥有它了,不担心被同时建立的另一个任务夺取,故可以重新开中断,并继续初始化os_tcb的数据单元。,3)任务控制块初始化-ostcbinit(),3)任务控制块初始化-ostcbinit(),3)任务控制块初始化-ostcbinit(),3)任务控制块初始化-ostcbinit(),/将os_tcb插入到已建立任务的os_tcb的双向链表中,该双向链表开始于ostcblist,而一个新任务的os_tcb常常被插入到链表的表头,3)任务控制块初始化-ostcbinit(),ostcblist = ptcb,/使任务进入就绪态,/返回一个代码表明os_tcb已经被分配和初始化了,3)任务控制块初始化-ostcbinit(),第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,4 任务就绪表,1)任务就绪表结构 2)任务就绪表操作 使任务进入就绪态 使任务脱离就绪态 找出进入就绪态的优先级最高的任务,1)任务就绪表结构,就绪表是保存任务就绪标志的表,表中的每一位对应一个任务,某任务处于就绪态时,表中相应位置1.就绪表有两个变量:osrdygrp和osrdytbl,osrdygrp,2) 任务就绪态表操作,osrdygrp|= osmaptblprio 3; osrdytblprio3|=osmaptblprio,使 任务进入就绪态,2) 任务就绪态表操作,例 1 使优先级为12的任务进入就绪状态,12=1100b, osrdygrp|= osmaptblprio 3 |= osmaptbl1b |= 00000010 osrdytblprio 3|= osmaptblprio & 0x07 |= osmaptbl100b |= osmaptbl4 |= 00010000 即osrdygrp的第1位置1,osrdytbl1的第4位置1,2) 任务就绪态表操作,例2 使优先级为21的任务进入就绪态,21=10 101b, osrdygrp|= osmaptblprio 3 |= osmaptbl10b= osmaptbl2 |= 00000100 osrdytblprio 3|= osmaptblprio & 0x07 |= osmaptbl101b |= osmaptbl5 |= 00100000 即osrdygrp的第2位置1,osrdytbl2的第5位置1,2) 任务就绪态表操作,使任务脱离就绪态 将就绪任务表数组osrdytblprio3中相应元素的相应位清零,且当osrdytblprio3中的所有位都为零时,即全组任务中没有一个进入就绪态时,osrdygrp的相应位才为零。 例 使优先级为12的任务脱离就绪表 if(osrdytbl1,if(osrdytblprio3,osrdytblprio3|=osmaptblprio&0x07,osrdygrp|= osmaptblprio 3,2) 任务就绪态表操作,y=1,x=4,prio=12,y=2,x=4,prio=20,例,int8u const osunmaptbl = 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x00 to 0x0f 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x10 to 0x1f 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x20 to 0x2f 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x30 to 0x3f 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x40 to 0x4f 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x50 to 0x5f 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x60 to 0x6f 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x70 to 0x7f 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x80 to 0x8f 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0x90 to 0x9f 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0xa0 to 0xaf 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0xb0 to 0xbf 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0xc0 to 0xcf 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0xd0 to 0xdf 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /0xe0 to 0xef 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /0xf0 to 0xff ;,优先级判定表,2) 任务就绪态表操作,例1 已知osrdygrp=01101000b, osrdytbl3=11100100b,找出进入就绪态的优先级最高的任务 osrdygrp=01101000b=0x68,查osunmaptbl0x68得到的值是3,y=3。 osrdytbl3=11100100b=0xe4,则osunmaptbl0xe4的值是2,x=2。 prio= (y 3) + x=3*8+2=26。 查任务控制块优先级表数组ostcbpriotbl26,即可得到指向该任务的任务控制块os_tcb的指针.,2) 任务就绪态表操作,例2 已知osrdygrp=00100100b, osrdytbl2=00010010b,找出进入就绪态的优先级最高的任务 y = osunmaptblosrdygrp= osunmaptbl100100b = osunmaptbl0x24=2 x = osunmaptblosrdytbly= osunmaptblosrdytbl2 =osunmaptbl00010010b =osunmaptbl0x12=1 prio = (y 3) + x =(23)+1=17,第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,5 任务调度,任务调度器 任务切换 给调度器上锁和开锁,1)任务调度器,任务调度(task scheduling) c/os-总是运行进入就绪态任务中优先级最高的任务; 调度器的工作是确定哪个任务优先级最高以及下面该哪个任务运行了; 任务级的调度由函数ossched()完成,中断级的调度由另一个函数osintext()完成的。,1)任务调度器(the task scheduler),2) 任务切换,任务级的任务切换需完成以下2步操作: 将被挂起任务的处理器寄存器推入堆栈 将较高优先级任务的寄存器值从堆栈中恢复到寄存器中 任务级的任务切换由os_task_sw()宏完成. #define os_task_sw() osctxsw(),任务切换os_task_sw()的代码,void osctxsw(void) 将r1,r2,r3及r4推入当前堆栈; ostcbcur-ostcbstkptr = sp;/sp入控制块 ostcbcur = ostcbhighrdy; sp = ostcbhighrdy -ostcbstkptr; 将r4,r3,r2及r1从新堆栈中弹出; ,保存当前,恢复即将,注:设处理器只有4个寄存器,调用os_task_sw()前的数据结构,保存当前cpu寄存器的值,(3),重新装入要运行的任务,低优先级任务 os_tcb,存贮器低地址,存贮器高地址,堆栈方向,重新装入要运行的任务,低优先级任务 os_tcb,存贮器低地址,存贮器高地址,堆栈方向,sp,r1,r2,r3,r4,pc,psw,存贮器低地址,存贮器高地址,高优先级任务 os_tcb,ostcbcur (1),(2),cpu,(4),ostcbhighrdy,osctxsw,osctxsw,osctxsw,3)给调度器上锁与开锁,上锁osschedlock()与开锁osschedunlock()函数用于禁止与允许任务调度。调用上锁函数的任务可一直保持对cpu的控制权(无论是否有优先级更高的任务进入了就绪态),直到调用开锁函数后,任务调度才得到允许。上锁和开锁函数必须成对使用 上锁函数不影响中断响应。 oslocknesting跟踪osschedlock()函数被调用的次数,c/os-允许嵌套深度达255层。当oslocknesting等于零时,调度重新得到允许,osschedunlock()调用ossched。,3)给调度器上锁与开锁,调用osschedlock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用。即用户程序不得调用osmboxpend()、osqpend()、ossempend()、ostasksuspend(os_pr1o_self)、ostimedly()或ostimedlyhmsm(),直到oslocknesting回零为止。因为调度器上了锁,用户就锁住了系统,任何其它任务都不能运 。,osschedlock (),osschedunlock (),第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,6 任务的创建,ostaskcreate()-建立任务函数(调用ostaskstkinit ()与 ostcbinit() ostaskcreateext()-建立任务扩展函数 创建任务的一般方法,1)ostaskcreate(),/检测分配给任务的优先级是否有效,task:指向任务代码的指针 pdata:传递给任务的参数的指针 ptos:指向任务堆栈栈顶指针 prio:任务优先权,/确保在规定的优先级上还没有建立任务。,/如果拟分配的优先级是空闲的,则放置一个非空指针来保留该优先级,/建立任务堆栈,返回新堆栈栈顶(psp),并保存在任务的0s_tcb中,/从空闲的os_tcb池中获得并初始化一个os_tcb,在0s_core.c文件中,1)ostaskcreate(),/如果函数是在某任务的执行中被调用,应调用调度函数以判断新建立的任务是否比原来的任务有更高的优先级,若是,内核作任务切换,1)ostaskcreate(),if (err = os_no_err) (7),/检验返回代码,如果成功,给ostaskctr加1,ostaskctr用于保存产生的任务数目,1)ostaskcreate(),3)创建任务的一般方法,3)创建任务的一般方法,第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,7 挂起和恢复任务求,挂起任务,ostasksuspend(int8u prio) 挂起自已; 参数prio=os_prio_self; 从就绪表中清除; ostcbstat |= os_stat_suspend 调用调度函数ossched()。 挂起其它任务 参数prio=待挂起任务的优先级 从就绪表中清除 ostcbstat |= os_stat_suspend,7 挂起和恢复任务求,被挂起的任务只能通过调用ostaskresume()函数来恢复。 若被挂起的任务同时也在等待(ostcbdly0),在对任务做取消挂起操作时,只能将其恢复为非挂起态,不能将其置为就绪态,要继续等待延时期满时,才能转入就绪状态。,ostasksuspend(),/检验用户是否通过指定 os_prio_self来挂起调用本函数的任务本身,/用户也可以通过指定优先级来挂起调用本函数的任务,/检验要挂起的任务是否存在,ostasksuspend(),ostasksuspend(),/就绪表中被移除,/在任务的os_tcb中设置os_stat_suspend标志以表明任务正在被挂起,/ostasksuspend()只有在被挂起的任务是调用本函数的任务本身的情况下才调用任务调度程序 。,7 挂起和恢复任务求,恢复任务,ostaskresume() 被挂起的任务只有通过调用ostaskresume()才能恢复。,/要恢复的任务必须是存在的,因为需要操作它的任务控制块os_tcb(2),ostaskresume().,ostaskresume().,/该任务必须是被挂起的(3),/通过清除ostcbstat域中的os_stat_suspend位取消挂起(4),/要使任务处于就绪状态,os_tcbdly域必须为0(5),ostaskresume().,第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,8 其它任务管理函数,1)删除任务 2)改变任务的优先级 3)获取任务的信息,1)删除任务,删除任务,ostaskdel() 删除任务,是将任务返回并处于休眠状态,并不是说任务的代码被删除了,只是任务的代码不再被c/os-调用。 调用ostaskdel()删除任务。 ostaskdel()不能删除空闲任务,也不能在isr中被调用; ostaskdel()首先判断优先级是否有效;从使用链表中删除控制块;从就绪表或等待事件表中清除;将控制块放回空闲链表。,/要删除的任务不能是空闲任务,因为删除空闲任务是不允许,ostaskdel (),/不能在isr例程中删除一个任务,因为这也是不被允许的,/调用此函数的任务可以通过指定os_prio_self参数来删除自已,ostaskdel (),/将时钟延迟数清零,以确保自己重新允许中断的时候,isr不会使该任务就绪,/置任务标志以阻止其它任务或isr让该任务重新开始执行。,/阻止任务调度程序在删除过程中切换到其它的任务中去;,ostaskdel (),/重新允许中断以减少中断的响应时间。这样,就能处理中断服务了,但由于它增加了oslocknesting,isr执行完后会返回到被中断任务,从而继续任务的删除工作,/重新关中断后,它通过锁定嵌套计数器减一以重新允许任务调度,用户可以在这里删除或释放自定义的tcb附加数据域,/ 将指向被删除的任务的os_tcb的指针指向null,就从优先级数组中将os_tcb去除。再接着将被删除的任务的os_tcb从os_tcb双向链表中移除,/被删除的任务位于表头,/被删除的任务位于表中间,ostaskdel (),os_tcb返回到空闲os_tcb表中,允许其它任务的建立,最后调用任务调度程序来查看在ostaskdel()重新允许中断的时候 (11),中断服务子程序是否曾使更高优先级的任务处于就绪状态(18)。,ostaskdel (),1) 删除任务,请求删除任务,ostaskdelreq() 有时候,任务会占用一些内存缓冲区或信号量一类的资源,这时假如另一个任务试图删除该任务,这些被占用的资源就会因为没被释放而丢失,导致存储器漏洞,这是任何嵌入式系统都无法接受的。在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己。可以通过ostaskdelreq()函数来完成该功能。,ostaskdelreq().,2) 改变任务的优先级,改变任务的优先级,ostaskchangeprio() 在用户建立任务的时候会分配给任务一个优先级。在程序运行期间,用户可以通过调用ostaskchangeprio()来改变任务的优先级。换句话说,就是c/os-允许用户动态的改变任务的优先级。 ostaskchangeprio()可以改变调用本函数的任务(当前任务)的优先级或其它任务的优先级.,/不能改变空闲任务的优先级,只能改变调用本函数的任务或者其它任务的优先级,ostaskchangeprio(),/检验新优先级是否是合法的,/如果新优先级是合法的,则保留这个优先级,ostaskchangeprio(),/检验当前任务是否想改变它的优先级。然后检查想要改变优先级的任务是否存在(6)。,/插入null指针将指向当前任务os_tcb的指针从优先级数组中移除(7),/检验想要改变优先级的任务是否就绪 (8),/如果该任务处于就绪状态,必须在当前的优先级下从就绪表中移除 (9),,/将任务插入就绪表,ostaskchangeprio(),/如任务在等待某一事件的发生,必须将任务从事件控制块(在旧的优先级下)中移除。并在新的优先级下将事件插入到等待队列中 (12),ostaskchangeprio(),/将指向任务os_tcb的指针存到ostcbpriotbl中 (13)。新的优先级被保存在os_tcb中(14),重新计算的值也被保存在os_tcb中(15)。ostaskchangeprio()完成了关键性的步骤后,在新的优先级高于旧的优先级或新的优先级高于调用本函数的任务的优先级情况下,任务调度程序就会被调用(16)。,ostaskchangeprio(),ostaskchangeprio(),3)获取任务的信息,获得有关任务的信息,ostaskquery() 应用程序可以通过调用ostaskquery()函数来获得自身或其它任务的信息。该函数获得的只是指定任务的任务控制块os_tcb中内容的拷贝。 要调用该函数,应用程序必须为os_tcb分配存储空间。这个os_tcb的数据空间与c/os-分配给任务控制块os_tcb的数据空间完全不同。在调用了该函数后,这个os_tcb包含了指定任务的os_tcb的副本.不要改变ostcbnext与ostcbprev的指向. 本函数只用来了解任务正在干什么-本函数是一个有用的调试工具 .,3) 获取任务的信息,ostaskquery (),第2章 uc/os-ii中的任务,1,4,2,6,5,8,任务的基本概念,任务调度,任务的创建,3,任务就绪表,7,9,c/os-的初始化和任务的启动,任务控制块,任务堆栈,任务的挂起和恢复,其它任务管理函数,9 c/os-的初始化和任务的启动,c/os-初始化 osiint()初始化函数负责初始化c/os-所有的变量和数据结构(见os_core.c)。 osinit()先后做以下事情: 初始化全局变量 初始化就绪表 建空闲数据缓冲池(空任务控制块、空事件控制块、空消息队列控制块、空存储器管理控制块) 建立空闲任务ostaskidle()(优先级为s_lowest_prio) 建立统计任务ostaskstat()(如果统计任务允许位和任务建立扩展允许位都设为1,优先级为os_lowest_prio-1)。,初始化全局变量,0,初始化就绪表,0,0,0,空闲缓冲池,空任务控制块空闲缓冲池,空闲缓冲池,空事件、空消息队列与空存储器管理控制块空闲缓冲池,建空闲任务与统计任务,void main(void)/int argc, char *argv char id0 = 4; armtargetinit(); /* needed by uc/os */ osinit(); ostimeset(0); /* create the start task */ ostaskcreate(taskstart,(void *)0, ,void osinit (void) int16u i; ostime = 0l; /* clear the 32-bit system clock */ osintnesting = 0; /* clear the interrupt nesting counter */ oslocknesting = 0; /* clear the scheduling lock counter */ #if os_task_create_en | os_task_create_ext_en | os_task_del_en ostaskctr = 0; /* clear the number of tasks */ #endif osrunning = false; /* indicate that multitasking not started */ osidlectr = 0l; /* clear the 32-bit idle counter */ #if os_task_stat_en /* statistic task is not ready */ #endif,osctxswctr = 0; /* clear the context switch counter */ osrdygrp = 0; /* clear the ready list */ for (i = 0; i os_rdy_tbl_size; i+) osrdytbli = 0; ospriocur = 0; ospriohighrdy = 0; ostcbhighrdy = (os_tcb *)0; /* tcb initialization */ ostcbcur = (os_tcb *)0; ostcblist = (os_tcb *)0; for (i = 0; i (os_lowest_prio + 1); i+) ostcbpriotbli = (os_tcb *)0; for (i = 0; i (os_max_tasks + os_n_sys_tasks - 1); i+) ostcbtbli.ostcbnext = ,ostcbtblos_max_tasks + os_n_sys_tasks - 1.ostcbnext = (os_tcb *)0; /* last os_tcb */ ostcbfreelist = /* initialize the message queue structures */ #endif,#if os_mem_en #endif,#else #if os_task_create_ext_en ostaskcreateext(ostaskidle, (void *)0, /* no arguments passed to ostaskidle() */ #endif #endif #if os_task_stat_en #if os_task_create_ext_en,#if os_stk_growth = 1 ostaskcreateext(ostaskstat, (void *)0, /* no args passed to ostaskstat() */ #else ostaskcreateext(ostaskstat, (voi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论