OpenEdv-开源电子网

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

uCosIII,在软件定时器回调函数里发送消息,使用Task1接收,收到的消息总是不对,请指点,共同学习,谢谢!

[复制链接]

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
发表于 2015-7-22 16:02:40 | 显示全部楼层 |阅读模式
5金钱
程序思路是这样的:
创建Task1、Task2、软件定时器1、消息对象KEY_Msg;
Task1任务:等待消息,打印出消息内容
************************************
while (1)
{
    KeyIdx=OSQPend((OS_Q* )&KEY_Msg,   
    (OS_TICK )0,
                   (OS_OPT )OS_OPT_PEND_BLOCKING,
                   (OS_MSG_SIZE* )&size,
                   (CPU_TS* )0,
                   (OS_ERR* )&err);
    printf("\r\n OSQPend %d", *KeyIdx);
}
**************************************
软件定时器1任务:扫描2个按键,有按键按下发送消息;
**************************************
ucKeyIdx = KeyScan(0);

if(ucKeyIdx != 0)
{
    printf("\r\n OSQPost %d", ucKeyIdx);
    OSQPost((OS_Q* )&KEY_Msg,
                    (void* )&ucKeyIdx,
                    (OS_MSG_SIZE)1,
                    (OS_OPT )OS_OPT_POST_FIFO,
                    (OS_ERR* )&err);
    printf("\r\n err %d", err);
}

**************************************
运行结果:
OSQPost 1
 err 0
 OSQPend 0

 OSQPost 2
 err 0
 OSQPend 0

那么问题来了,为什么Task1能收到消息,但是消息的结果是0呢?

PS:如果不用软件定时器扫描按键,而用Task2扫描按键,
运行结果:
 OSQPost 1
 OSQPend 1
 err 0
 OSQPost 2
 OSQPend 2
 err 0
结果正确,请问大虾,这是为什么呀???

最佳答案

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

没人给出答案,自己解决了,O(∩_∩)O哈哈哈~ 在消息发送时,实际上只是发送消息指针,不管是消息本身是什么数据类型,发送的指针都被理解为(void*)。在接收方得到这个消息指针后,通过指针来获取真正的消息内容。 如果发送消息的是任务(不是ISR),那么任务没有删除,保存消息的变量(不管是全局还是局部),总是存在的,接收消息的一方总是能够通过指针访问到这个变量,从而得到消息内容。 如果用ISR的局部变量来保存消息,则 ...
签名必须手写!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-22 16:02:41 | 显示全部楼层
没人给出答案,自己解决了,O(∩_∩)O哈哈哈~
在消息发送时,实际上只是发送消息指针,不管是消息本身是什么数据类型,发送的指针都被理解为(void*)。在接收方得到这个消息指针后,通过指针来获取真正的消息内容。
如果发送消息的是任务(不是ISR),那么任务没有删除,保存消息的变量(不管是全局还是局部),总是存在的,接收消息的一方总是能够通过指针访问到这个变量,从而得到消息内容。
如果用ISR的局部变量来保存消息,则接收方就不能获取真正的消息,原因是接收消息方在获取消息指针时ISR已经结束,其局部变量也一同消息。
软件定时器的回调函数和ISR差不多。
签名必须手写!
回复

使用道具 举报

3

主题

401

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1769
金钱
1769
注册时间
2015-6-11
在线时间
313 小时
发表于 2015-7-22 16:41:33 | 显示全部楼层
printf("\r\n OSQPend %d", *KeyIdx);因为你放在了OSQPend下面了
OSQPend调用时输出的值是当前的请求值,执行到printf输出时信号量已经被请求了,当然变0了
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-22 16:50:32 | 显示全部楼层
回复【2楼】zc123:
---------------------------------
如果不用软件定时器扫描按键,而用Task2扫描按键,结果正确,这个怎么解释?
签名必须手写!
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-22 16:52:59 | 显示全部楼层
回复【2楼】zc123:
---------------------------------
我把消息赋值给一个全局变量gucKeyIdx = *KeyIdx;然后再打印
printf("\r\n OSQPend %d", gucKeyIdx);
结果还是0;
签名必须手写!
回复

使用道具 举报

3

主题

401

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1769
金钱
1769
注册时间
2015-6-11
在线时间
313 小时
发表于 2015-7-22 17:02:12 | 显示全部楼层
回复【4楼】sf116:
---------------------------------
KeyIdx赋值给全局变量是无意义的啊,
Task1调用时,此时信号量1
OSQPend((OS_Q*  )&KEY_Msg,   
    (OS_TICK  )0,
                   (OS_OPT  )OS_OPT_PEND_BLOCKING,
                   (OS_MSG_SIZE* )&size, 
                   (CPU_TS*  )0,
                   (OS_ERR*  )&err);运行后,信号量为0,返回0
也就是KeyIdx就是0
你下面哪种情况应该是TASK2和软件定时器1两个任务同时产生信号量吧
1+1-1 = 1;
1+1+1 - 1 = 2;
你把软件定时器1内部注释掉,再看TASK2扫描对不对
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-22 17:14:01 | 显示全部楼层
回复【5楼】zc123:
---------------------------------
软件定时器注释掉的,只运行TASK2结果是对的。
签名必须手写!
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-23 09:15:33 | 显示全部楼层
原子哥来帮忙看看呀
签名必须手写!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-23 23:05:32 | 显示全部楼层
我没搞过iii,帮顶。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2015-7-24 19:22:22 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
感谢原子哥光顾
签名必须手写!
回复

使用道具 举报

3

主题

126

帖子

0

精华

高级会员

Rank: 4

积分
776
金钱
776
注册时间
2015-2-28
在线时间
251 小时
发表于 2015-12-28 17:14:32 | 显示全部楼层
本帖最后由 mingjie2015 于 2015-12-28 17:38 编辑
sf116 发表于 2015-7-24 19:22
回复【8楼】正点原子:
---------------------------------
感谢原子哥光顾

如果用ISR的局部变量来保存消息,则接收方就不能获取真正的消息,原因是接收消息方在获取消息指针时ISR已经结束,其局部变量也一同消息。
软件定时器的回调函数和ISR差不多。

那你怎么实现的呢
ucKeyIdx**为全局变量???
回复

使用道具 举报

6

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
437
金钱
437
注册时间
2013-4-9
在线时间
76 小时
 楼主| 发表于 2016-1-8 20:46:21 | 显示全部楼层
mingjie2015 发表于 2015-12-28 17:14
如果用ISR的局部变量来保存消息,则接收方就不能获取真正的消息,原因是接收消息方在获取消息指针时ISR已 ...

对,类似思路
签名必须手写!
回复

使用道具 举报

5

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2018-7-27
在线时间
86 小时
发表于 2021-3-5 11:54:48 | 显示全部楼层
sf116 发表于 2015-7-22 16:02
没人给出答案,自己解决了,O(∩_∩)O哈哈哈~
在消息发送时,实际上只是发送消息指针,不管是消息本身是什 ...

我也碰到这个问题了,按照你说的解决了,大神厉害!!!!!!!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 10:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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