uc/OS-II操作系统:uc/OS中的任务_下(如不懂——>请收下我的膝盖)

注:本章接着上一章节书写

六、任务的挂起和恢复

1)挂起一个任务,就是暂停这个任务的调度。
(2)挂起任务的 TCB 还存在系统中,只是该任务的状态是 “挂起” ,对挂起态的任务uC/OS-II不再调度运行。
(3)挂起的任务恢复后即可参与uC/OS-II的任务调度。
(4)uC/OS-II中,可挂起除 “空闲任务”(OSTaskIdel( )) 外的任何任务。
(5)挂起/恢复使用系统函数OSTaskSuspend( ) / OSTaskResume( ) 实现。
1、挂起任务的函数原型
INT8U OSTaskSuspend( INT8U  prio );
本函数的参数、返回值及含义:
用优先级指定目标,挂起自身时使用OS_PRIO_SELF
OS_NO_ERR --- 完成指定任务的挂起。
OS_TASK_SUSPEND_IDEL --- 不能挂起空闲任务。
OS_PRIO_INVALID --- 无效的任务(优先级)指定。
OS_TASK_SUSPEND_PRIO ---指定的任务不存在。
2、恢复任务函数原型
INT8U OSTaskResume( INT8U  prio );
本函数的参数、返回值及含义:
用优先级指定目标。
OS_NO_ERR --- 完成指定任务的恢复。
OS_TASK_RESUME_PRIO --- 优先级指定的任务不存在。
OS_PRIO_INVALID --- 无效的任务(优先级)指定。
OS_TASK_NO_SUSPEND --- 指定的任务不是挂起态。

七、其他任务管理函数

1、修改任务优先级别函数原型
INT8U OSTaskChangePrio(INT8U  oldprio,	INT8U newprio );
函数说明:
在任务运行时,修改任务的优先级。
功能正确完成,函数返回 OS_NO_ERR。
OS_PRIO_INVALID ---- 指定的 prio 越界。
OS_PRIO_EXIST ---- newprio 已在用。
OS_PRIO_ERR ---- oldprio 不存在。
2、任务的删除函数原型
INT8U OSTaskDel( INT8U  prio );
函数说明:
使用 OS_PRIO_SELF 参数删除任务时是删除自身。
功能正确完成,函数返回 OS_NO_ERR。
删除一个任务实质上是删除该任务的TCB并归还到“空任务控制块链表” ,释放堆栈空间,并不删除任务代码。

(1)关于任务的删除
》“任务A” 在删除 “任务B” 时,A不能知道B的详细情况,可能会造成A已申请的资源从系统中永久的丢失 — 这不合理!
》正确的方法 — Task_A 欲删除 Task_B 时,A 提出删除申请,B根据自身的情况处理后,删除自身。
》uC/OS-II 中的 TCB 含有一个成员 OSTCBDelReq 用于标示有其他任务申请删除它。
》使用系统函数 OSTaskDelReq( ) 提出任务删除申请。
》ISR 中不允许删除任务。

3、系统函数原型
INT8U  OSTaskDelReq( INT8U  prio ) ;
优先级指定其他任务时的函数返回值说明:
OS_TASK_IDEL_PRIO --- 申请删除空闲任务出错。
OS_PRIO_INVALID --- 优先级指定出错。
OS_TASK_NOT_EXIST --- 优先级指定的任务已不存在。
OS_NO_ERR --- 删除申请成功。

特别说明:此函数的参数可以是 “优先级” 指定的其他任务,也可以是OS_PRIO_SELF 		指定自身,后者用于查阅是否有其他任务申请删除本任务。
代码如下:
举例:Task_A (prio = 10) 删除 Task_B (prio = 9) ,直到删除成功,Task_A才继续。


Void  Task_A ( void *pdata )		// Task_A prio = 10
{
    
        … …
    while ( OSTaskDelReq(9) != OS_TASK_NOT_EXIST )  // 申请删除Task_B
    {
    
        OS_TimeDly( 10 );    }				// 直到删除成功
     … … 
}

Void  Task_B ( void *pdata )		// Task_B prio = 9
{
    
        … …
     if ( OSTaskDelReq( OS_PRIO_SELF ) == OS_TASK_DEL_REQ )  // 有删除申请
     {
    
       … … 				// 释放私有资源
         OSTaskDel ( OS_PRIO_SELF );		// 删除自身
     }
     else
     {
    
    
          … … ;       // 任务B的其他代码
     }
}

八、uc/OS-II的初始化和任务的启动

1、uc/OS-II的初始化
在使用uC/OS-II之前,必须对其运行环境初始化:
void  OSInit( viod ) ;
用法举例:
void main (void)
{
    
    
    ......
    OSInit();	 /* Initialize uC/OS-II */
    ......		 /* Craete Task */
    OSStart();	 /* Start Multitasking */
}
OSInit( ) 的主要工作:
(1)对 uC/OS-II 的所有全局变量和数据结构初始化。
(2)创建空间任务( OSTaskIdel() )3)根据系统设置( OS_TASK_STAT_EN = 1 / 0 ) 启动统计任务。
2、uc/OS-II的启动
void  OSStart( viod ) ;
用法举例:
void main (void)
{
    
    
    ......
    OSInit();	 /* Initialize uC/OS-II */
    ......		 /* Craete Task */
    OSStart();	 /* Start Multitasking */
}
主函数 main( ) 调用了OSStart( ) 之后,uC/OS-II 才开始任务调度管理。

九、关于任务的总结

1)Task 由 TCB、Task_Stack、Task_Code 三部分组成。
(2)uC/OS-II使用 TCB 对任务进行控制。
(3)Task_Stack 用于任务切换时私有现场保护。
(4)uC/OS-II 按任务优先级对任务进行调度。
(5)uC/OS-II 每调用一次API函数和中断返回都会进行一次任务调度。
(6)任务调度的周期和任务调度器自身的运行事件无关。
(7)任务的优先级(prio)也是任务的句柄。
(8)uC/OS-II 的初始化和启动。

猜你喜欢

转载自blog.csdn.net/Mr_zhang1911116/article/details/123736537