⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_task.c

📁 avr ucos 代码 测试环境:source insight WINAVR 4个进程
💻 C
📖 第 1 页 / 共 4 页
字号:
            OS_EXIT_CRITICAL();//退出临界状态
        }
        return (err);//返回错误信息
    }
    OS_EXIT_CRITICAL();//如果优先级占用,退出临界状态
    return (OS_PRIO_EXIST);//返回优先级存在
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                     CREATE A TASK (Extended Version)
*
* Description: This function is used to have uC/OS-II manage the execution of a task.  Tasks can either
*              be created prior to the start of multitasking or by a running task.  A task cannot be
*              created by an ISR.  This function is similar to OSTaskCreate() except that it allows
*              additional information about a task to be specified.
*
* Arguments  : task     is a pointer to the task's code
*
*              pdata    is a pointer to an optional data area which can be used to pass parameters to
*                       the task when the task first executes.  Where the task is concerned it thinks
*                       it was invoked and passed the argument 'pdata' as follows:
*
*                           void Task (void *pdata)
*                           {
*                               for (;;) {
*                                   Task code;
*                               }
*                           }
*
*              ptos     is a pointer to the task's top of stack.  If the configuration constant
*                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
*                       memory to low memory).  'pstk' will thus point to the highest (valid) memory
*                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pstk' will point to the
*                       lowest memory location of the stack and the stack will grow with increasing
*                       memory locations.  'pstk' MUST point to a valid 'free' data item.
*
*              prio     is the task's priority.  A unique priority MUST be assigned to each task and the
*                       lower the number, the higher the priority.
*
*              id       is the task's ID (0..65535)
*
*              pbos     is a pointer to the task's bottom of stack.  If the configuration constant
*                       OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
*                       memory to low memory).  'pbos' will thus point to the LOWEST (valid) memory
*                       location of the stack.  If OS_STK_GROWTH is set to 0, 'pbos' will point to the
*                       HIGHEST memory location of the stack and the stack will grow with increasing
*                       memory locations.  'pbos' MUST point to a valid 'free' data item.
*
*              stk_size is the size of the stack in number of elements.  If OS_STK is set to INT8U,
*                       'stk_size' corresponds to the number of bytes available.  If OS_STK is set to
*                       INT16U, 'stk_size' contains the number of 16-bit entries available.  Finally, if
*                       OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
*                       available on the stack.
*
*              pext     is a pointer to a user supplied memory location which is used as a TCB extension.
*                       For example, this user memory can hold the contents of floating-point registers
*                       during a context switch, the time each task takes to execute, the number of times
*                       the task has been switched-in, etc.
*
*              opt      contains additional information (or options) about the behavior of the task.  The
*                       LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
*                       specific.  See OS_TASK_OPT_??? in uCOS-II.H.
*
* Returns    : OS_NO_ERR        if the function was successful.
*              OS_PRIO_EXIT     if the task priority already exist
*                               (each task MUST have a unique priority).
*              OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
*                               (i.e. > OS_LOWEST_PRIO)
*********************************************************************************************************
*/
/*
*****************************************************************************
                                                     建立一个任务的扩展版函数
描述:这个函数用于ucosII处理完成一个任务,它要么在多任务处理之前建立,
				 要么运行任务建立,它不够由中断服务程序建立。
                   它与OSTaskCreate()功能相似,但它允许一个特殊任务的更多信息。
参数:task: 指向任务代码的指针
      pdata:任务开始执行时,传递给任务参数的指针,用法见上。
      ptos:分配给任务堆栈的栈顶指针
      prio:分配给任务的优先级
      id:为任务创建一个特殊标志符,扩展版本有用。在这里设为和优先级一样即可。
      pbos:指向任务堆栈栈底指针,用于堆栈检验
      stk_size:用于指定堆栈容量。例:如果堆栈入口宽度为4B,那么stk_size为1000,
               说明堆栈有4000B
      pext:指向用户附加的数据域指针,用来扩展任务的任务控制块OS_TCB
      opt:设定OSTaskCreateExt的选项,指定是否允许堆栈检验,是否将堆栈清零,是否
           进行浮点数操作等。具体见uCOS_II中每一位定义。只要将相应位与opt相或即可
返回:OS_NO_ERR   :如果函数成功。
		  OS_PRIO_EXIT :如果优先级已经存在。
		  OS_PRIO_INVALID:如果定义优先级的数大于最大值



*****************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0 //能使包含创建代码
INT8U  OSTaskCreateExt (void   (*task)(void *pd),
                        void    *pdata,
                        OS_STK  *ptos,
                        INT8U    prio,
                        INT16U   id,
                        OS_STK  *pbos,
                        INT32U   stk_size,
                        void    *pext,
                        INT16U   opt)//具体含义见上
{
#if OS_CRITICAL_METHOD == 3                  /* Allocate storage for CPU status register               */
//为CPU状态寄存器分配存储空间
    OS_CPU_SR  cpu_sr;
#endif
    OS_STK    *psp;//任务堆栈参数指针
    INT8U      err;//错误参数


#if OS_ARG_CHK_EN > 0//允许检验什么东西,没有看懂
    if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
		//优先级超出范围
        return (OS_PRIO_INVALID);//返回优先级不可行
    }
#endif
    OS_ENTER_CRITICAL();//如果可行,进入临界状态
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
		//保证此优先级不存在
        OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
                                             /* ... the same thing until task is created.              */
											 //保留优先级,说明此优先级已经占用
        OS_EXIT_CRITICAL();//退出临界状态,这样可以使此函数在定义任务数据结构
                            //其它部分的时候,能够开中断

        if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   /* See if stack checking has been enabled     */
			//允许检验堆栈
            ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   /* See if stack needs to be cleared           */
            //任务建立时清除堆栈
            #if OS_STK_GROWTH == 1//堆栈从低到高增长
            (void)memset(pbos, 0, stk_size * sizeof(OS_STK));
			//memset是一个标准的ANSI函数,编译器商家会使之最优化
            #else//这个函数具体是什么不知道。
            (void)memset(ptos, 0, stk_size * sizeof(OS_STK));
            #endif
        }

        psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack          */
		//初始化任务堆栈
        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
		//任务控制块初始化
        if (err == OS_NO_ERR) {//如果成功则OS_TCBInit返回OS_NO_ERR
            OS_ENTER_CRITICAL();//进入临界状态
            OSTaskCtr++;                                       /* Increment the #tasks counter         */
			//创建任务数加一
            OS_EXIT_CRITICAL();//退出临界状态
            if (OSRunning == TRUE) {                           /* Find HPT if multitasking has started */
				//如果多任务运行的话,检查高优先级
                OS_Sched();//任务调度
            }
        } else {//如果任务控制块初始化失败
            OS_ENTER_CRITICAL();
            OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others  */
			//将这一优先级给其它任务
            OS_EXIT_CRITICAL();
        }
        return (err);//如果不允许检验堆栈
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);//如果此优先级存在,返回。
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                            DELETE A TASK
*
* Description: This function allows you to delete a task.  The calling task can delete itself by
*              its own priority number.  The deleted task is returned to the dormant state and can be
*              re-activated by creating the deleted task again.
*
* Arguments  : prio    is the priority of the task to delete.  Note that you can explicitely delete
*                      the current task without knowing its priority level by setting 'prio' to
*                      OS_PRIO_SELF.
*
* Returns    : OS_NO_ERR           if the call is successful
*              OS_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
*              OS_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
*                                  (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
*              OS_TASK_DEL_ERR     if the task you want to delete does not exist
*              OS_TASK_DEL_ISR     if you tried to delete a task from an ISR
*
* Notes      : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
*                    a) by making it not ready
*                    b) by removing it from any wait lists
*                    c) by preventing OSTimeTick() from making the task ready to run.
*                 The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
*              2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
*                 the next instruction following the enable interrupt instruction is ignored.  
*              3) An ISR cannot delete a task.
*              4) The lock nesting counter is incremented because, for a brief instant, if the current
*                 task is being deleted, the current task would not be able to be rescheduled because it
*                 is removed from the ready list.  Incrementing the nesting counter prevents another task
*                 from being schedule.  This means that an ISR would return to the current task which is
*                 being deleted.  The rest of the deletion would thus be able to be completed.
*********************************************************************************************************
*/
/*
*****************************************************************************************************
                                                                 删除一个任务
描述:此函数允许你删除一个任务,这个正在调用的任务能通过它自己的优先级数删除它自己,
                 被删除的任务返回睡眠状态,它能通过创建一个已删除任务再次激活。
参数:prio:被删除任务的优先级,当将prio设成OS_PRIO_SELF时,我们不知道它的优先级也
                   能够删除它
返回:OS_NO_ERR:删除成功
                 OS_TASK_DEL_IDLE:如果试图删除空闲任务
                 OS_PRIO_INVALID:如果指定优先级高过允许值
                 OS_TASK_DEL_ERR:如果想删除的任务不存在
                 OS_TASK_DEL_ISR:如果想从中断服务程序中删除任务
备注:1、为减少中断延时,OSTaskDel()通过三个手段不能使任务:
                   a、指定它没有就绪b、从等待列表中删除c、在OSTimeTick()中设置阻止任务准备运行。
                然后任务会被从ucos的复杂结构中解链
                    2、函数OS_Dummy() 在OS_EXIT_CRITICAL()调用之后调用是因为在多数处理器中,在能使中断
                       指令的下一条指令将被忽略。
                      3、一个中断服务程序不能删除一个任务
                     4、锁定嵌套数增加是因为作为一个即时启动,如果当前任务被删除,这个当前任务不能重新被
                       安排因为它已经从就绪列表中删除。增加嵌套数防止另一个任务被调度。这意味着中断服务程序
                    将返回被删除的当前任务,余下的删除工作将被中止。


*********************************************************************************************************
*/

/*$PAGE*/
#if OS_TASK_DEL_EN > 0//允许包含任务删除代码
INT8U  OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR     cpu_sr;//为CPU状态寄存器分配存储空间
#endif

#if OS_EVENT_EN > 0
	//能使队列代码产生&&申请队列控制块最大数不为零||能使邮箱代码产生||
	//能使信号量代码产生||能使互斥量代码产生 

    OS_EVENT     *pevent;//OS_EVENT:事件控制块
#endif    
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
//OS版本大于等于251,能使事件标志,事件标志最在值大于零
    OS_FLAG_NODE *pnode;//事件标志等待列表
#endif
    OS_TCB       *ptcb;//任务控制块
    BOOLEAN       self;//#define BOOLEAN  unsigned  char



    if (OSIntNesting > 0) {                                     /* See if trying to delete from ISR    */
		//看是不是要从ISR中删除
        return (OS_TASK_DEL_ISR);//返回
    }
#if OS_ARG_CHK_EN > 0//允许参数检测?
    if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
		//保证删除的不是空闲任务
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {       /* Task priority valid ?               */
		//如果被删除任务优先级违法
        return (OS_PRIO_INVALID);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -