找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8864|回复: 0
打印 上一主题 下一主题
收起左侧

uC/OS-II学习笔记—任务的删除

[复制链接]
跳转到指定楼层
楼主
任务状态转换图如下所示:

一开始,任务在操作系统中是以函数代码的形式存在的,在操作系统启动的时候被加载到内存中,并未运行。并且,最开始的时候就绪表和就绪组是空的,或者说里面的内容都是0。很明显,这时候任务在内存中睡眠,处于睡眠态。 如果不调用任务创建函数对任务进行操作,该任务将永远处于睡眠态直到操作系统结束运行,被清除出内存。
任务的创建的学习中可以看到,任务创建的过程,首先分配一个空闲的TCB给任务,然后对该TCB的各个域进行赋值,对任务的堆栈进行初始化,其中,任务的代码的地址被压入堆栈。这为以后任务的运行做了充分的准备。就绪表和就绪组做了适当的处理,根据任务的优先级进行了设置。就绪TCB链表也插入了该TCB。
那么,若将任务删除,如上图所示,很明显是任务的逆过程,应该将就绪表、就绪组进行逆向的操作,就绪链表中的相关TCB应该被移除,转移到空闲TCB链表。和任务创建一,也要进行一些检查,看任务是否符合被删除的条件。
任务删除还涉及一个请求删除的问题,因此任务删除看似简单,实际上是比较复杂的一个过程。
任务删除函数的参数只有一个,这个参数就是任务的优先级。 我们知道,任务的优先级是uC/OS-II标志任务的唯一标志,任务控制块中虽然也有一个ID,但只是为了扩展使用。因此,任务删除函数也可以理解为删除指定优先级的任务。程序代码如下所示:


从任务删除的代码中可以看到,任务删除远远不像想象中那么简单。删除一个任务,就要照顾到该任务已经影响到的方方面面,否则系统就可能崩溃。由于任务删除的代码很长,而在执行的过程中一直在访问全局变量,因此使系统不能响应中断,破坏系统实时性。因此,在代码的中间,使用巧妙的手段开一次中断,过程如下:
(1)将任务调度锁加1。
(2)开中断
(3)执行一条空语句保证中断有时间执行。
(4)关中断
(5)将调度锁减1,恢复原来的值。
删除任务的代码尽管复杂,但无外乎先进行参数的检查,然后如果该任务在等待某些事件,就删除等待的标志,之后对TCB中的值进行修改,对就绪表、就绪组、任务优先级指针表、就绪任务链表、空闲任务链表等重要的数据结构进行与创建任务相反的操作,只不过中间因为代码执行时间过长,增加了临时允许中断的操作。

关于任务的删除,除了这个直接删除任务的函数之外,还有一个非常重要的请求删除任务的函数——OSTaskDelReq。
当以其他任务的优先级作为参数的时候,OSTaskDel粗暴地删除了任务,这在某些情况下是有效的,但是却不是必须这样做。通知对方任务,告诉它要删除你了,请任务自己删除自己是一种更好的做法。因为这么做,任务可以在删除自己之前先放弃自己使用的资源,如缓冲区、信号量、邮箱、队列等。如果总是用OSTaskDel删除一个任务,这个任务占用的资源不能得到释放,系统就会产生内存泄漏,在内存泄漏累积到较大的时候,系统就会最后因为没有可用的内存崩溃。
其实,OSTaskDelReq名称虽然是请求,却是集请求与响应于一段代码内,该代码的功能是请求删除某任务和查看自己是否有任务要删除自己。
例如,优先级为5的任务A调用OSTaskDelReq(10),请求删除优先级为10的任务B。任务B调用OSTaskDelReq(OS_PRIO_SEL)并查看返回值,如果返回值为OS_ERR_TASK_DEL_REQ,说明有任务要求删除自己了。任务B应该先释放自己使用的资源,然后调用OSTaskDel(10)或OSTaskDel(OS_PRIO_SEL)来删除自己。代码如下所示:

可见,请求删除任务的代码是比较少的,且前面一段是参数的检查。后半部分的代码根据参数不同,分别执行判断是否有请求参数标志和给对方任务打上请求删除标志。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表