返回该小组首页 回复主题
liongt

liongt

小组等级:     E币:705  (E币换礼)

#1楼主:uC/OS-II 消息邮箱的疑问!

文章发表于:2008-07-14 08:48

    我在启动任务里创建了两个任务A和B,并在启动任务里以广播的方式发送消息邮箱,运行结果如图,怎么一开始只有A任务收到了消息呢?后面A和B才能都收到,问题出在哪呢?

void  TaskStart(void *p_arg)
{
 char* s;
 p_arg = p_arg; //去除编译器警告
 

#if 0
    BSP_Init();
#endif

#if OS_TASK_STAT_EN > 0
    OSStatInit(); //CPU使用率统计初始化
#endif

    //建立其他任务
 OSTaskCreate(
     TaskNodeA, 
     (void *)0, 
     (OS_STK *)&TaskNodeAStk[TASK_STK_SIZE-1],
     TASK_NODEA_PRIO
    );

 OSTaskCreate(
     TaskNodeB, 
     (void *)0, 
     (OS_STK *)&TaskNodeBStk[TASK_STK_SIZE-1],
     TASK_NODEB_PRIO
    );

    while (TRUE) //任务主体,无限循环
 {
  s="Hello!";
  OSMboxPostOpt(Str_Box,s,OS_POST_OPT_BROADCAST);
  OSTimeDlyHMSM(0,0,2,0);
    }
}

void  TaskNodeA(void *p_arg)
{
 INT8U err;
 char* s;
 char* s1="NodeA";

 p_arg = p_arg; //去除编译器警告

 while (1)
 {
  s=OSMboxPend(Str_Box,0,&err); //请求邮箱
  OS_Printf(s1);
  OS_Printf(s);
  OS_Printf("\n");
  OSTimeDlyHMSM(0,0,1,0);
 }
}

void  TaskNodeB(void *p_arg)
{
 INT8U err;
 char* s;
 char* s2="NodeB";

 p_arg = p_arg; //去除编译器警告

 while (1)
 {
  s=OSMboxPend(Str_Box,0,&err); //请求邮箱
  OS_Printf(s2);
  OS_Printf(s);
  OS_Printf("\n");
  OSTimeDlyHMSM(0,0,1,0);
 }
}

 

liongt

   小组等级:    E币:705  (E币换礼)

#2

文章发表于:2008-07-15 19:06

还是没解决!

tiloog

   小组等级:    E币:803  (E币换礼)

#3

文章发表于:2008-07-16 13:37

我估计是你的任务优先级存在问题。如果A任务的优先级比较高,当你的TaskStart任务创建创建完这个任务之后,A任务就得以运行,然后睡眠在油箱 上,TaskStart人物继续运行,创建B任务,但是B任务优先级较低,得不到CPU。当TaskStart发送broadcast之后,自己睡眠,然 后唤醒调度A任务,此时A就能接收到TaskStart发送msg,但是B接收不到。A任务处理完毕之后睡眠,此时CPU才能调度B任务,B任务睡眠在油 箱之上。此后,TaskStart再发送msg后,都能唤醒A、B任务,但是A的优先级高,所以先执行,B后执行,所以出现了AABAB的现象。
这是我分析的,我不知道你任务的优先级情况,但如果像我描述的那样,那么输出信息就正确了,如果将B任务的优先级调高,比TaskStart任务要高,那么我觉得你的问题就解决了。
不知道是不是这么回事,请大家分析~~

liongt

   小组等级:    E币:705  (E币换礼)

#4

文章发表于:2008-07-17 18:33

21ic 上一个高手的回复,学习了!

主要原因是因为第1次邮箱为空造成.整个过程分析如下

Step1.启动任务调用POST后,由于没有任务等待该邮箱,直接将消息放入返回,延时(2s).
Step2.高优先级的任务A运行.这时任务A可以直接PEND到邮箱的内容,显示完成后,延时(1s).
Step3.B任务获得运行权,由于邮箱未空,在PEND函数处挂起.
Step4.一直运行空闲任务,1秒到之后,A任务也在PEND函数处挂起.
Step5.一直运行空闲任务,2秒到后,启动任务再次运行,这时候使用广播的方式把任务A,B都激活.
Step6.A任务和B任务连续运行.显示字符,之后就是重复.

tiloog

   小组等级:    E币:803  (E币换礼)

#5

文章发表于:2008-07-17 19:24

上述分析基本和我前面的分析一致,但是我认为这个分析存在一个问题:
就是step2,任务A怎么会pend到邮箱内容的?你都是采用broadcast方式,broadcast方式时,如果等待队列中不存在任务,那么A如何获取消息?唯一的理由就是在消息发送前,A任务已经在邮箱上等待了。这就是我的分析和那个高人分析的不同之处,其它的都一样。

所以,我想问liongt一下,你的任务优先级关系具体是怎样的?你可以调整优先级关系,实验一下。

另外,我查了一下broadcast源码,如下:
if ((opt & OS_POST_OPT_BROADCAST) != 0x00) {  /* Do we need to post msg to ALL waiting tasks ? */
            while (pevent->OSEventGrp != 0x00) {      /* Yes, Post to ALL tasks waiting on mailbox     */          
                OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX);   
            }
        } else {
            OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX);    /* No,  Post to HPT waiting on mbox         */
        }

欢迎积极讨论。

liongt

   小组等级:    E币:705  (E币换礼)

#6

文章发表于:2008-07-23 15:37

优先级

#define  TASK_START_PRIO  1 //任务START的优先级
#define  TASK_NODEA_PRIO  5 //任务NODEA的优先级
#define  TASK_NODEB_PRIO  10 //任务NODEB的优先级

按照你说的调整优先级,开始的时候还是只有一个任务能收到消息。

tiloog

   小组等级:    E币:803  (E币换礼)

#7

文章发表于:2008-07-25 09:29

你把TASK_START_PRIO的优先级调为最低,TASK_NODEA_PRIO和TASK_NODEB_PRIO的优先级跳高,可以如下:

#define  TASK_START_PRIO  10

#define  TASK_NODEA_PRIO  1
#define  TASK_NODEB_PRIO  2

主要测试思想如下:当task_start任务创建task_a和task_b之后,立即让task_a和task_b运行起来,并且在邮箱上睡眠,等task_a,task_b都睡眠之后,task_start再发送广播消息。这样的话task_a和task_b都应该能够收到消息了。

你可以尝试一下。

 

liongt

   小组等级:    E币:705  (E币换礼)

#8

文章发表于:2008-07-25 20:52

我看这样就应该没问题了,回去试一下!多谢tilong兄!

总共 , 当前 /

快速回复主题--如果想加入编辑器功能,建议使用 [高级回复]

您目前还不是小组成员,请先加入

回复贴子区

用户名:    您没有注册?

密码:    忘记了密码?

内容:

  • DesignDesign
  • HTMLHTML

浏览该小组的用户还看过...

设计资源与分销