(四) uc/os2的任务管理

 
建立任务(OSTaskCreate()/OSTaskCreateExt())
 
        嵌入式开发工程师写好一个任务的代码后,需要调用这个接口把任务纳入 UC/OS2来管理。上面的内核结构中说到,每个任务都有一个任务控制块,每个任务都有自己的任务堆栈空间,以及跟任务相关的就绪表等,故新建一个任务时主要动作分大两步, 1、调用OSTaskStkInit()初始化这个任务堆栈。其中OSTaskStkInit()的应该参照你使用CPU的用户手户用汇编代码来实现。2、取得一个任务控制块,使用内核OS_TCBInit()接口初始化这个任务控制块级并设置跟这个任务相关的一些数据结构如:任务就绪表等。OSTaskCreateExt()取完成OSTaskCreate()的功能外,会把整个堆栈空间初始化为0,作用见堆栈检验接口OSTaskStkChk();
 
任务堆栈检验(OSTaskStkChk())
 
       使用 OSTaskStkChk()可以返回一个记录所检查堆栈空间的使用情况,包括已使用空间及空闲空间的大小。但只有用OSTaskCreateExt()建立的任务的堆栈才正常使用OSTaskStkChk()。这个堆栈检验功能的原理很简单,因为OSTaskCreateExt()已经把任务堆栈每个字节初始为0了,所以只需要从栈底依次扫描每个字节并计数直到当一个字节的内容不为0,也即从这个字节起的空间已经至少被任务使用过了,得到的计数就是空闲空间的大小,使用空间的大小由栈的总大小减去空闲空间的大小就可以得到。
 
删除任务(OSTaskDel())
 
       跟建立任务相反,删除任务即是从 UC/OS2管理的任务中移掉该任务,不再使这个任务被调度。主要操作如下:从就绪表中移除,从相应事件控制块的等待表中移除,从事件标志组中等待表中删除,把这个任务控制块放入空闲控制块链表,最后重新调度任务。
 
请求删除任务(OSTaskDelReq())
 
        一个任务当前占用了一些资源如信号量,如果另一个任务调用 OSTaskDel()去删除这个任务,那么就会出现被占用的资源就会因没有释放而丢失,从而导致资源泄漏。所以任务必须在释放其所占用的所有资源后方可以释放。UC/OS2通过OSTaskDelReq()来实现,任务1通过OSTaskDelRe()删除任务2,在OSTaskDelReq()里会把任务2的任务控制块里一个被删除的标志置位,而任务2必须是会自己主动去检查这个标志,如是发现被置位了就主动释放所有自己占用的资源,然后调用OSTaskDel()把自己真实的删除。
 
改变任务的优先级(OSTaskChangePrio())
 
        uC/OS2支持动态改变任务的优先级, OSTaskChangePrio()的主要步聚如下:如果要改变优先级的任务当前就绪,则把任务从就绪表中旧优先级位置移出,移入就绪表中新的优先级位置。如果优务未就绪,则说明在等待某事件,则需要把相应事件控制块的结构中的任务表的相应优先级进行相应置位,以反映等待这个事件控制块的任务的优先级的改变。
 
挂起任务(OSTaskSuspend())
 
        通过 OSTaskSuspend()uC/OS2可以主动挂起一个任务。OSTaskSuspend()会把任务从任务就绪表中移出,另外在任务控制块的任务状态字段设置表示任务持起的相应标志位。最后重新启动系统调度。在这里你不需要担心当前任务本身处在等待某事件,当这个事件发现时会把这个挂起的任务重新加入就绪表,因为要把一个任务加入就绪表必须是任务控制块的任务状态字段置0时才可以。所以任务状态字段置了挂起位后就不可能会被加入就绪表。
 
恢复任务(OSTaskResume())
 
        通过 OSTaskSuspend()uC/OS2可以主动挂起的任务,只能由OSTaskResume()解挂。在这个接口里,只不是是反向设置一下任务状态字段的挂起标志,如果这个设置了以后,这个任务的状态就变成了就绪态后,就把这个任务加入就绪表,最后重新启动系统调度。这里需要注意的是并不是调用OSTaskResume()后任务就会就绪,任务可能还是等待别的某个事件。看一下任务状态字段每个标识的定义就会很明白。
 
获得任务信息(OSTaskQuery())
 
        这个接口很简单,只是得到一份待查询任务的任务控制块的拷贝。
 

你可能感兴趣的:(数据结构,汇编,OS,嵌入式,任务)