搜索
bottom↓
回复: 11

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

[复制链接]

出0入0汤圆

发表于 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,希望大家加入一起讨论

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2008-4-14 17:09:50 | 显示全部楼层
没明白什么意思。

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

出0入0汤圆

发表于 2008-4-14 17:48:45 | 显示全部楼层
消息队列有上一個消息, 下一個消息的指針的, 看看消息队列的數據結構就明白.

出0入0汤圆

 楼主| 发表于 2008-4-14 22:08:47 | 显示全部楼层
我的问题大概是这样的,在2.3任务里把两个数组通过消息队列发给任务一,任务一等待2,3任务来的消息,这时两则消息吧,那怎么在任务1中把传来的两个数组内容取出来呢,我现在的方式只能取出最先发来的消息中内容,麻烦各位了
static void  AppTask1(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[0][0]);
          break;
          
          case 3:
          LCD_write_string(0,1,line1);
       
          break;
       
          default:
          break;
    }
               
        OSTimeDly(100);
               }

}









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

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



static void  AppTask3(void *p_arg)
{  
    char AD[2]={'3','5'};

    INT8U err;
    p_arg = p_arg;

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

出0入0汤圆

发表于 2008-4-15 07:54:31 | 显示全部楼层
static void  AppTask2(void *p_arg)
{   
    char CAP[2]={'2','4'};
    INT8U err;
    p_arg = p_arg;

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

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

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

出0入0汤圆

发表于 2008-4-15 08:29:19 | 显示全部楼层
将两个消息队列合并成一个消息队列,消息BUF定义成全局数据,用数组中的某个字节(根据需要增加字节数)来表示消息类型,如BUF[0] = MSG1 | MSG2;消息响应函数里面根据自己定义的消息类型去处理相应的消息。(前提是消息响应函数不是需要同时处理两个消息的并集)。

出0入0汤圆

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

出0入0汤圆

发表于 2008-4-15 09:59:04 | 显示全部楼层
简单的说

#define MSG1 0
#define MSG2 1

type MsgBuf[SIZE]={0};


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

                ……

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

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

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

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

}

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

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

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

出0入0汤圆

 楼主| 发表于 2008-4-15 10:12:50 | 显示全部楼层
恩,有思路了 ,看来自己学的还是太浅了
我以前认为由于消息队列里存放的是指针数组,即指向多个消息的指针,所以我在msg = OSQpend()这接收方把msg定义为2重指针,但是
都没好用

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

出0入0汤圆

发表于 2008-4-15 10:30:58 | 显示全部楼层
消息队列数据结构, 自己消化一下吧.

ECB数据结构
typedef struct {
void *OSEventPtr; /*指向消息或消息队列的指针*/
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];//等待任务列表
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;

出0入0汤圆

 楼主| 发表于 2008-4-15 11:51:24 | 显示全部楼层
出来,出来了 !太兴奋了,谢谢楼上的指点,太猛了!!这个问题弄好久了
终于出来了!
非常感谢!!!

出0入0汤圆

 楼主| 发表于 2008-4-15 15:43:46 | 显示全部楼层
还是有点问题,就是任务三能把数组内容3,5传过去,可是任务2没有把数组内容2,4传过去
我有个这样理解不知道对不?
对于消息队列等待函数每次返回来是一个指针,即一则消息的指针,任务切换后再轮到该等待消息队列的任务时是下一则消息的指针,也就是说等待对列的任务一次等待不能取出两条消息对吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 19:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表