打印

uCOS-II中消息邮箱中消息的为局部变量讨论

[复制链接]
楼主: Swd21ic
手机看帖
扫描二维码
随时随地手机跟帖
21
Swd21ic|  楼主 | 2008-11-28 23:40 | 只看该作者 回帖奖励 |倒序浏览

来个完全分析.. 都是经过DEBUG验证了的

写到图里了.

使用特权

评论回复
22
Swd21ic|  楼主 | 2008-11-28 23:42 | 只看该作者

re

不过为了避免出错和习惯性问题.还是用全局变量和静态变量吧..

使用特权

评论回复
23
zyok| | 2008-11-28 23:48 | 只看该作者

很好,谢谢

使用特权

评论回复
24
zyok| | 2008-11-28 23:50 | 只看该作者

我觉得case 3 比较好

使用特权

评论回复
25
machunshui| | 2008-11-29 08:31 | 只看该作者

局部变量又怎样?

“也许还有一种:任务的私有堆栈虽然使用定义上是局部变量,但实际上是静态变量。”

任务函数的局部变量就是局部变量,不是静态变量。

象中断函数的局部变量的地址不是不能被邮箱消息队列使用,而是当系统使用,中断函数已经退出,这个地址的内容被别的函数覆盖,已经不是原来的数据。


任务函数不返回,

当然不存在其局部变量被覆盖的问题,

那么根据其局部变量地址来使用该局部变量,

当然是可以的,

所以任务函数的局部变量可以作为OSMboxPost的参数来使用。

使用特权

评论回复
26
machunshui| | 2008-11-29 08:41 | 只看该作者

任务函数调用的函数的局部变量是会有问题的

21楼分析的透彻。

任务函数调用的函数的局部变量是会有问题的。

使用特权

评论回复
27
Swd21ic|  楼主 | 2008-11-29 09:34 | 只看该作者

re

"任务函数调用的函数的局部变量是会有问题的"
Case4.1那种立刻进行任务切换的情况是不会有问题的..
当然..谁也不会那么去用.

使用特权

评论回复
28
学生D| | 2008-11-29 10:27 | 只看该作者

支持22楼。

我觉得还是按有把握的事情去做。例如21楼的case 1、case 2总是可靠的。

case3/case4 该不是与不同系的编译、连接/定位器有关?例如case 3,如果移植到51系,使用Lx51,情景就大不一样了。



周慈航老师也是先有实验,后有结论。有些结论是在“必须满足的前提下”才保证是对的。例如21楼的case 4.1/case 4.2/case 4.3,应该注释一下书中所讲的“必须满足的前提”:

“任何时候消息的生产速度都比消息的消费速度慢,即被控制任务总是在等待消息。”简单说,消息发送者要求消息接收者已经/正在等待自己的消息。如果false,消息还发吗?(消息邮箱里只能存放一条消息,如果消息发送了却不能立即取走的话,岂不是浪费了CPU资源。)

所以,
case 4.1  符合前提,OK。
case 4.2  不符合前提,ERROR.(照理不应该/也不用发送)
case 4.3  不符合前提,ERROR..(不应该用局部变量发送)

使用特权

评论回复
29
ayb_ice| | 2008-11-29 10:28 | 只看该作者

我查了一下源代码

邮箱是存储的确实是指针,
但这也不是问题,这个消息变量(定义)本身是由发送方来保证的,这和局部变量的问题是两码事,如果在接收方接收到消息前局部变量死亡肯定会有问题的,所有的问题都是C一样的。
一般的做法是直接使用全局变量或在任务中(注意是任务中)的局部变量,或者通过动态内存分配,
具体的一般是:
  发送方先申请内存,然后存消息,发送消息,接收方收到消息后使用或复制,然后释放内存,KEIL RTX DEMO程序就是这样做的。

使用特权

评论回复
30
Swd21ic|  楼主 | 2008-11-29 14:02 | 只看该作者

re

我不太会用动态内存分配..可能没写过上位机软件吧.感觉怪怪的.
直接用数组了..

使用特权

评论回复
31
ayb_ice| | 2008-11-29 17:27 | 只看该作者

可以直接用UCOSII的动态内存管理函数

使用特权

评论回复
32
js87654| | 2008-12-2 02:16 | 只看该作者

1

使用特权

评论回复
33
hitoolarm| | 2008-12-2 15:59 | 只看该作者

顶,楼主说的很有参考价值.

使用特权

评论回复
34
goulj| | 2008-12-2 16:59 | 只看该作者

关键是要看任务函数的存在

是局部变量, 可是这个局部变量是在任务函数主体中定义的,任务被删除前, 此函数会一直存在, 这时可以认为局部变量不会消失. 而任务函数在已经给出的代码中, 没有看到被删除.所以不存在另一个任务函数找不到此消息的问题. 大家讨论的完全驴唇不对马嘴.

使用特权

评论回复
35
wlq_9| | 2008-12-2 17:06 | 只看该作者

关键

还是变量的生存周期.
保险的角度来说,静态和全局是肯定不会出问题的.任务内的局部变量,生存周期问题,我觉得不保险,如果编译器不巧,把局部变量放到了R里面,而任务切换的时候,R被入任务栈.在另一个任务访问这个局变的时候,很可能就是个错误值.当然,在编译器把这个局变放到其它内存,比方说任务栈里面的时候,就是没有问题的.

使用特权

评论回复
36
ayb_ice| | 2008-12-2 21:14 | 只看该作者

其实任务中的局部变量

生命周期和全局的一样长,因为编译器并不知道任务什么时候被删除,只能认为一直没有被删除,不过我认为还是使用全局变量好,因为对全局变量的访问效率一般要高些,因为地址是已知的...

使用特权

评论回复
37
空下这个座| | 2008-12-8 16:25 | 只看该作者

一直都没有用局部变量

    一直以来都是写个全局的循环存入的数组来存那些邮箱和消息的数据,然后再把地址传递出去。不用去管优先级那点破事,也不用担心消息内容被改,当然,前提是数组不溢出。

使用特权

评论回复
38
9509238| | 2008-12-15 22:28 | 只看该作者

基本上是一个堆栈的理解问题

真是奇怪,ucos不是源代码公开的吗,为什么不看看源代码先呢!!!
这里,先给你解释一下吧: 
ucos的邮箱消息只是记录一个指针,也就是某个数据结构实例的存储地址.邮箱API函数只记录地址,并不关心数据本身.只要能保证消息被接收到之前,该地址的数据没有被改变,那么你的设计就是可行的.
显然,中断服务函数的栈随着中断退出和再次进入就可能被破坏,这样不行;
而周慈航的例子中,可行的原因是,它的任务执行着一个while(TRUE){}循环,并没有退出任务,所以任务的栈空间中的实例是保留的,也就是说设计可行.

使用特权

评论回复
39
Swd21ic|  楼主 | 2008-12-16 14:11 | 只看该作者

re

是哦.源码很熟了..就是不用应用。哈哈

使用特权

评论回复
40
stone.csz| | 2008-12-25 22:13 | 只看该作者

Ucos

对于任何变量,不管是全局变量还是局部变量,我们都可以使用邮箱进行传递。当然对于全局变量如果使用邮箱传递那就有点多此一举乐,因为全变对于任何任务都是可见的。所以通常用邮箱传递的都是局部变量,而且放入邮箱中的也只是一个指向局部变量的指针,并不是其内容哦!!

使用特权

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

本版积分规则