声明:首先,我只用过UCOSII,因此对于UCOS III 不熟,但是大同小异,UCOS III的任务数没有局限而已,这是我的认为,下面就说一下你的程序吧,只是建议
- 从main()开始,建议创建任务时使用的函数OSTaskCreateExt(),而不使用,OSTaskCreate(),其好处,网上可以自己查。在任务创建后可以使用OSTaskNameSet(),目的是:指定任务的名称,用于调试。这个函数是可选的,但是建议加上,不要省掉这一步例如:
#define TASK_START_NAME "Start Task"
OSTaskNameSet(STARTUP_TASK_PRIO, TASK_START_NAME, &err)
- 在上一步之后要加上这句话OSTimeSet(0);节拍计数器清0,节拍计数器是0-4294967295,虽然节拍器不是那么容易就溢出,但是不能不考虑这种情况,尤其是在长时间使用的过程中,有可能就会溢出,这样就造成死机的现象。OSStart(&err) 我记得只要OSStart()就可以,当然这个无所谓。
- 那么就是主任务了,这个主任务,我觉得不是很满意,我记得我给你讲过,在主任务中去执行你的功能,因为主任务的优先级最高,这样做是非常传统的做法,也是很符合逻辑的做法,因此,我建议做出一下改动:
A. 如果main()中存在很多初始化的地方,有时会报错的,在此我不举例子,但是建议将部分初始化的函数放在,Task_Start()内,这一点可有可无,只是经验而已。
B. 将你创建的任务不要统统都放在主任务中,很不合理,你可以把这些任务打包,然后主任务调用,其次就是你没有必要在开个Task_Main任务,这不是多此一举吗,这一点很重要,我建议如下:
void Task_Start(void *p_arg)
{
OS_ERR err;
(void)p_arg;
//一些初始化的东西也可以放在这儿,随便
AppTaskCreate();//打包任务
While(1)
{
//这里面就是写的你的主要功能,标志位什么的
都在这里面写
//见你使用的是OSTimeDly,在此不建议在任务结尾出使用这个函数,但可以在中间使用,两者的差别可以到网上查,在你的系统做的非常大的时候,会出现很多问题,但在中间建议使用自己写的延时函数,因为这样不容易造成逻辑混乱,但有的地方必须使用,那就是需要任务中间切换才使用。当然OSTimeDly与II中的不太一样,这需要你自己考量了。
OSTimeDlyHMSM(0, 0, 0, 1000);
}
}
OS_EVENT *TaskMbox;//可以创建邮箱,实际上也可以
创建,看你想不想学
OS_EVENT *TaskUpdate; //时间刷新标志,创建信号量,
static void AppTaskCreate (void)
{
CPU_INT08U err;
TaskMbox = OSMboxCreate((void *)0);//你可以创建了放在这儿,也许可以用到,我觉得能用得到
TaskUpdate =OSSemCreate(1);
OSTaskCreateExt(任务一);
OSTaskNameSet();
OSTaskCreateExt(任务二);
OSTaskNameSet();
}
C. OSTaskChangePrio()我不知道你为什么使用这个函数,你的目的是什么,切换任务的优先级,那么我告诉你,这样做是很不好的,很容易就把逻辑搞混乱了,而且你的系统根本就不大,为什么要使用优先级切换,再说,你的优先级很明确,不存在并列的那种,OSTaskChangePrio函数的主要用途,以我的个人理解是,弥补UCOS系统解决任务间的时间片轮转的,因为UCOS是内核抢占,不存在时间片轮转,OSTaskChangePrio就是为了解决这一点才这样做的,但是对于III,我就不清楚了,但应该也是一样的把,因此建议把各个任务中的OSTaskChangePrio()变成OSTimeDlyHMSM(0, 0, 0, 1000),就可以了,当然,你没在这个函数中做优先级切换这个动作,那我觉得更没必要了。
D. 其次也是最重要的环节,就是任务的开辟问题,你怎么开这么多任务啊,没必要啊,我觉的你的任务可以开一下结果:
主任务(3)、key任务(4)、串口任务(建议不要)、服务器任务(这个目前还不清楚,传输的数据是什么,这个不好定),我觉得这样就够了,没必要,每个模块都开任务,很不合理,比如GSM发短信模块,就没必要单独拿出来
就拿key任务来说吧:
static void Task_Key(void *p_arg)
{
(void)p_arg;
While(1)
{
If(1== key_gsm)//发短信标志,当然也可以在这里直接发短信,如果延时很短的话,但建议不要这样做
GSM_Part=1;
OSTimeDly(100);//这里建议使用阻塞延时,转换为III的形式,自己转把
If(1== key_sound)//这个按键很特殊就是循环播报与否的开关,也可以使按键,如果是按键,就能向下面这样变成了,//可以这样写If(1== key_sound) { if(1== Sound_Part) Sound_Part=0; else Sound_Part=1;}
Sound_Part=1;
else Sound_Part=0;
OSTimeDly(100);
}
}
到此也就基本上结束了!!只是建议,我只看了个大概,所以目前只能这样了,明天晚上我会把程序写好,发过去你这个我感觉有很大的问题,暂时先不加服务器通信那一块,因为我还不清去那一块需要所消耗的时间和逻辑情况和数据情况,要不要开任务,这都要把驱动写好才能决定的。