uCOS-II创建了四个任务可最终只执行了两个任务
如题,用开发板调式看到只有两个任务执行,大家帮忙看看程序有什么问题。#include <includes.h>
static OS_STKGstkStart; /*The stack of start task */
/*启动任务的堆栈 */
static OS_STKGstkLED1;
static OS_STKGstkLED2;
static OS_STKGstkLED3;
static OS_STKGstkLED4;
OS_EVENT *LEDCON;
/*********************************************************************************************************
FUNCTION PROTOTYPES 函数声明
*********************************************************************************************************/
static void taskStart (void*pdata); /*The start task启动任务 */
static void taskLed1 (void*pdata);
static void taskLed2 (void*pdata);
static void taskLed3 (void*pdata);
static void taskLed4 (void*pdata);
int main (void)
{
OSInit(); //Initialize the kernel of uC/OS-II
// LEDCON:结构体成员变量,返回为结构体数据
LEDCON = OSSemCreate(1); // 建立信号量LEDCON,
OSTaskCreate( taskStart, //Initialize the start task
(void *)0, // 任务参数指针
&GstkStart, // 任务栈顶指针
TASK_START_PRIO ); //
OSStart(); // Start uC/OS-II启动uC/OS-II,在这之前必须创建至少一个任务
return(0);
}
static void taskStart (void*pdata)
{
(void)pdata;
pdata = pdata; /* 避免编译器警告 */
targetInit(); /*Initialize the target's MCU */
#if OS_TASK_STAT_EN > 0
OSStatInit(); /*使能统计功能 */
#endif
OSTaskCreate(taskLed1, (void *)0, &GstkLED1, TASK_LED1_PRIO);/*建立LED的处理任务*/
OSTaskCreate(taskLed2, (void *)0, &GstkLED2, TASK_LED2_PRIO);
OSTaskCreate(taskLed3, (void *)0, &GstkLED3, TASK_LED3_PRIO);
OSTaskCreate(taskLed4, (void *)0, &GstkLED4, TASK_LED4_PRIO);
while (1) {
/*
*OSTaskSuspend(OS_PRIO_SELF);
*The start task can be pended here. 启动任务可在这里挂起
*/
OSTaskSuspend(OS_PRIO_SELF);
}
}
static void taskLed1(void*pdata)
{
(void)pdata;
INT8U err;
pdata = pdata;
for(;;)
{
OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
LED_Toggle(LED1); // 反转LED1
OSTimeDlyHMSM(0,0,0,500); // 延时500ms
LED_Toggle(LED1);
OSTimeDlyHMSM(0,0,0,500);
OSSemPost(LEDCON); // 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
}
}
static void taskLed2(void*pdata)
{
(void)pdata;
pdata = pdata;
INT8U err;
for(;;)
{
OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
LED_Toggle(LED2); //反转LED1
OSTimeDlyHMSM(0,0,0,500); // 延时500ms
LED_Toggle(LED2);
OSTimeDlyHMSM(0,0,0,500);
OSSemPost(LEDCON); // 释放信号量
}
}
static void taskLed3(void*pdata)
{
(void)pdata;
pdata = pdata;
INT8U err;
for(;;)
{
OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
LED_Toggle(LED3); //反转LED1
OSTimeDlyHMSM(0,0,0,500); // 延时500ms
OSSemPost(LEDCON); // 释放信号量
}
}
static void taskLed4(void*pdata)
{
(void)pdata;
pdata = pdata;
INT8U err;
for(;;)
{
OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
LED_Toggle(LED4); // 反转LED1
OSTimeDlyHMSM(0,0,0,500); // 延时500ms
OSSemPost(LEDCON); // 释放信号量
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/ 查os_cig.h 下的这两个设置
#define OS_MAX_TASKS 64 /* Max. number of tasks in your application, MUST be >= 2 */
#define OS_LOWEST_PRIO 64 /* Defines the lowest priority that can be assigned ... */ 这个和你的延时有关系的,任务1执行后就任务2,任务2执行后就任务1,任务2执行那个完毕后,发送信号量,当然是优先级高的执行,此时任务1 已经在等待了 我会依据你们的回答去查查看,谢了! #define OS_MAX_TASKS 8
#define OS_LOWEST_PRIO 8
这两个我都设位8的,要是真的是与延时有关,那该怎么处理呢?本人刚接触嵌入式不久,望多多指教。 两个任务都要访问全局变量,如何实现资源同步?
多任务运行后,任务A和任务B都请求对方发送信号量,如何解决:
任务A等待任务B发送信号量,但是任务B又在等待任务A发送信号量,如何解决谁也不会给对方发送信号量?
(1)、任务1
voidTaskA (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
(2)、任务2
voidTaskB (void *pdata)
{
等待信号量;
程序实体;
发送信号量;
}
标准答案:
在创建信号时,初始值必须为“1”。
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_610261RSUJDW.JPG
(原文件名:未命名.JPG) uC/OS-ii中:周期性执行任务的代码如下:
voidMyTask (void *pdata) //周期性执行的任务函数
{
进行准备工作的代码;
for (;;) //无限循环,也可用 while (1)
{
任务实体代码;
OSTimeDly( )
}
}
有四个周期性执行的任务,任务A(优先级=0)、任务B(优先级=1)、任务C(优先级=2)、任务D(优先级=3)
如果每个任务的延时节拍时间OSTimeDly( )设置的不合理,可能会导致永远也执行不到“任务D”
有没有设置“延时节拍时间OSTimeDly( )”的一般方法呢?
---------------------------------------------------------------------------------------------------------------------
只要确保在A进行延时的时间内,B能够执行所要执行的任务代码,并进入延时,这就能够保证C任务可以分配到时间。
一般情况下,在保证应用可靠的情况下,任务都尽可能少的占用处理器,能延时就尽量迟时,能延时多久,就延时多久,这样可以保证系统低优先级任务的运行顺畅。 http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_610262S9LHH5.JPG
(原文件名:11.JPG)
如上:两个任务通过信号量实现资源同步
第一个任务的OSTimeDly( )为OSTimeDly(1000)
第二个任务的OSTimeDly( )为OSTimeDly(2000) 楼主,可不可以把你看的资料(***程序设计基础)共享一下啊,谢谢啦 回复【8楼】Jigsaw
楼主,可不可以把你看的资料(***程序设计基础)共享一下啊,谢谢啦
-----------------------------------------------------------------------
到嵌入式论坛中寻找,我提供的有下载链接。 假设个例子,让任务1延时5秒,任务2延时4秒,任务3延时3秒,任务4延时2秒,那么在任务2完成后,任务1仍然处于挂起的时刻,那么任务3就可以执行了, mark 呵呵~~谢了!看来我得多看看书,接触不久相关的书还没得看呢。只是拿代码来调试。 现在我对OSTimeDlyHMSM这个延时函数还是不怎么懂,程序里建立了四个任务,每个任务的优先级都不同,按理说当程序里调用OSTimeDlyHMSM这个延时函数时,延时函数会去调用任务切换函数,这样会使优先级高的函数运行,可为什么四个函数还可以同时运行呢? 四个函数?是四个任务吧。
四个任务实际上并不是同时进行的,是分时运行的,每个任务轮流的占用CPU。
回复【2楼】dogbush
这个和你的延时有关系的,任务1执行后就任务2,任务2执行后就任务1,任务2执行那个完毕后,发送信号量,当然是优先级高的执行,此时任务1 已经在等待了
-----------------------------------------------------------------------
2楼说得有一定的道理,但不完全对。
由于楼主的代码里没有提到各个任务的具体优先级,所以这里就假设四个任务优先级分别从任务1到任务4是从高到低的。
首先任务1运行到OSSemPend(LEDCON,0,&err); 时由于信号量的计数值初始化为为1,所以继续执行,不进行任务的调度。当执行到第1个OSTimeDlyHMSM(0,0,0,500); 时,OS开始进行任务的调度。
此时任务2处于最高的优先级,因此任务2得到运行的机会,执行到OSSemPend(LEDCON,0,&err); 时,由于此时任务1还没有释放信号量,所以任务2继续等待信号量,再次进行任务调度。
任务3 得到运行的机会,同任务2一样,到OSSemPend(LEDCON,0,&err);时,由于任务1还没有释放信号量,所以任务3也继续等待。
任务4得到运行机会,同上,由于任务1 还没有释放,所以也得继续等待。
直到任务1的OSTimeDlyHMSM(0,0,0,500);延时期满,任务1继续执行。到第2个OSTimeDlyHMSM(0,0,0,500);时,再次进行任务的调度,但由于此时信号量还没有释放,所以过程和第1个OSTimeDlyHMSM(0,0,0,500);基本一样,直到延时期满。任务1执行OSSemPost(LEDCON),释放信号量,并开始任务的调度。
此时任务2处于最高优先级,并且处于等等信号量中,由于任务1已经释放了信号量,所以任务2继续执行,而且不进行任务调度,直到第1个OSTimeDlyHMSM(0,0,0,500);,此时开始任务的调度。
任务1此时处于最高的优先级中 ,所以第1个运行的任务是任务1,直到执行OSSemPend(LEDCON,0,&err); 时,由于任务2还没有释放信号量,所以任务1等待,并开始任务调度。
任务3得到机会,但任务2还没有释放,所以任务3继续等待,并开始任务调度。
任务4得到机会,同3一样,继续等待,并开始任务调度。
直到任务2的第1个OSTimeDlyHMSM(0,0,0,500)延时期满,任务2继续执行。直到第2个OSTimeDlyHMSM(0,0,0,500),并开始任务调度,但由于任务2没有释放信号量,而且所以其他任务都处于等待信号量中,所以直到延时期满,任务2继续执行。直到释放信号量。
任务2释放信号量时,开始任务调试。注意此时任务1是处于等待信号量中的,而且是最高优先级,所以任务1得到运行机会,而不是任务3和任务4。接下来的过程就是以上所述的循环,任务3和任务4永远得不到运行的机会,所以看起来建立了四个任务,实际上只有两个在运行。 问题就在你信号量的发送,你第一个任务执行完时才释放信号量,第二第三第四个任务都就绪了,但由于第二个任务优先级高自然接下来先执行第二个任务,可是由于第一个任务执行完才释放信号量那马上就又回到就绪状态,而你第二个任务也是执行完以后才释放信号量,由于第一个任务优先级最高,那第二个任务结束就会执行第一个任务,第二个任务执行完释放信号量又马上就绪,这样不断重复,那第三第四个任务就永远无法执行。所以你要想让这四个任务都执行就要处理好信号量在什么时候释放,不要等到任务最后才释放,这样就会出现只有两个任务可以执行了。 感谢楼上的分析! OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
LED_Toggle(LED1); // 反转LED1
OSTimeDlyHMSM(0,0,0,500); // 延时500ms
LED_Toggle(LED1);
OSTimeDlyHMSM(0,0,0,500);
OSSemPost(LEDCON); // 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
这种写法不太好吧,
一般情况下信号量应该是执行的时候Pend,然后执行完逻辑后就Post,然后释放cpu控制权。
OSSemPend(LEDCON,0,&err); // uC/OS-II检查信号量LEDCON的状态
//功能相关。。。。。。
OSSemPost(LEDCON); // 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
OSTimeDlyHMSM(0,0,0,500); 问题就在你信号量的发送,你第一个任务执行完时才释放信号量,第二第三第四个任务都就绪了,但由于第二个任务优先级高自然接下来先执行第二个任务,可是由于第一个任务执行完才释放信号量那马上就又回到就绪状态,而你第二个任务也是执行完以后才释放信号量,由于第一个任务优先级最高,那第二个任务结束就会执行第一个任务,第二个任务执行完释放信号量又马上就绪,这样不断重复,那第三第四个任务就永远无法执行。
要想是第三和第四个任务能够执行,可以建立四个信号量,传递顺序为1-2-3-4-1;
具体为:
int main (void)
{
OSInit(); //Initialize the kernel of uC/OS-II
// LEDCON:结构体成员变量,返回为结构体数据
//LEDCON = OSSemCreate(1); // 建立信号量LEDCON,
//添加部分:
task1_Sem = OSSemCreate(1);
task2_Sem = OSSemCreate(0);
task3_Sem = OSSemCreate(0);
task4_Sem = OSSemCreate(0);
然后在
static void taskLed1(void*pdata)
{
……
{
……
//OSSemPost(LEDCON); // 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
OSSemPost(task2_Sem);// 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
}
}
static void taskLed2(void*pdata)
{
……
{
……
//OSSemPost(LEDCON); // 释放信号量
OSSemPost(task3_Sem);// 释放信号量,同时一直在等待该信号量的taskLed3从挂起处开始执行
}
}
static void taskLed3(void*pdata)
{
……
{
……
//OSSemPost(LEDCON); // 释放信号量
OSSemPost(task4_Sem);// 释放信号量,同时一直在等待该信号量的taskLed4从挂起处开始执行
}
}
static void taskLed4(void*pdata)
{
……
{
……
//OSSemPost(LEDCON); // 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
OSSemPost(task1_Sem);// 释放信号量,同时一直在等待该信号量的taskLed2从挂起处开始执行
}
} ls的讨论精彩,学习了。 呵呵 先记下 回头看!!!! 请问楼主是在哪种单片机上移植uCOS的? mark! kevinzcp 发表于 2011-1-10 16:48
查os_cig.h 下的这两个设置
#define OS_MAX_TASKS 64 /* Max. number of tasks in your app ...
谢谢。我碰到的情况就是如此。自定义的优先级太低了,小于OS_LOWEST_PRIO,导致不能运行。 学习了,我对ucos不熟悉也遇到这个情况,解决方法:1:在while中加系统延时。2:在while中加等待信号事件。
页:
[1]