打印

UCOS II中队列和任务挂起的问题

[复制链接]
1903|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
学习UCOS II (V2.86) 中的时候,碰到一个问题。
创建好队列后,在一个任务1中发送一个消息 ,另外一个任务2中接收,并打印。在任务1中通过计数 来挂起任务2和恢复任务2,那么打印出来的是对的。但是如果把挂起和恢复 放在任务3中,打印出来的,就有问题了。具体现象是
任务2取消息的速度大于任务1发的速度,则会重复打印,并且会跳过我挂起时候的计数。如下图所示 。  如果任务2取消息的速度小于任务1发的速度,则会跳过打印。

具体在任务1中的代码如下
    u8 test = 10;
    u8 *test2;
     while(1)
    {
         
        test2=mymalloc(10);   
        if(test2)
        {        
            test ++;   
            sprintf((char*)test2,"alex %03d",test);
            err=OSQPost(q_msg,test2);   

            if(test == 32)
            {
                OSTaskSuspend(QMSGSHOW_TASK_PRIO);
            }
            else if(test == 64)
            {
                test = 0;
                OSTaskResume(QMSGSHOW_TASK_PRIO);
            }
            myfree(test2);
        }
        
        delay_ms(500);
    }


在任务3(d定时器回调函数)中的代码如下
static u8 msg_cnt=0;    //msg±àºÅ   
    p=mymalloc(13);   
    if(p)
    {
        msg_cnt++;
         sprintf((char*)p,"ALIENTEK %03d",msg_cnt);
        
        err=OSQPost(q_msg,p);   
        if(err!=OS_ERR_NONE)   
        {
            myfree(p);   

            OSTmrStop(tmr3,OS_TMR_OPT_NONE,0,&err);    //¹Ø±ÕÈí¼þ¶¨Ê±Æ÷3
         }
        if(msg_cnt == 32)
        {

//            OSTaskSuspend(TOUCH_TASK_PRIO);
            OSTaskSuspend(QMSGSHOW_TASK_PRIO);
        }
        else if(msg_cnt == 64)
        {
            msg_cnt = 0;
//            printf("RESUME TASK    \r\n");
//            OSTaskResume(TOUCH_TASK_PRIO);
            OSTaskResume(QMSGSHOW_TASK_PRIO);
        }
        


相关帖子

沙发
dai410257573|  楼主 | 2017-6-27 19:39 | 只看该作者
@icecut   i哥,求助

使用特权

评论回复
板凳
icecut| | 2017-6-28 10:27 | 只看该作者
你的测试代码写的感觉怪怪的.
1.请补上任务2
2. 队列就是个队列,放进去的会排队,取出来的会消失,在你这里怎么会重复 取出呢?

我认为task1会很随便的往里放,如果加不进去了,就自动挂起...
任务人随便的读取,取一个少一个...

请你根据书或者文档确认这个队列的功能是否完整

使用特权

评论回复
地板
kingkits| | 2017-6-28 10:32 | 只看该作者
建议使用环形缓冲区

使用特权

评论回复
5
dai410257573|  楼主 | 2017-6-28 11:05 | 只看该作者
icecut 发表于 2017-6-28 10:27
你的测试代码写的感觉怪怪的.
1.请补上任务2
2. 队列就是个队列,放进去的会排队,取出来的会消失,在你这里 ...


我截了3个图,任务1 2 3的,其中任务1 和 3中红色框部分,只会存在一个,放在回调函数,任务3中不会打印乱,但是放在任务1中,挂起后再恢复,就是如我在问题描述中的现象了。
我理解的队列状态是   ,我挂起后,再恢复后来取消息,也会从队列的第一个来取,放如队列中,也是排队放入的

使用特权

评论回复
6
icecut| | 2017-6-28 11:37 | 只看该作者
now=...是哪里打印的.没看见呢.
你的程序0-32次是正常发送, 32到64是强制发送,不接收,然后再正常发送接收?

使用特权

评论回复
7
dai410257573|  楼主 | 2017-6-28 11:44 | 只看该作者
icecut 发表于 2017-6-28 11:37
now=...是哪里打印的.没看见呢.
你的程序0-32次是正常发送, 32到64是强制发送,不接收,然后再正常发送接收? ...

uart_send_string();这个函数就是通过串口发数据~~
是的,我刚好学习到这个地方,就这样写了一个程序。逻辑是,0-32时候,正常发送,32-64任务挂起,不再取消息,然后恢复任务后,再继续取消息,来打印消息中传递过来的值。
实验的现象就是,在回调函数中,是没问题的,打印的逻辑正常,但是放在任务1中,就出现了描述的错误,好像就是回调函数的 *p是每次都重新定义和分配内存,而我在任务1中的test2    就只定义一次,另外我在while(1)中这样申请内存,可以吗?

使用特权

评论回复
8
icecut| | 2017-6-28 12:30 | 只看该作者
1. 一般ucos 的main任务不留功能直接pending起来就好了.或者永远sleep---->来自非官方设计思路
2.ucos的内存管理不一定好用.练习的时候能用.建议你用全局数组对比,申请256个这样就做256次,可以判断是不是内存问题

使用特权

评论回复
9
dai410257573|  楼主 | 2017-6-28 23:21 | 只看该作者
icecut 发表于 2017-6-28 12:30
1. 一般ucos 的main任务不留功能直接pending起来就好了.或者永远sleep---->来自非官方设计思路
2.ucos的内 ...

i哥,我找到问题了,创建队列是不会自动分配地址,而是指向传入的地址,所以每一次传入队列中的数据就会被新的数据覆盖。在上述3个任务中,任务3中的定时器回调函数,都是每一次分配一个地址。而在main中的test则是一个固定地址。所以在取消息的时候,会只出现最新的数据。

使用特权

评论回复
10
icecut| | 2017-6-29 10:00 | 只看该作者
恩.一般是post一个地址过去...这样占用空间小

使用特权

评论回复
11
dai410257573|  楼主 | 2017-6-29 11:39 | 只看该作者
icecut 发表于 2017-6-29 10:00
恩.一般是post一个地址过去...这样占用空间小

谢谢i哥

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

312

帖子

5

粉丝