pupist 发表于 2006-12-16 14:38:32

ucos 消息队列通信

我现在有三个任务

task 1   优先级4

task 2   优先级5



task uart 优先级8





task 1 2向 task uart的队列中发消息 要求串口输出   此时 运行一会会出错



如果把 task uart的优先级调到最高 就不会出现这个问题



有人知道怎么解决这个问题么

AuToCTRL 发表于 2006-12-16 19:07:18

使用的是Sem信号量作消息,还是Mbox作消息的载体?



应该没有问题的。具体你贴段相关程序看看

pupist 发表于 2006-12-19 14:27:02

uart pend一个队列 就会这样子 晚上贴上大家看看

pupist 发表于 2006-12-19 21:20:52

voidAppTask1(void *p_arg)

{

                t_Message *i;

                INT8U   err;

    p_arg = p_arg;

   

                FUNCTIONPASS(AppTask1);

    Mbox=OSMboxCreate((void*) 0);



    i=&MsgBUF;

    i->TX_ID = OS_TASK_1_PRIO;

    i->data= (INT8U *)&Val_ADC;



    while (1)

    {

            OSTimeDlyHMSM(0,0,0,200);   

            OSQPost(Q_ADC,(void*)i);

//                        printf("i.TX_ID= %d,请求ADC采样-\r
",i.TX_ID);

                        OSMboxPend(Mbox,0,&err);

                        if(OS_NO_ERR == err){

                                printf("1收到ADC结果\r
");

                                }

    }

}



voidAppTask2(void *p_arg)

{

                t_Message *i;

                INT8U   err;

    p_arg = p_arg;

   

                FUNCTIONPASS(AppTask2);

    Mbox=OSMboxCreate((void*) 0);



    i=&MsgBUF;

    i->TX_ID = OS_TASK_2_PRIO;

    i->data= (INT8U *)&Val_ADC;



    while (1)

    {

            OSTimeDlyHMSM(0,0,0,100);   

            OSQPost(Q_ADC,(void*)i);

//                        printf("i.TX_ID= %d,请求ADC采样-\r
",i.TX_ID);

                        OSMboxPend(Mbox,0,&err);

                        if(OS_NO_ERR == err){

                                printf("2收到ADC结果\r
");

                                }

    }

}



voidAppTaskADC(void *p_arg)

{

                INT8U *msg;

                INT8Uerr;

    p_arg = p_arg;



                FUNCTIONPASS(AppTaskADC);

                Q_ADC=OSQCreate((void*)0,5); /* ADC队列 缓存5个AD采样请求 */

    while (1)

    {

            msg=(INT8U *)OSQPend(Q_ADC, OS_TICKS_PER_SEC, &err);

            if (OS_NO_ERR == err)

            {

                    printf("收到%d的%d通道ADC采集请求msg=%d.\r
",((t_Message *)msg)->TX_ID,((t_Message *)msg)->data,msg);

//                OSTimeDlyHMSM(0,0,0,5);

                    OSMboxPost(Mbox[((t_Message *)msg)->TX_ID],(void *)1);

            }       

            if(OS_TIMEOUT == err)

            {

                                            printf("SYSTIME= %d,ADC等待超时!\r
",OSTimeGet());

            }

    }

}



#defineOS_TASK_1_PRIO                  7

#defineOS_TASK_2_PRIO                  8

//#defineOS_TASK_UART0_PRIO                3

#defineOS_TASK_UART1_PRIO                12

#defineOS_TASK_ADC_PRIO                  5
-----此内容被pupist于2006-12-19,21:21:41编辑过

pupist 发表于 2006-12-19 21:22:32

大家帮忙看看为什么 OS_TASK_ADC_PRIO改成13就不行了

pupist 发表于 2006-12-20 21:29:30

顶一下高手们出手看看吧

AuToCTRL 发表于 2006-12-21 20:10:22

我解释下,不对之处请指出:

OS_TASK_ADC_PRIO=5

OS_TASK_1_PRIO=7

OS_TASK_2_PRIO=8

1。TASK ADC先执行,在执行OSQPend(Q_ADC, OS_TICKS_PER_SEC, &err)后就挂起,等待Q_ADC队列,然后作下任务切换。

2。TASK 1优先级比较高,所以它先执行, 执行OSTimeDlyHMSM(0,0,0,200)后又作任务切换。

3。TASK 2开始执行,发送OSQPost(Q_ADC,(void*)i),后挂起等待 OSMboxPend(Mbox,0,&err)

4。TASK ADC接收到Q_ADC队列消息后,继续执行OSMboxPost(Mbox[((t_Message *)msg)->TX_ID],(void *)1)。然后又挂起等待Q_ADC队列消息。

5。TASK 2接收到OSMboxPend(Mbox,0,&err) 后,执行OSTimeDlyHMSM(0,0,0,100)

6。TASK 1执行,发送OSQPost(Q_ADC,(void*)i),后挂起等待 OSMboxPend(Mbox,0,&err)

7。然后重复步骤4、5、6、7。



如果改变优先级:

OS_TASK_1_PRIO=7

OS_TASK_2_PRIO=8

OS_TASK_ADC_PRIO=13

1。TASK 1最先执行,执行OSTimeDlyHMSM(0,0,0,200)后作任务切换。

2。TASK 2开始执行,执行OSTimeDlyHMSM(0,0,0,100)后作任务切换。

3。TASK ADC开始执行,在执行OSQPend(Q_ADC, OS_TICKS_PER_SEC, &err)后就挂起,等待Q_ADC队列,然后作下任务切换。

4。TASK 2开始执行,发送OSQPost(Q_ADC,(void*)i),后挂起等待 OSMboxPend(Mbox,0,&err)

5。TASK ADC接收到Q_ADC队列消息后,继续执行OSMboxPost(Mbox[((t_Message *)msg)->TX_ID],(void *)1)。然后又挂起等待Q_ADC队列消息。

6。TASK 2接收到OSMboxPend(Mbox,0,&err) 后,执行OSTimeDlyHMSM(0,0,0,100)

7。TASK 1执行,发送OSQPost(Q_ADC,(void*)i),后挂起等待 OSMboxPend(Mbox,0,&err)

8。然后重复步骤5、6、7、8。



所以改变优先级后应该多了1、2两个步骤,以后应该是和优先级没改前一样的。

pupist 发表于 2006-12-21 20:55:04

但是效果不同   我如果在ADC任务中延时一会

voidAppTaskADC(void *p_arg)

{

                INT8U *msg;

                INT8Uerr;

    p_arg = p_arg;



                FUNCTIONPASS(AppTaskADC);

                Q_ADC=OSQCreate((void*)0,5); /* ADC队列 缓存5个AD采样请求 */

    while (1)

    {

            msg=(INT8U *)OSQPend(Q_ADC, OS_TICKS_PER_SEC, &err);

            if (OS_NO_ERR == err)

            {

                    printf("收到%d的%d通道ADC采集请求msg=%d.\r
",((t_Message *)msg)->TX_ID,((t_Message *)msg)->data,msg);

                    OSTimeDlyHMSM(0,0,0,5);

                    OSMboxPost(Mbox[((t_Message *)msg)->TX_ID],(void *)1);

            }       

            if(OS_TIMEOUT == err)

            {

                                            printf("SYSTIME= %d,ADC等待超时!\r
",OSTimeGet());

            }

    }

}





会出现 只有一个任务转起来有一个任务发给ADC的消息 出错了的问题

pupist 发表于 2006-12-22 15:13:19

找到毛病了队列初始化的时候没给分空间 :P

AuToCTRL 发表于 2006-12-22 20:37:05

队列初始化没有分配空间会出现这个问题??./emotion/em014.gif

pupist方便发上来瞧瞧么。

pupist 发表于 2006-12-23 18:20:45

OS_EVENT   *Q_ADC;

#define                        Q_ADC_LEN                5

void *Q_ADCtbl;





Q_ADC=OSQCreate(&Q_ADCtbl,Q_ADC_LEN); /* ADC队列 缓存Q_ADC_LEN个AD采样请求 */

                ~~~~~~~~~~~这里以前填的是 (void *) 0

MYMCU 发表于 2006-12-23 19:34:24

没用过,帮你顶一下.
页: [1]
查看完整版本: ucos 消息队列通信