tan_zhichao 发表于 2008-4-14 09:06:42

如何从一个消息队列中取出两条消息

大家好,我现在有个关于ucos_ii的消息队列问题困扰我一周了,大家能给提点意见吗?
我有两个任务分别向主控任务分别发送两则消息,以消息队列形式发的,在主控任务方用一个消息队列来接收,我想问下我在主控任务里怎样把发来的两则消息(邮箱内容是含有两个元素的一维数组)取出来呢,若是一条我会取,两条消息就不知道怎么取了,记得ucos_ii中的消息队列可以存放多条消息,可等价于多个邮箱,实际存的是指针数组,但是在接收方我用
char a,b;
char *rxmsg;
rxmsg=(char *)OSQPend(QSem,0,&err);
a=*rxmsg;
b=*(rxmsg+1);
这样做只是取出来第一则消息的内容了
那第二则消息如何取呢
我用2重指针了,也没弄好
请大家指点下,谢谢了,真的太谢谢了
还有这有个群号59122411,希望大家加入一起讨论

ATmega32 发表于 2008-4-14 17:09:50

没明白什么意思。

消息发送的代码也贴出来。

sourceForge 发表于 2008-4-14 17:48:45

消息队列有上一個消息, 下一個消息的指針的, 看看消息队列的數據結構就明白.

tan_zhichao 发表于 2008-4-14 22:08:47

我的问题大概是这样的,在2.3任务里把两个数组通过消息队列发给任务一,任务一等待2,3任务来的消息,这时两则消息吧,那怎么在任务1中把传来的两个数组内容取出来呢,我现在的方式只能取出最先发来的消息中内容,麻烦各位了
static voidAppTask1(void *p_arg)
{

    char *rxmsg;
    char a,b;
    INT8U err;
    p_arg = p_arg;
    while (TRUE) {
rxmsg=(char *)OSQPend(QSem,0,&err);

      if (a=='2'){
       LCD_write_string(0,0,line1);
       }
       else
       {LCD_write_string(0,1,line2);
       }
        switch(a)
        {      
          
          case 2:
             LCD_write_string(0,0,line1);
       OSMboxPost(ad,(void *)&a);
          break;
          
          case 3:
          LCD_write_string(0,1,line1);
       
          break;
       
          default:
          break;
    }
               
        OSTimeDly(100);
               }

}









static voidAppTask2(void *p_arg)
{
    char CAP={'2','4'};
    INT8U err;
    p_arg = p_arg;

   while (TRUE){
         OSQPost(QSem,(void *)&CAP);
         OSTimeDly(3);       
    }
}



static voidAppTask3(void *p_arg)
{
    char AD={'3','5'};

    INT8U err;
    p_arg = p_arg;

   while (TRUE){
         OSQPost(QSem,(void *)&AD);
               OSTimeDly(3);       
      
    }
}

ATmega32 发表于 2008-4-15 07:54:31

static voidAppTask2(void *p_arg)
{   
    char CAP={'2','4'};
    INT8U err;
    p_arg = p_arg;

   while (TRUE){
         OSQPost(QSem,(void *)&CAP);   
         OSTimeDly(3);         
    }
}

个人认为楼主的程序:
1.char CAP到定义为全局变量或者静态变量
2.如果楼主要传递CAP整个数组,应该再定义一个静态指针,
static char CAP={'2','4'};
static char *p=CAP;
OSQIntPost(QSem,&p);

如果楼主要传递数组两个元素,
static char CAP={'2','4'};
OSQIntPost(QSem,&CAP);
OSQIntPost(QSem,&CAP);

kanprin 发表于 2008-4-15 08:29:19

将两个消息队列合并成一个消息队列,消息BUF定义成全局数据,用数组中的某个字节(根据需要增加字节数)来表示消息类型,如BUF = MSG1 | MSG2;消息响应函数里面根据自己定义的消息类型去处理相应的消息。(前提是消息响应函数不是需要同时处理两个消息的并集)。

tan_zhichao 发表于 2008-4-15 09:30:02

首先谢谢ATmega32 cortex-m3详细指点,
我现在传一个整个数组还是数组的内容都能实现,并且在等待消息队列方也能取出来,现在关键是我要传的是两个数组,并且是分别是两个任务通过消息队列传送的啊,
同时感谢kanprin 萧威,我c语言不是很好,我的两个数组只能是两个任务传的,但怎样能把两个任务中的消息队列和宾呢

kanprin 发表于 2008-4-15 09:59:04

简单的说

#define MSG1 0
#define MSG2 1

type MsgBuf={0};


void task_msg_proc(void *arg)
{
        type *msg;
        ……
        while(1)
        {
                msg = OSQpend();

                ……

                if(msg & (1 << MSG1))
                {
                msg1_proc;
                }

                if(msg & (1 << MSG2))
                {
                msg2_proc;
                }
        }
}

void task_msg1_post(void *arg)
{
        type *msg1 = MsgBuf;
        ……
        while(1)
        {
                do something ……

                msg1 |= (1 << MSG1);
                ……
                postQ msg1;
        }

}

void task_msg2_post(void *arg)
{
        type *msg2 = MsgBuf;
        ……
        while(1)
        {
                do something ……

                msg2 |= (1 << MSG2);
                ……
                postQ msg1;
        }
}

注意,考虑数据的可靠性,安全性,对全局数组MsgBuf[]的访问加入互斥机制。

tan_zhichao 发表于 2008-4-15 10:12:50

恩,有思路了 ,看来自己学的还是太浅了
我以前认为由于消息队列里存放的是指针数组,即指向多个消息的指针,所以我在msg = OSQpend()这接收方把msg定义为2重指针,但是
都没好用

我现在就试试你的方法
太谢谢你了
对了有个群号59122411,愿意的话一起来讨论吧

sourceForge 发表于 2008-4-15 10:30:58

消息队列数据结构, 自己消化一下吧.

ECB数据结构
typedef struct {
void *OSEventPtr; /*指向消息或消息队列的指针*/
INT8U OSEventTbl;//等待任务列表
INT16U OSEventCnt; /*计数器(当事件是信号量时)*/
INT8U OSEventType; /*事件类型:信号量、邮箱等*/
INT8U OSEventGrp; /*等待任务组*/
} OS_EVENT;

typedef struct os_q {
struct os_q *OSQPtr;//空闲队列控制块指针
void **OSQStart; //指向消息队列的起始地址
void **OSQEnd; //指向消息队列的结束地址
void **OSQIn; //指向消息队列中下一个插入消息的位置
void **OSQOut;//指向消息队列中下一个取出消息的位置
INT16U OSQSize; //消息队列中总的单元数
INT16U OSQEntries; //消息队列中当前的消息数量
} OS_EVENT;

tan_zhichao 发表于 2008-4-15 11:51:24

出来,出来了 !太兴奋了,谢谢楼上的指点,太猛了!!这个问题弄好久了
终于出来了!
非常感谢!!!

tan_zhichao 发表于 2008-4-15 15:43:46

还是有点问题,就是任务三能把数组内容3,5传过去,可是任务2没有把数组内容2,4传过去
我有个这样理解不知道对不?
对于消息队列等待函数每次返回来是一个指针,即一则消息的指针,任务切换后再轮到该等待消息队列的任务时是下一则消息的指针,也就是说等待对列的任务一次等待不能取出两条消息对吗?
页: [1]
查看完整版本: 如何从一个消息队列中取出两条消息