OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5233|回复: 7

UCOSIII 内建消息,使用OS_OPT_PEND_NON_BLOCKING,任务不能切换

[复制链接]

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
发表于 2016-8-10 13:43:21 | 显示全部楼层 |阅读模式
5金钱
我使用UCOSIII内建消息机制,想通过任务A给任务B发送一个消息,任务B根据接收到消息并打印,同时任务B还有其他工作要做,想通过OS_OPT_PEND_NON_BLOCKING,检查如果没有接收到A的消息就继续循环,不对任务B进行阻塞。
问题是:使用了OS_OPT_PEND_NON_BLOCKING之后,程序一直在任务B中循环不会再切换到任务A中运行了。
以下是任务B的接收函数
void modbus_tcp_thread(void *arg)
{
        struct netbuf *p;
        u8 i = 0;
        u8 buf[10];
        OS_MSG_SIZE size;
        OS_ERR err;
//        printf("**modbus_tcp_thread任务开始:\r\n");
        printf("**modbus_tcp_thread任务 任务优先级:%d\r\n",MODBUSTCP_PRIO);       
        eMBEnable( );
        while (1)
        {
                eMBPoll();
               
                //请求消息OS_OPT_PEND_BLOCKING 如果没有任何消息存在的话就阻塞任务,一直等待,直到接收到消息
                p=OSTaskQPend((OS_TICK                )0,
                      (OS_OPT                )OS_OPT_PEND_NON_BLOCKING,//OS_OPT_PEND_NON_BLOCKING 如果消息队列没有任何消息的话任务就直接返回
                      (OS_MSG_SIZE*        )&size,
                      (CPU_TS*                )0,
                      (OS_ERR*      )&err );
               
                if(err == OS_ERR_NONE)
                {
                        printf("size:%d",size);
                        memcpy(buf,p,size);
                        printf("Modbus接收数据:");
                        for(i=0;i<size;i++)
                        {
                                printf("%d,",buf[i]);
                        }
                        printf("\r\n");
                       
                }
                myfree(SRAMIN,p);        //释放内存
                               
        }
}


以下是任务A的发送函数:
printf("第%d组数据:",j);
                                for(i=0;i<10;i++)
                                {
                                        buf[i] = i*j;
                                        printf("%d,",buf[i]);
                                }
                                 printf("\r\n");
                               
                                //发送消息
                                OSTaskQPost((OS_TCB*        )&ModbusTCPTaskTCB,        //向任务Msgdis发送消息
                                                        (void*                )buf,
                                                        (OS_MSG_SIZE)10,
                                                        (OS_OPT                )OS_OPT_POST_FIFO,
                                                        (OS_ERR*        )&err1);


最佳答案

查看完整内容[请看2#楼]

那消息的OS_OPT_PEND_NON_BLOCKING功能好像就没有用处了,只要打开他,他所有在的任务就一直占用着CPU,除非延时或者定期调用它了!!!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
 楼主| 发表于 2016-8-10 13:43:22 | 显示全部楼层
ysq7120 发表于 2016-8-10 16:05
这种处理消息的任务,一般让他单纯一点的好。

那消息的OS_OPT_PEND_NON_BLOCKING功能好像就没有用处了,只要打开他,他所有在的任务就一直占用着CPU,除非延时或者定期调用它了!!!!!
回复

使用道具 举报

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
 楼主| 发表于 2016-8-10 13:52:30 | 显示全部楼层
补充以下:使用OS_OPT_PEND_BLOCKING,当任务A给任务B发送消息后,任务B就会执行下面的打印。假如A不发送消息任务B就会被挂起,直到有消息接收。目前就是想让任务B在没有消息接收的时候也进行while()大循环!!!!
回复

使用道具 举报

11

主题

80

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4493
金钱
4493
注册时间
2016-8-2
在线时间
51 小时
 楼主| 发表于 2016-8-10 15:22:25 | 显示全部楼层
在使用UCOSIII的内建消息队列过程中,我在A任务向B任务发送一个消息,B任务中进行消息OSTaskQPend接收。
1.如果配置成OS_OPT_PEND_BLOCKING 阻塞模式,没有消息的时候任务B就会被挂起。OSTaskQPend后续的代码就一直不能执行。
2.如果配置成OS_OPT_PEND_NON_BLOCKING,OSTaskQPend()函数会被在任务的大循环中一直被调用,后续的代码也可以被执行。
3.但是OSTaskQPend函数在不断的调用过程中,OSTaskQPend函数内部不断的在OS_CRITICAL_ENTER(); //关中断OS_CRITICAL_EXIT();  开关中断。
4.导致的结果就是任务B一直在运行,无法切换到任务A中。
5.在OSTaskQPend中增加5ms延时可以解决上述问题但是,影响任务实时性。

求大神帮忙出出主意怎么弄!
回复

使用道具 举报

19

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2016-4-22
在线时间
187 小时
发表于 2016-8-10 16:03:07 | 显示全部楼层
你的eMBPoll为了干什么?你要平时无消息也循环无法就执行这个函数。那你还不如开个定时器,平时就调用他。而任务里面依然用OS_OPT_PEND_BLOCKING 。
这样你的任务打印就能实时。平时没有消息也可以节省资源。
伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞新雨月,也难如钩也难圆。
回复

使用道具 举报

19

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2016-4-22
在线时间
187 小时
发表于 2016-8-10 16:05:21 | 显示全部楼层
这种处理消息的任务,一般让他单纯一点的好。
伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞新雨月,也难如钩也难圆。
回复

使用道具 举报

19

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2016-4-22
在线时间
187 小时
发表于 2016-8-10 17:00:57 | 显示全部楼层
shaozp 发表于 2016-8-10 16:30
那消息的OS_OPT_PEND_NON_BLOCKING功能好像就没有用处了,只要打开他,他所有在的任务就一直占用着CPU, ...

这个可以用来检测信号有没有,而不用等待。windows上的事件也是可以这样。有时我自是想判断一下这个信号量/消息等的状态,可以用这个,有没有别的用法我就不清楚了。我一般只用这种情况。
伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞新雨月,也难如钩也难圆。
回复

使用道具 举报

4

主题

27

帖子

0

精华

高级会员

Rank: 4

积分
890
金钱
890
注册时间
2016-12-2
在线时间
39 小时
发表于 2017-12-27 14:25:41 | 显示全部楼层
我也遇到了同样的问题,有消息的时候就用消息内接收到的新的值做后面的程序处理,没有收到消息的话,就直接用上次消息得到的旧的值再次进行后面的程序处理。跟楼主是一个情况,请问,是怎么解决的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 13:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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