一般说来,任务可在OSStart()启动任务调度之前来创建,也可在任务中创建,但是UC/OS有个规定:在调用OSStart()启动任务调度之前,必须创建了至少一个任务。因此一般习惯上,在OSStart()启动任务调度之前先创建一个任务,并赋予它最高的优先级,从而使它成为起始任务,然后在这个起始任务中再创建其他任务。如果要使用统计任务,则统计任务的初始化函数也必须在这个起始任务中来调用。
注意:
UC/OS不允许在中断服务程序中创建任务。
下面是创建任务的示意性代码:
/******************主函数*****************/ void main(void) { ... ... OSInit(); //对ucos-ii进行初始化 ... ... OSTaskCreate(TaskStart,... ...); //创建起始任务 OSStart(); //开始多任务调度 } /*****************起始任务***************/ void TaskStart(void *pdata) { ... ... //在这个位置安装并启动ucos-ii的时钟 OSStatInit(); //初始化统计任务 ... ... //在这个位置创建其他任务 for(; ;) { /*起始任务TaskStart的代码*/ } }
创建任务函数
任务的创建实质上是创建一个任务控制块,并通过任务控制块把任务代码和任务堆栈关联起来形成一个完整的任务。UC/OS提供两个函数创建任务OSTaskCreate()和OSTaskCreateExt()。一般前者用的多,OSTaskCreate()如下所示:
1 INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio) 2 { 3 OS_STK *psp; 4 INT8U err; 5 #if OS_CRITICAL_METHOD == 3 6 OS_CPU_SR cpu_sr = 0; 7 #endif 8 #if OS_ARG_CHK_EN > 0 9 if (prio > OS_LOWEST_PRIO) { //检测任务的优先级是否合法 10 return (OS_PRIO_INVALID); 11 } 12 #endif 13 OS_ENTER_CRITICAL(); 14 if (OSIntNesting > 0) { /* Make sure we don‘t create the task from within an ISR */ 15 OS_EXIT_CRITICAL(); 16 return (OS_ERR_TASK_CREATE_ISR); 17 } 18 if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {//确认优先级未被使用 19 OSTCBPrioTbl[prio] = (OS_TCB *)1; //保留优先级 20 21 OS_EXIT_CRITICAL(); 22 psp = OSTaskStkInit(task, p_arg, ptos, 0);//初始化堆栈 23 err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);//初始化任务控制块 24 if (err == OS_NO_ERR) { 25 if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */ 26 OS_Sched();//任务调度 27 } 28 } else { 29 OS_ENTER_CRITICAL(); 30 OSTCBPrioTbl[prio] = (OS_TCB *)0;//放弃任务 31 OS_EXIT_CRITICAL(); 32 } 33 return (err); 34 } 35 OS_EXIT_CRITICAL(); 36 return (OS_PRIO_EXIST); 37 } 38 #endif
时间: 2024-10-10 13:12:17