ucos任务创建后,什么时候开始运行?
举例验证
举一个例子:
main:
int main(void)
{
unsigned char os_err;
InterruptCount = 0; //for test
MailSendCount = 0; //for test
MailRecCount = 0; //for test
SendCount = 0; //for test
CPU_IntDis(); //关闭中断,在初始化进程结束后才打开中断
OSInit(); //初始化UCOS
os_err = OSTaskCreateExt((void (*)(void *)) tApp_MainTask, //创建主任务
(void *) 0,
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE -1] , //指定任务堆栈栈顶
(INT8U ) APP_TASK_START_PRIO, //指定任务优先级
(INT16U ) APP_TASK_START_PRIO, //指定任务标识号
(OS_STK *) &App_TaskStartStk[0], //指定任务堆栈栈底
(INT32U ) APP_TASK_START_STK_SIZE,//任务堆栈大小
(void *) 0, //指向附加数据域
(INT16U ) (OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK) //操作选项
);
#if OS_TASK_NAME_EN > 0
OSTaskNameSet(APP_TASK_START_PRIO, (INT8U *)"Start Task", &os_err);
#endif
OSStart(); //开始任务调度 ,该函数内部将会打开中断允许
return(0);
}
main->OS环境设置->任务创建->启动系统
OS环境设置:
void OSInit (void)
{
OSInitHookBegin(); /* Call port specific initialization code */
OS_InitMisc(); /* Initialize miscellaneous variables */
OS_InitRdyList(); /* Initialize the Ready List */
OS_InitTCBList(); /* Initialize the free list of OS_TCBs */
OS_InitEventList(); /* Initialize the free list of OS_EVENTs */
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
OS_FlagInit(); /* Initialize the event flag structures */
#endif
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
OS_MemInit(); /* Initialize the memory manager */
#endif
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
OS_QInit(); /* Initialize the message queue structures */
#endif
OS_InitTaskIdle(); /* Create the Idle Task */
#if OS_TASK_STAT_EN > 0u
OS_InitTaskStat(); /* Create the Statistic Task */
#endif
#if OS_TMR_EN > 0u
OSTmr_Init(); /* Initialize the Timer Manager */
#endif
OSInitHookEnd(); /* Call port specific init. code */
#if OS_DEBUG_EN > 0u
OSDebugInit();
#endif
}
OS_InitMisc用于初始化系统变量,如时钟、中断层数、调度锁、任务数、OS运行状态、空闲计数、上下文转换次数等等。
OS_InitRdyList用于初始换就绪队列
OS_InitTCBList用于初始化TCB空闲列表
OS_InitEventList用于初始化事件控制块
OS_FlagInit用于初始化事件标志控制块
OS_MemInit用于初始化内存管理
OS_QInit用于初始化消息队列
OS_InitTaskIdle用于创建一个空闲任务
OS_InitTaskStat用于创建一个统计任务
OSTmr_Init用于初始化定时器list
任务创建:
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)
{
OS_STK *psp;
INT8U err;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == OS_TRUE) {
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u) { /* Make sure we don't create the task from within an ISR */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_CREATE_ISR);
}
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */
/* ... the same thing until task is created. */
OS_EXIT_CRITICAL();
#if (OS_TASK_STAT_STK_CHK_EN > 0u)
OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */
#endif
psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */
err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
if (err == OS_ERR_NONE) {
if (OSRunning == OS_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_ERR_PRIO_EXIST);
}
做的工作包括:检查多任务OS开启、优先级范围、是否在ISR中创建任务、TCB检测、清除任务堆栈、初始化堆栈。
结论:
由: if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */
OS_Sched();
可知:
在ucos启动的时候,创建的任务并不立即进行调度,而是在OSStart中进行调度,而对于已经启动,在创建任务的时候,任务一创建完成就会立即调度,如下:
OSStart:
void OSStart (void)
{
if (OSRunning == OS_FALSE) {
OS_SchedNew(); /* Find highest priority's task priority number */
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy(); /* Execute target specific code to start task */
}
}