ucos任务创建与任务删除代码分析

任务创建

INT8U  OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
    OS_STK    *psp;
    INT8U      err;
    OS_ENTER_CRITICAL();       //关中断函数 ,即进入临界区 
    						   //只允许一个任务进入临界区 
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) /* Make sure task doesn't already exist at this priority  */  
    /*如果指的是0地址说明未初始化,此任务不存在。可以创建。*/ 
	{ 
 	/* 通过放置一个非空指针来保存优先级Reserve the priority to prevent others from doing the same thing until task is created. */
        OSTCBPrioTbl[prio] = (OS_TCB *)1;     //当他不存在让其存在 
		OS_EXIT_CRITICAL();   //开中断函数 ,即能重新允许中断 ,退出临界区 
 	    psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);//返回新的堆栈顶psp,并被保存在任务的OS_TCB中   
		/* Initialize初始化 the task's stack         */
		/* 一旦stkinit()函数完成了建立堆栈的任务,OSCREATE()就调用Binit()
		这也是任务创建的核心,从空闲的OS_TCB池中获得并初始化一个TCB 
		一旦OS_TCB被分配,该任务的创建者就已经完全拥有它 ,即使这时内核又创建了其他
		任务,这些新任务也不可能对已分配的OS_TCB做任何操作,所以OSTCBInit()
		在这时就可以允许中断,并继续初始化os_tcb的数据单元 */
           err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
        // 从OSTCBINIT()返回后,OSCREATE()检验返回代码,成功,则
		//增加OSTASKCTR, 
		   if (err == OS_NO_ERR) 
		   {
             OS_ENTER_CRITICAL();
             OSTaskCtr++; /* 用于保存产生的任务数目Increment the #tasks counter */
             OS_EXIT_CRITICAL();
             /*如果oscreat()函数是在某个任务的执行过程中被调用
			 则任务调度函数会被调用来判断是否新建立的任务比原来的任务有更高的优先级。如
			 果新任务的优先级更高,内核会进行一次从旧任务到新任务的任务切换。
			 如果在多任务调度开始之前(即用户还没有调用OSStart()),
			 新任务就已经建立了,则任务调度函数OS_Sched()不会被调用。*/
             if (OSRunning == TRUE)         //任务在系统运行时建立 
	       	 {/* Find highest priority task if multitasking has started */
                 OS_Sched();           //找到当前最高优先级任务,让其运行 
             }
   	       } 
   	       //返回失败,就置OSTCBPRIO[PRIO]的入口为0,以放弃该任务的优先级 
            else 
			{
             OS_ENTER_CRITICAL();
             OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
             OS_EXIT_CRITICAL();
 	        } 																																										yu																																																									
        return (err);
    	}     
	OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
}                                                                                           

OS_ENTER_CRITICAL(); //关中断函数 ,即进入临界区 只允许一个任务进入临界区
if (OSTCBPrioTbl[prio] == (OS_TCB )0) / Make sure task doesn’t already exist at this priority /
/如果指的是0地址说明未初始化,此任务不存在。可以创建。/
{
/
通过放置一个非空指针来保存优先级Reserve the priority to prevent others from doing the same thing until task is created. */
OSTCBPrioTbl[prio] = (OS_TCB *)1; //当他不存在让其存在
OS_EXIT_CRITICAL(); //开中断函数 ,即能重新允许中断 ,退出临界区

if (OSRunning == TRUE) //任务在系统运行时建立
{/* Find highest priority task if multitasking has started */
OS_Sched(); //找到当前最高优先级任务,让其运行
}

删除任务

INT8U  OSTaskDel (INT8U prio)
{   OS_EVENT     *pevent;
    OS_TCB       *ptcb;
    BOOLEAN       self;
    if (OSIntNesting > 0) 
   { /* See if trying to delete from ISR  */        
		return (OS_TASK_DEL_ISR);
    }
  OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) 
   { /* See if requesting to delete self    */
        prio = OSTCBCur->OSTCBPrio; 
	/* Set priority to delete to current   */
    }
	ptcb = OSTCBPrioTbl[prio];
    if (ptcb != (OS_TCB *)0)
    {  /* Task to delete must exist  */
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) 
	   {  /* Make task not ready*/
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
        pevent = ptcb->OSTCBEventPtr;
        if (pevent != (OS_EVENT *)0) 
        { /* If task is waiting on event         */
            if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
            { /* ... remove task from event ctrl block */
                 pevent->OSEventGrp &= ~ptcb->OSTCBBitY;                        
            }
        }
        ptcb->OSTCBDly  = 0; /* Prevent OSTimeTick() from updating  */
        ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed     */
        if (OSLockNesting < 255) 
	   {     
	   		 OSLockNesting++; 
        }
        OS_EXIT_CRITICAL(); 
         OS_Dummy(); /* ... Dummy ensures that INTs will be */   
		 			 //人为把临界区分为两部分,为了及时响应 
		 			 //函数原型为空函数,相当于nop延时
		 			 //如果没有这个函数,开中断后直接关中断可能会导致中断无效
        OS_ENTER_CRITICAL(); /* ... enabled HERE! */
        if (OSLockNesting > 0) 
	  	{        
		  OSLockNesting--;      
        }
        OSTaskDelHook(ptcb); /* Call user defined hook              */
        OSTaskCtr--;        /* One less task being managed         */
        OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry            */
		if (ptcb->OSTCBPrev == (OS_TCB *)0) 
	 	{/* Remove from TCB chain */
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList = ptcb->OSTCBNext;
        } else {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
        }
        ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list         */
        OSTCBFreeList   = ptcb;
        OS_EXIT_CRITICAL();
        OS_Sched(); /* Find new highest priority task */
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();
    return (OS_TASK_DEL_ERR);
}

OS_EXIT_CRITICAL();
OS_Dummy(); /* … Dummy ensures that INTs will be /
//人为把临界区分为两部分,为了及时响应
//函数原型为空函数,相当于nop延时
//如果没有这个函数,开中断后直接关中断可能会导致中断无效
OS_ENTER_CRITICAL(); /
… enabled HERE! */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是UCOSIII操作系统任务创建删除、挂起、恢复的实验代码注解: ```c #include "includes.h" // UCOSIII头文件 // 任务堆栈大小 #define TASK_STACK_SIZE 512u // 任务优先级 #define TASK1_PRIO 1u #define TASK2_PRIO 2u // 任务堆栈空间 static CPU_STK Task1Stk[TASK_STACK_SIZE]; static CPU_STK Task2Stk[TASK_STACK_SIZE]; // 任务控制块 static OS_TCB Task1TCB; static OS_TCB Task2TCB; // 任务函数 static void Task1(void *p_arg); static void Task2(void *p_arg); int main(void) { OS_ERR err; // 初始化UCOSIII OSInit(&err); // 创建任务1 OSTaskCreate(&Task1TCB, // 任务控制块 "Task 1", // 任务名 Task1, // 任务函数 DEF_NULL, // 传递给任务函数的参数 TASK1_PRIO, // 任务优先级 &Task1Stk[0], // 任务堆栈起始地址 TASK_STACK_SIZE / 10u, // 任务堆栈大小 TASK_STACK_SIZE, // 任务堆栈空间 0u, // 任务扩展选项 OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR, // 任务选项 &err); // 创建任务2 OSTaskCreate(&Task2TCB, "Task 2", Task2, DEF_NULL, TASK2_PRIO, &Task2Stk[0], TASK_STACK_SIZE / 10u, TASK_STACK_SIZE, 0u, OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR, &err); // 启动UCOSIII内核 OSStart(&err); return 0; } // 任务1 static void Task1(void *p_arg) { OS_ERR err; while (DEF_TRUE) { // 执行任务1的操作 // ... // 挂起任务2 OSTaskSuspend(&Task2TCB, &err); // 恢复任务2 OSTaskResume(&Task2TCB, &err); // 删除任务2 OSTaskDel(&Task2TCB, &err); } } // 任务2 static void Task2(void *p_arg) { OS_ERR err; while (DEF_TRUE) { // 执行任务2的操作 // ... // 挂起任务1 OSTaskSuspend(&Task1TCB, &err); // 恢复任务1 OSTaskResume(&Task1TCB, &err); // 删除任务1 OSTaskDel(&Task1TCB, &err); } } ``` 代码中定义了两个任务,分别是`Task1`和`Task2`,并且设置了它们的优先级。在`main`函数中,首先调用`OSInit`函数初始化UCOSIII,然后调用`OSTaskCreate`函数创建任务1和任务2,最后调用`OSStart`函数启动UCOSIII内核。 在任务1和任务2的函数中,先执行一些操作,然后调用`OSTaskSuspend`函数挂起另一个任务,再调用`OSTaskResume`函数恢复另一个任务,最后调用`OSTaskDel`函数删除另一个任务。这样可以测试任务的挂起、恢复和删除功能。 需要注意的是,UCOSIII的任务堆栈是从高地址往低地址增长的,因此在创建任务时需要设置任务堆栈大小和任务堆栈空间,以及任务堆栈的起始地址。此外,还可以设置任务选项,例如`OS_OPT_TASK_STK_CHK`表示检查任务堆栈是否溢出,`OS_OPT_TASK_STK_CLR`表示在任务创建时清空任务堆栈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值