ucosii中的任务

        ucosii的任务有两种:用户任务和系统任务。用户任务是为解决应用问题而编写的,系统任务是为应用程序来提供服务的。任务是程序的动态表现,在操作系统中体现为线程,是程序的一次执行过程。程序是静止的,存在于ROM、硬盘等外围设备中。任务是运动的,存在于内存中,有睡眠、就绪、运行、阻塞、挂起等多种状态。系统的程序多次执行是可以的,这样就形成了多个优先级不同的任务,每一个都是独立的。

       在实时系统中,把应用程序的设计过程分割为多个任务,每个任务都有自己的优先级,在操作系统的调度下协调运行。

       任务由三部分组成:任务程序代码、任务堆栈和任务控制块。其中,任务控制块用来保存任务的属性;任务堆栈用来保存任务工作环境;任务程序代码是任务的执行部分。任务控制块负责把任务代码和任务堆栈关联,而使任务控制块、任务代码和任务堆栈成为一个整体,并且系统要通过这个任务控制块来感知和管理一个任务。因此任务控制块就相当于一个任务的身份证,没有任务控制块的任务是不能被系统承认和管理的。

        ucosii用两条链表来管理任务控制块。一条是空任务控制块链表(其中所有的任务控制块都没有分配给任务);另一条是任务控制块链表(其中所有的任务控制块已经分配给任务)。空任务控制块链表是在应用程序调用OSInit()对ucosii系统进行初始化时建立的;而任务控制块链表是在调用函数OSTaskCreate()创建任务时建立的。任务管理的数据结构包括任务控制块、任务空闲链表和任务就绪表、任务优先级指针表、任务堆栈等,是ucosii的内核部分之一。任务控制块的数量等于操作系统能同时管理的最大任务数,由操作系统在启动的时候在内存中创建。任务控制块划分了两个链表:就绪链表和空闲链表。创建一个任务,就从空闲链表中取出一个空闲的任务控制块,将任务的各种属性添入该控制块,并将该任务控制块移到就绪表,更改就绪表和就绪组,任务就从睡眠态转换到就绪态,当没有更高优先级的任务在运行时,任务就可以得到运行。相反,要结束一个任务的运行,就要将该任务的任务控制块从就绪链表移到空闲链表,然后修改就绪表和就绪组,取消任务的就绪标志,任务就从就绪态转换到其他状态,而只有再回到就绪态才有可能得到运行。需要注意的是就绪表是双向链表,而空闲链表是单向链表。OSTCKFreeList永远指向空闲链表的表头,空闲链表从OSTCKTbl[0]开始分配。OSTCKList永远指向就绪表的表头,将分配的空闲任务控制块放在链表的表头。

        操作系统初始化函数OS_Init是操作系统在开始运行时,对全局变量、任务控制块、就绪表、事件及消息列队等重要数据结构进行的初始化操作,并创建空闲任务、统计任务等系统任务。该函数必须在创建用户对象及调用OSSTart()启动实时任务调度之前运行。

        ucosii有两种调度器:一种是任务级的调度器;另一种是中断级的调度器。任务级的调度器由函数OSSched()来实现,而中断级的调度器由函数OSIntExit()来实现。在每个时钟滴答进入时钟中断服务程序,如果有比目前运行的任务更高优先级的任务就绪,在需要的时候进行一次任务调度。这个任务调度函数并不是前面的OS_Sched,而是OSIntExit。在中断程序中进行实际的任务切换的地方是OSIntCtxSw(),OSIntExit与OSSched类似,进行全局变量的配置,决定是否进行任务切换。

        任务的切换就是断点数据的切换,断点数据的切换也就是CPU堆栈指针的切换,被中止运行任务的任务堆栈指针要保存到该任务控制块中,待运行的任务堆栈指针要由该任务控制块存到CPU的SP中。

        习惯上在调用函数OSStart()之前先创建一个任务,并赋予它最高的优先级别,从而使它成为起始任务;然后在这个起始任务中,再创建其他各任务。

        在删除让任务的时候,如果有其他任务把一个占用一些动态分配的内存或者信号源之类的资源的任务删除了,那么被删除任务所占用的一些资源就会因为没有释放而丢失,这是任何系统都无法接受的。因此,在删除一个占用资源的任务时,一定要谨慎。具体的办法是,提出删除任务请求的任务只负责提出删除任务的请求,而删除工作则由被删除任务自己来完成。这样,被删除任务就可以根据自身的情况来决定何时删除自身,同时也有机会在删除自身之前把占用的资源释放掉。

你可能感兴趣的:(ucosii)