上文我讲解了UCOSIII的任务管理相关内容,本篇文章讲解如何使用API函数来进行创建和删除任务的实验工程。
UCOSIII是多任务系统,那么肯定要能创建任务,创建任务就是将任务控制块、任务堆栈、任务代码等联系在一起,并且初始化任务控制块的相应字段。
在UCOSIII中我们通过函数OSTaskCreate()来创建任务OSTaskCreate()函数原型如下(在os_task.c中有定义)。调用OSTaskCreate()创建一个任务以后,刚创建的任务就会进入就绪态。
注意!不能在中断服务程序中调用 OSTaskCreate()函数来创建任务。
下面是OSTaskCreate()函数原型:
来解释一下各参数含义哦:
*p_tcb:指向任务的任务控制块 OS_TCB。
*p_name:指向任务的名字,我们可以给每个任务取一个名字
p_task:执行任务代码,也就是任务函数名字
*p_arg:传递给任务的参数
prio:任务优先级,在UCOSIII中数值越低优先级越高。
*p_stk_base:指向任务堆栈的基地址。
stk_limit: 任务堆栈的堆栈深度,用来检测和确保堆栈不溢出。
stk_size: 任务堆栈大小
q_size: UCOSIII 中每个任务都有一个可选的内部消息队列,我们要定义宏 OS_CFG_TASK_Q_EN>0,这是才会使用这个内部消息队列。
time_quanta:在使能时间片轮转调度时用来设置任务的时间片长度,默认值为时钟节拍除以 10。
*p_ext: 指向用户补充的存储区。
opt: 包含任务的特定选项。
*p_err: 用来保存调用该函数后返回的错误码。
下面来讲解OSTaskDel()函数:
OSTaskDel()函数用来删除任务,当一个任务不需要运行的话,我们就可以将其删除掉,删除任务不是说删除任务代码,而是 UCOSIII 不再管理这个任务,在有些应用中我们只需要某个任务只运行一次,运行完成后就将其删除掉,比如外设初始化任务,OSTaskDel()函数原型如下
*p_tcb: 指向要删除的任务 TCB,也可以传递一个 NULL 指针来删除调用 OSTaskDel()函 数的任务自身。
*p_err: 指向一个变量用来保存调用 OSTaskDel()函数后返回的错误码。
虽然 UCOSIII 允许用户在系统运行的时候来删除任务,但是应该尽量的避免这样的操作,如果多个任务使用同一个共享资源,这个时候任务 A 正在使用这个共享资源,如果删除了任务 A,这个资源并没有得到释放,那么其他任务就得不到这个共享资源的使用权,会出现各种奇 怪的结果。
我们调用 OSTaskDel()删除一个任务后,这个任务的任务堆栈、OS_TCB 所占用的内存并没 有释放掉,因此我们可以利用他们用于其他的任务,当然我们也可以使用内存管理的方法给任 务堆栈和 OS_TCB 分配内存,这样当我们删除掉某个任务后我们就可以使用内存释放函数将这 个任务的任务堆栈和 OS_TCB 所占用的内存空间释放掉。
OK 到这里我们就来实现一个具体工程:
先来说说工程具体时限要求:
设计 3 个任务,任务 1 用于创建其他任务,创建完成以后就删除掉自身,任务 2 和任 务 3 在 LCD 上有各自的运行区域,每隔 1s 他们都会切换一次各自运行区域的背景颜色,而且 显示各自的运行次数,任务 2 运行 5 次以后删除掉任务 3,两个任务运行的过程中还要通过串 口打印各自的运行次数,当任务 2 删除掉任务 3 以后也要通过串口打印提示信息。
话不多说,上代码:
可见,在代码最开始是任务基本属性的定义,其中任务优先级数值越大,其优先级越小。。。。。
下面,是任务1,2具体实现。。。。
OK。。。。。。
来总结一下
创建开始任务start_task,start_task任务用来创建另外两个任务:task1_task和task2_task开始任务start_task只是用来创建任务 task1_task 和 task2_task,那么这个任务肯定只需要执行一次,两个任务创建完成以后就可以删除掉 start_task 任务了,
这里我们使用 OSTaskDel() 函数删除掉任务自身,这里传递给 OSTaskDel()函数参数 p_tcb 的值为 0,表示删除掉任务自身。 根据要求我们在任务 1 执行 5 次后由任务 1 删除掉任务 2,这里通过调用 OSTaskDel() 函数删除掉任务 2,注意这时我们传递给OSTaskDel()中参数p_tcb的值为任务2的任务控制块Task2_TaskTCB的地址,因此这里我们用了取址符号“&”。调用函数OSTimeDlyHMSM()延时1s,调用 OSTimeDlyHMSM()函数以后就会发起一个任务切换。
这个小视频就是结果:任务1运行5次后,删除任务2,则在LCD上任务2的区域不再刷新颜色,任务1的区域仍然刷新颜色。。。。。
|