第四章 作战指挥部 【前仆后继的废话】 作战指挥部建立两个应用任务,一个任务负责点灯,一个任务负责灭灯,你来我往,让人觉得好闪。 当然,当然阅读完本章,读者还是不知道怎样做到想闪就闪,想不闪就不闪,以及怎样才能闪到眼都花掉。 具体的处理还要查看后面章节才能知道,基于μC/OS-II之“点灯术”怎样实现。 · main.c#include <includes.h> extern OSTaskCreate_(void); extern DeviceInit(void); INT32S main (void) ① { DeviceInit(); //初始化器件,包括MCU、外设的相关初始化,由于与OS无关,本书省去它的说明 OSInit(); //初始化OS,这个函数将在【第六章】集中说明 OSTaskCreate _(); //建立OS任务,这个函数是OSTaskCreate(…) 或 OSTaskCreateExt(…)的替身② //“原函数”OSTaskCreate()这个函数将在【第七章】集中说明 OSStart(); //启动OS,这个函数将在【第九章】集中说明 return(0); } ------------------------------------------------------------------------------------------------------------------------------------------- ① “够力”提示:μC/OS-II的main()函数内,经典最小代码为: OSInit(); OSTaskCreate(…); 或 OSTaskCreateExt(…) OSStart(); ② 采用替身的目的是,为了让main.c文件“永恒不变”。 因为,如果直接调用OSTaskCreate、OSTaskCreateExt,还需要相应的多个函数参数,而这些参数是可能变化的。 如果将OSTaskCreate_()函数代码放到main.c外,再到那些文件里调用OSTaskCreate、OSTaskCreateExt, 那样,main.c就可以不作任何修改,一直拿来用则可以。可以看到,DeviceInit()函数代码也均在main.c外。 这样,main.c的代码就非常简洁,且移到其它工程,不需作任何修改,可直接使用。 ------------------------------------------------------------------------------------------------------------------------------------------- · AppCfg.h #define APP_TASK_STK_SIZE 64u #define TASK_A_STK_SIZE 64u #define TASK_B_STK_SIZE 64u #define APP_TASK_PRIO 4 #define TASK_A_PRIO 5 #define TASK_B_PRIO 6 static OS_STK AppTaskStk[APP_TASK_STK_SIZE]; static OS_STK TaskAStk[TASK_A_STK_SIZE]; static OS_STK TaskBStk[TASK_B_STK_SIZE]; · AppTask.Cvoid OSTaskCreate_ (void) { OSTaskCreate(AppTask, 0, &AppTaskStk[APP_TASK_STK_SIZE - 1], APP_TASK_PRIO ); } static void AppTask (void*p_arg) { AppTaskCreate();① //通过AppTask建立实现需要运行的任务 OSTaskDel(OS_PRIO_SELF); ② // 删除自身 } static void AppTaskCreate(void) { OSTaskCreate(taskA, (void *)0, &Task_AStk[TASK_A_STK_SIZE-1],TASK_A_PRIO); OSTaskCreate(taskB, (void *)0, &Task_BStk[TASK_B_STK_SIZE-1],TASK_B_PRIO); } static void TaskA(void*parg) { while(1) ③ { LED_On(1); LED_On(2); LED_On(3); LED_On(4); OSTimeDlyHMSM(0, 0, 0, 100); ④ } } static void TaskB(void *parg) { while(1) { LED_Off(1); LED_Off(2); LED_Off(3); LED_Off(4); OSTimeDlyHMSM(0, 0, 1, 0); } } ------------------------------------------------------------------------------------------------------------------------------------------- ① AppTaskCreate()函数见后面章节说明。 ② OSTaskDel()函数见后面章节说明。 这种方法最为常见,因为本任务仅仅需要运行一次,所以,最合理的方式就是将它删除。 当然,它也可以改为以下两种方法,从而进行任务切换: ·OSTimeDlyHMSM(0, 0, 2, 0); ·y = OSTCBCur->OSTCBY; OSRdyTbl[y]&= (OS_PRIO)~OSTCBCur->OSTCBBitX; if(OSRdyTbl[y] == 0u) OSRdyGrp&= (OS_PRIO)~OSTCBCur->OSTCBBitY; OS_Sched(); ③ 应用任务必须是一个超循环体,这是显然的。 ④ OSTimeDlyHMSM()函数见后面章节说明。 ------------------------------------------------------------------------------------------------------------------------------------------- |