打印

唉,这么简单的问题搞这么复杂来忽悠菜鸟……

[复制链接]
楼主: 刘前辈
手机看帖
扫描二维码
随时随地手机跟帖
81
李富贵| | 2011-8-28 23:52 | 只看该作者 回帖奖励 |倒序浏览
不会吧,这么j8毛大的事情也会这么热烈讨论。
难道研究所的人整天研究各种雕虫小技和**毛蒜皮?

使用特权

评论回复
82
highgear| | 2011-8-29 00:04 | 只看该作者
二鬼子李富贵?
话糙理不糙。

使用特权

评论回复
83
李富贵| | 2011-8-29 01:08 | 只看该作者
俺是学不会新把戏的老狗。但是努力学习中。。。。。

之所以在这个帖子发言,是觉得某些老狗玩弄20年前的旧把戏,还洋洋自得,这嘴脸俺看不下去。

使用特权

评论回复
84
Cortex-M0| | 2011-8-29 06:30 | 只看该作者
大家散会吧,  **毛蒜皮没啥好争的~~~

使用特权

评论回复
85
t.jm| | 2011-8-29 08:44 | 只看该作者
这个问题,前面已经有人解决了。就是volatile。这个问题,51有,8086肯定有。但是这么多年,只有这里第一次讨论啊。。。。并且,读取是先读低位在读高位,就算溢出,错的也不是丢进位啊。 ...
icecut 发表于 2011-8-28 10:42

除了关中断,所有的解决都不是真的解决,只是出错概率大小的问题。即使是小概率,用在LED闪烁无所谓,敢用在火箭、高铁中吗?
volatile更不是用来解决这类问题的,不加volatile 单字节都有可能出错,但这属于compiler优化的问题。
对要读两次才能读到数据,即使你用汇编读写都没用,必须关中断没什么好争论的。

使用特权

评论回复
86
Cortex-M0| | 2011-8-29 08:56 | 只看该作者
回t.jm老师:

关中断确实是个行之有效的最简单的方法,代码简单长度短。

但有时在实时性很高的场合,关中断影响到整个系统的定时或计数时间节拍,才会有N多的其他“非典”解决方法。

举个简单例子,有些场合,如需要分两次才能读出高速计数器中之值,关中断也没用,除非关高速计数器,这又是一个不能容忍的杯具。

使用特权

评论回复
87
t.jm| | 2011-8-29 09:10 | 只看该作者
回t.jm老师:

关中断确实是个行之有效的最简单的方法,代码简单长度短。

但有时在实时性很高的场合,关中断影响到整个系统的定时或计数时间节拍,才会有N多的其他“非典”解决方法。

举个简单例子,有些场合,如 ...
Cortex-M0 发表于 2011-8-29 08:56

谁都想不管中断都达到目的,但是这是不可能的。
我也想过用汇编读写,比如取数是我先读高字节后读低字节等等,++操作也许有效,--就没效了,在复杂的环境中++,--,+n,-n都是有可能的。
这些非典只是在自我安慰。

使用特权

评论回复
88
Cortex-M0| | 2011-8-29 10:01 | 只看该作者
唉~~~

俺真笨,今天才明白,刘前辈的小儿科问题,为什么这么有市场~~~

因为,懂的都笑笑,打酱油路过,不值的回答~~~

不懂的总有一大堆理由,答非所问的解释一件很简单的小儿科问题~~~

所以,刘前辈的小儿科问题,才能在二姨家所向披靡~~~

使用特权

评论回复
89
ayb_ice| | 2011-8-29 10:17 | 只看该作者
唉~~~

俺真笨,今天才明白,刘前辈的小儿科问题,为什么这么有市场~~~

因为,懂的都笑笑,打酱油路过,不值的回答~~~

不懂的总有一大堆理由,答非所问的解释一件很简单的小儿科问题~~~

所以,刘前辈的小儿科问题 ...
Cortex-M0 发表于 2011-8-29 10:01
:victory:

使用特权

评论回复
90
t.jm| | 2011-8-29 10:31 | 只看该作者
举个简单例子,有些场合,如需要分两次才能读出高速计数器中之值,关中断也没用,除非关高速计数器,这又是一个不能容忍的杯具。
Cortex-M0 发表于 2011-8-29 08:56 [/quote]
像这种情况搞个影子寄存器就OK了,硬件问题硬件解决才是行之有效的方法,
读到的数据即使不会是最新的也不会是错误的数据。

使用特权

评论回复
91
Cortex-M0| | 2011-8-29 11:06 | 只看该作者
t.jm老师正解!

搞个影子寄存器,硬件问题硬件解决才是王道 !  

可惜很多小MCU不是俺设计的,都是现成的,不带影子寄存器~~~ :L

使用特权

评论回复
92
t.jm| | 2011-8-29 11:29 | 只看该作者
t.jm老师正解!

搞个影子寄存器,硬件问题硬件解决才是王道 !  

可惜很多小MCU不是俺设计的,都是现成的,不带影子寄存器~~~ :L
Cortex-M0 发表于 2011-8-29 11:06

我说的影子寄存器是指对应你说的高速计数器的,有了影子寄存器不关中断就能正确读取高速计数器的数值,而且现在的一些MCU硬件上已采用这种东西了,读写寄存器分开,写入时先对影子寄存器操作等等。
对内存的操作,需要两个时序以上才能取到完整数据,而且中断中会对这个数据改写时只有关中断才能解决问题。其它方法都有BUG,只是出错频率的问题。

使用特权

评论回复
93
icecut| | 2011-8-29 11:52 | 只看该作者
91# Cortex-M0
俺要用大数,1024bit计数,你给来个影子寄存器吧....

使用特权

评论回复
94
icecut| | 2011-8-29 11:52 | 只看该作者
我说的影子寄存器是指对应你说的高速计数器的,有了影子寄存器不关中断就能正确读取高速计数器的数值,而且现在的一些MCU硬件上已采用这种东西了,读写寄存器分开,写入时先对影子寄存器操作等等。
对内存的操作, ...
t.jm 发表于 2011-8-29 11:29

如果都有bug,那就不用多核处理器了.

使用特权

评论回复
95
Cortex-M0| | 2011-8-29 12:12 | 只看该作者
91# Cortex-M0
俺要用大数,1024bit计数,你给来个影子寄存器吧....
icecut 发表于 2011-8-29 11:52



那这个影子寄存器,只能依靠t.jm 大虾解决了~~~  :lol

使用特权

评论回复
96
Cortex-M0| | 2011-8-29 12:15 | 只看该作者
如果都有bug,那就不用多核处理器了.
icecut 发表于 2011-8-29 11:52



这个不是bug,  这个是由于当时年代,芯片密度及制造工艺的局限性造成的。

使用特权

评论回复
97
icecut| | 2011-8-29 12:19 | 只看该作者
96# Cortex-M0
不管什么局限都叫bug....

现在的多核,这种问题更多....但只能算同步问题.不是bug了

使用特权

评论回复
98
刘前辈|  楼主 | 2011-8-29 12:33 | 只看该作者
本帖最后由 刘前辈 于 2011-8-29 13:09 编辑
#69楼M0
既然已经用了循环读取 count 的方法,就没必要用 DPTR 了。
流行音乐 发表于 2011-8-28 15:01
流行音乐 正解!
这里面的DPTR纯粹当一int型变量使用,写DPTR是为了吸引眼球,显示“红杏出墙”之“非典”应用~~~


M0太有才了。

咱来讲讲为什么用DPTR的小儿科问题,若有疑问,看看Hot大叔推荐的李庆的《嵌入式RTOS概念》,在这道题目中概念是一样的:

SmartPower的题目偶发错误,原因是由于中断ISR和 主函数共享了一个变量count ,典型的读写者(小儿科)问题:读者读到一半,写者修改了数据,造成读者下一半数据读错误。——这类问题对icucut,SmartPower ,  一朝成名版主,原野之狼版主    ……来说,根本不叫问题,因为他们都懂得RTOS基本概念。

所以,要避开这类问题,就是主函数和ISR之间不要有共享变量 ,HOt大叔本题目一开始就说过了:“2者不要共用一个全局变量,俺习惯用静态全局变量。”——M0没看懂HOT大叔说的是什么?还以为大叔说的是小儿科问题……

     所以,DPTR就是大叔说的概念,“不与ISR共用一个count !ISR用公用变量count ,主函数用私有变量DPTR。这样,无论怎样中断,都不会影响下面DPTR的值:所以:

if ( DPTR>250 ) {  }  中的DPTR是一个私有变量,是一种避免与ISR共享变量的解决方法。根本无法取消的(当然可以定义另外一个int 局部变量)。

        所以,M0版主还没看懂HOT大叔说的是什么就认为是小儿科问题?M0 是不是间接在说HOT大叔也是小儿科 ?那就自取其辱了。

       以后,M0版主要像     其他几个斑竹那样,发奋学习RTOS原理概念了。还有所长,别再把哲学家喂成
╭︿︿︿╮
{/ o  o /}  
( (oo) )   
  ︶ ︶︶     才好。这把年龄再学也来不及了。只有红眼骂娘?……


、、

使用特权

评论回复
99
t.jm| | 2011-8-29 13:17 | 只看该作者
如果都有bug,那就不用多核处理器了.
icecut 发表于 2011-8-29 11:52

为什么不是说多核处理器核心设计和编程方法就有考虑此问题呢?
对内存不做保护的操作不要说多核,就是单核都会出问题。

使用特权

评论回复
100
Cortex-M0| | 2011-8-29 13:20 | 只看该作者
唉。。。。。

刘前辈辛苦啦,码了这么多字来教俺,谢谢~~~

只是,程序运行中出错的地方不在

if ( DPTR>250 ) {  }  中的DPTR是一个私有变量,是一种避免与ISR共享变量的解决方法。根本无法取消的(当然可以定义另外一个int 局部变量)。

而在于

DPTR = count ;       // 所长是不是什么都要让刘前辈告诉你?一点都不长进。

count 对 DPTR 的赋值过程中,万一当中发生中断,并且在中断过程中 ,count 变量中间有半进位发生,中断返回后,再继续执行 count 对 DPTR 赋的值就杯具了~~~

这个问题转了好大的一个圈,又回到了原地,再讨论下去又有神马意义?

至于本式中的 DPTR,可用任何 int变量代替,执行结果相同~~~

使用特权

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

本版积分规则