任务管理——μC/OS-II

1 任务代码

  用户任务代码一般分为两种。

  • 开始任务:启用操作系统函数在main.c函数中调用,在此之前需要创建一个用户任务。规范起见,第一个创建的任务就是开始任务,在此任务中,完成对所有任务的创建。任务创建完成后,挂起开始任务。并且在开始任务的主体中,没有无限循环(只需要执行一次)。
//开始任务
void start_task(void *pdata)
{
	pdata=pdata;
	//此处为可以被中断的用户代码	
	OS_ENTER_CRITICAL();  				//进入临界段(关中断)	
	//此处为不可以被中断的用户代码
	//一般在此处创建其他任务	
	OSTaskSuspend(START_TASK_PRIO);		//挂起开始任务(一般来说,开始任务只执行一次)
	OS_EXIT_CRITICAL(); 				//退出临界段(开中断)
}

  • 其他任务:用户根据功能需要编写的任务。
//其他任务
void other_task(void *pdata)
{
	pdata=pdata;
	while(1)
	{
		//此处为可以被中断的用户代码
		OS_ENTER_CRITICAL();  				//进入临界段(关中断)		
		//此处为不可以被中断的用户代码		
		OS_EXIT_CRITICAL(); 				//退出临界段(开中断)
		//此处为可以被中断的用户代码
	}
}

2 任务堆栈

  • 创建任务堆栈。
#define START_STK_SIZE	128
OS_STK START_TASK_STK[START_STK_SIZE];
  • 任务堆栈的初始化:在OSTaskCreate()或OSTaskCreateExt()中调用了,用户无需自己初始化。
  • 堆栈生长方向:不同的处理器的堆栈生长方向不同,在调用OSTaskCreate()或OSTaskCreateExt()的时候,要根据堆栈的生长方向合适地传递参数。需要传递的是任务堆栈的栈顶地址。

3 任务控制块

  • 任务控制块结构。
typedef struct os_tcb {
    OS_STK          *OSTCBStkPtr;           /* Pointer to current top of stack                         */

#if OS_TASK_CREATE_EXT_EN > 0u
    void            *OSTCBExtPtr;           /* Pointer to user definable data for TCB extension        */
    OS_STK          *OSTCBStkBottom;        /* Pointer to bottom of stack                              */
    INT32U           OSTCBStkSize;          /* Size of task stack (in number of stack elements)        */
    INT16U           OSTCBOpt;              /* Task options as passed by OSTaskCreateExt()             */
    INT16U           OSTCBId;               /* Task ID (0..65535)                                      */
#endif

    struct os_tcb   *OSTCBNext;             /* Pointer to next     TCB in the TCB list                 */
    struct os_tcb   *OSTCBPrev;             /* Pointer to previous TCB in the TCB list                 */

#if (OS_EVENT_EN)
    OS_EVENT        *OSTCBEventPtr;         /* Pointer to          event control block                 */
#endif

#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)
    OS_EVENT       **OSTCBEventMultiPtr;    /* Pointer to multiple event control blocks                */
#endif

#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)
    void            *OSTCBMsg;              /* Message received from OSMboxPost() or OSQPost()         */
#endif

#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
#if OS_TASK_DEL_EN > 0u
    OS_FLAG_NODE    *OSTCBFlagNode;         /* Pointer to event flag node                              */
#endif
    OS_FLAGS         OSTCBFlagsRdy;         /* Event flags that made task ready to run                 */
#endif

    INT32U           OSTCBDly;              /* Nbr ticks to delay task or, timeout waiting for event   */
    INT8U            OSTCBStat;             /* Task      status                                        */
    INT8U            OSTCBStatPend;         /* Task PEND status                                        */
    INT8U            OSTCBPrio;             /* Task priority (0 == highest)                            */

    INT8U            OSTCBX;                /* Bit position in group  corresponding to task priority   */
    INT8U            OSTCBY;                /* Index into ready table corresponding to task priority   */
    OS_PRIO          OSTCBBitX;             /* Bit mask to access bit position in ready table          */
    OS_PRIO          OSTCBBitY;             /* Bit mask to access bit position in ready group          */

#if OS_TASK_DEL_EN > 0u
    INT8U            OSTCBDelReq;           /* Indicates whether a task needs to delete itself         */
#endif

#if OS_TASK_PROFILE_EN > 0u
    INT32U           OSTCBCtxSwCtr;         /* Number of time the task was switched in                 */
    INT32U           OSTCBCyclesTot;        /* Total number of clock cycles the task has been running  */
    INT32U           OSTCBCyclesStart;      /* Snapshot of cycle counter at start of task resumption   */
    OS_STK          *OSTCBStkBase;          /* Pointer to the beginning of the task stack              */
    INT32U           OSTCBStkUsed;          /* Number of bytes used from the stack                     */
#endif

#if OS_TASK_NAME_EN > 0u
    INT8U           *OSTCBTaskName;
#endif

#if OS_TASK_REG_TBL_SIZE > 0u
    INT32U           OSTCBRegTbl[OS_TASK_REG_TBL_SIZE];
#endif
} OS_TCB;

  • 任务控制块的创建和初始化:给用户任务分配任务控制块是系统的职责,无需用户创建任务控制块;在OSTaskCreate()或OSTaskCreateExt()中对任务控制块进行了初始化。

4 任务调度

μC/OS-II中,任务调度有以下两种:

  • 任务级的调度器:在调用某些系统函数的时候(如OSTimeDly(),OSTaskResume()等),调用OSSched()函数实现任务调度。
  • 中断级的调度器:在中断服务程序结束的时候(无中断嵌套),调用OSIntExt()函数实现任务调度。

5 任务管理相关API

  μC/OS-II中与任务管理相关的函数定义在os_task.c文件中,函数声明在ucos_ii.h文件中,以下列出函数声明以供查阅。

INT8U         OSTaskChangePrio        (INT8U            oldprio,
                                       INT8U            newprio);
                                      
INT8U         OSTaskCreate            (void           (*task)(void *p_arg),
                                       void            *p_arg,
                                       OS_STK          *ptos,
                                       INT8U            prio);
                                       
INT8U         OSTaskCreateExt         (void           (*task)(void *p_arg),
                                       void            *p_arg,
                                       OS_STK          *ptos,
                                       INT8U            prio,
                                       INT16U           id,
                                       OS_STK          *pbos,
                                       INT32U           stk_size,
                                       void            *pext,
                                       INT16U           opt);

INT8U         OSTaskDel               (INT8U            prio);
INT8U         OSTaskDelReq            (INT8U            prio);

INT8U         OSTaskNameGet           (INT8U            prio,
                                       INT8U          **pname,
                                       INT8U           *perr);

void          OSTaskNameSet           (INT8U            prio,
                                       INT8U           *pname,
                                       INT8U           *perr);

INT8U         OSTaskResume            (INT8U            prio);
INT8U         OSTaskSuspend           (INT8U            prio);

INT8U         OSTaskStkChk            (INT8U            prio,
                                       OS_STK_DATA     *p_stk_data);

INT8U         OSTaskQuery             (INT8U            prio,
                                       OS_TCB          *p_task_data);

INT32U        OSTaskRegGet            (INT8U            prio,
                                       INT8U            id,
                                       INT8U           *perr);

void          OSTaskRegSet            (INT8U            prio,
                                       INT8U            id,
                                       INT32U           value,
                                       INT8U           *perr);



你可能感兴趣的:(嵌入式学习)