打印

有偿求助环形缓冲器用法—300RMB

[复制链接]
楼主: 冷漠
手机看帖
扫描二维码
随时随地手机跟帖
21
改一下4楼的代码,原来的代码在寄存器比较少的系统上会有临界区的问题

size_t GetRingCount()
{
  size_t size = (Ring.pIn - Ring.pOut) ;
  if( ( (size % RING_SIZE) == 0) && (size) ){
    size = RING_SIZE;
  }
  return  size;
}

使用特权

评论回复
22
desert_hawk| | 2010-1-7 11:40 | 只看该作者
互个鬼斥保护。

收发各建一环队,各队的插入和提取在其头尾操作。要碰头,不是空了就是满了,只要有空满标志即可,不会打架地。
HWM 发表于 2010-1-7 10:40

想请教HWM一下,如果用了空满标志,空满标志的访问用不用互斥?别说你只是在考虑51这种能用一条指令置位或复位一个标志的单片机,看看链接的那个帖子,看楼主用的是什么。

使用特权

评论回复
23
xlsbz| | 2010-1-7 11:43 | 只看该作者
可能是我理解的太肤浅了吧!

我认为就像HWM所说的那样啊,不至于搞那么麻烦吧!
到处都是看到UCOS的影子,感觉怪怪的!
inter_zhou 发表于 2010-1-7 11:13


我现在没闲工夫看这么复杂。以后有功夫再研究吧。

说不准也有用。

使用特权

评论回复
24
lxyppc| | 2010-1-7 11:51 | 只看该作者
当RING_SIZE为2^n时,取余会被编译成一个&运算,mCount可以由两个索引的关系得到
lxyppc 发表于 2010-1-6 16:33
这个说法比较不可靠,%运算没有这么简单,就算除数是2^n ...
arm_fan168 发表于 2010-1-7 11:04


因为RING_SIZE是个常量,所以编译会这么做的
比如

使用特权

评论回复
25
desert_hawk| | 2010-1-7 11:54 | 只看该作者
还想请教一下lxyppc,看到您在某个帖子里讲了一些关于“夹角”的问题,然后您说“所以pIn与pOut换成指针也没有什么区别”。那就麻烦lxyppc给分析分析,当pIn与pOut变成指针后,pIn%RING_SIZE是什么。别告诉我您的写法又变了,变成了“(pIn-buffer)++/RING_SIZE”了, 那没意思,那就把指针当索引用了。

使用特权

评论回复
26
lxyppc| | 2010-1-7 12:02 | 只看该作者
还想请教一下lxyppc,看到您在某个帖子里讲了一些关于“夹角”的问题,然后您说“所以pIn与pOut换成指针也没有什么区别”。那就麻烦lxyppc给分析分析,当pIn与pOut变成指针后,pIn%RING_SIZE是什么。别告诉我您的写 ...
desert_hawk 发表于 2010-1-7 11:54


夹角的问题只是针对计算Buffer中已有内容个数的时候说的,是为了说明pIn - pOut为什么可以直接用来作Buffer中元素的个数

如果换成指针,push与pop的代码写法都需要改变

使用特权

评论回复
27
HWM| | 2010-1-7 12:02 | 只看该作者
想请教HWM一下,如果用了空满标志,空满标志的访问用不用互斥?别说你只是在考虑51这种能用一条指令置位或复位一个标志的单片机,看看链接的那个帖子,看楼主用的是什么。 ...
desert_hawk 发表于 2010-1-7 11:40

如果设置标志都不用“原子操作”,而去自寻烦恼,那就没啥好说啦。高兴咋玩就咋玩吧,不陪了。

使用特权

评论回复
28
desert_hawk| | 2010-1-7 12:56 | 只看该作者
感谢楼上两位的回答。
我说一下自己对4楼方法的看法:
1.限制条件决定了缓冲区的长度只能取有限的那几个数值,注定了这种方法不可能成为一个通用性好的方法。
2.并没发现这种方法有何简便,除了免去了“mCount--”的互斥外。而且比起所长的方法, 也有增加复杂度的地方。“mCount--”不知道会对应用产生多大的影响?有多大损失?那有硬件除法器的单片机,有的运算一条除法就好几个周期,也快赶上关中断的时间了。
楼上的HWM老师不陪了,那鄙人也不陪了。非常没想到的是,这么一个简单的小问题浪费了这么多唇舌。

使用特权

评论回复
29
arm_fan168| | 2010-1-7 14:29 | 只看该作者
因为RING_SIZE是个常量,所以编译会这么做的
比如
14145
lxyppc 发表于 2010-1-7 11:51

这就有点奇怪了,看不清你发的图片,但相信一定如你所说。可是我用了好几种编译器都试过,没有一种出现你说的效果。其中IAR就试了两种,IAR EWAVR和IAR EWARM5.xx,都是全功能版。下边贴个IAR EWAVR的图片,进行%运算编译器会生成一个子程序,名称是?SS_DIVMOD_L02,调用这个子程序单步运行会有好几十条指令,莫非我的实验方法不对?

使用特权

评论回复
30
lxyppc| | 2010-1-7 14:44 | 只看该作者
本帖最后由 lxyppc 于 2010-1-7 14:46 编辑
这就有点奇怪了,看不清你发的图片,但相信一定如你所说。可是我用了好几种编译器都试过,没有一种出现你说的效果。其中IAR就试了两种,IAR EWAVR和IAR EWARM5.xx,都是全功能版。下边贴个IAR EWAVR的图片,进行%运 ...
arm_fan168 发表于 2010-1-7 14:29


找到原因了,IAR中的确是这样的,把优化级别降低,就会变成调用一个除法子程序

使用特权

评论回复
31
arm_fan168| | 2010-1-7 14:47 | 只看该作者
呵呵,应该就是这个原因了,编译器的优化级别我一般都选择none。

使用特权

评论回复
32
arm_fan168| | 2010-1-7 15:03 | 只看该作者
试了一下,还是不行,把IAR EWAVR的优化级别调到最高,情况依旧。

使用特权

评论回复
33
冷漠|  楼主 | 2010-1-7 15:16 | 只看该作者

“最简单的方法,往往是最有效的。”

本帖最后由 冷漠 于 2010-1-7 15:23 编辑

空/满 标志要互斥?

如果有这种担心,那就把pIn, pOut都设为uchar 类型好了。或者干脆,愿意互斥就互斥吧。愿意把所有的变量都设为全局变量就设置吧,管它什么攻击窗口不窗口,多方便痛快呀。没有人能拦着程序员的意愿。

也没有人会在这种裸奔应用中把pIn,  pOut设为指针,给自己添麻烦。“最简单的方法,往往是最有效的。”

使用特权

评论回复
34
lxyppc| | 2010-1-7 15:38 | 只看该作者
试了一下,还是不行,把IAR EWAVR的优化级别调到最高,情况依旧。
arm_fan168 发表于 2010-1-7 15:03


试试把char 改成 unsigned char
把b = a % RING_SIZE; 改成 b = (unsigned char)(a % ((unsigned char)RING_SIZE));
把RING_SIZE 改成 (1<<6)

使用特权

评论回复
35
冷漠|  楼主 | 2010-1-7 16:14 | 只看该作者
本帖最后由 冷漠 于 2010-1-7 16:16 编辑

如果一定要用uC/OS 的队列方法处理,最好搞清楚什么叫系统函数的“原子性”。别好像互斥互斥的就显得大拿了。

每个操作系统服务函数都是一句原语,——原子性语句。它的特点就是从开始执行起,就必须无阻碍地连续执行到结束。
注意下面:

所以这种函数一开始就是执行“关中断——OS_ENTER_CRITICAL( )”,直到运行完,最后才“开中断——OS_EXIT_CRITICAL( )"。全函数原子性,根本不用关心内部的pIn / pOut。

所以,哪位一定要追求用所长的程序,显得自己阳春白雪的话,请在你的程序中每次引用PUSH( )或者POP( )函数时,在函数前面加上:

#pragma  disable   /*Disable  Interrupts */
PUSH( );

或者
#pragma  disable
POP( );

这样,无论是所长抄的uC/OS ,还是 lxyppc 采用的双字节 uint 类型,都不必担心被修改了吧。

HWM :不陪你玩了。
冷漠: 以后看好书上的OS 概念再来。原语为什么要关中断?它要进入内核呀。用户进的去内核么。

使用特权

评论回复
36
sz_kd| | 2010-1-7 16:20 | 只看该作者
呵呵,还在吵。。。。。。。。。。。。。。。。。。

不过你们争论我们到是学到很多东西,不管怎么样,保证正确性就可以,方法可以有千万个

使用特权

评论回复
37
冷漠|  楼主 | 2010-1-7 16:41 | 只看该作者
本帖最后由 冷漠 于 2010-1-7 16:52 编辑

RING_SIZE= 8   或者16 或者2^n 的时候:
b = a % RING_SIZE
可简化为:
b = a & (RING_SIZE - 1)  //即0x0F, 0xFF, 0xFFF......

自己确实没想到过,很巧妙。圈圈说是他的发现专利,后来在Keil 的程序上看到。看来Keil 是剽窃了圈圈的专利。
        所以21IC是学习的好地方,有很多知识自己看书没用,记不住。只有看了别人的不同用法,才会加深印象。

使用特权

评论回复
38
desert_hawk| | 2010-1-7 17:06 | 只看该作者
“以后看好书上的OS 概念再来。”
-------------
麻烦以后别用这种说教的态度和人说话,你没这个资格。你讲的那些“理论”,我看都懒得看,技术方面我不再和你争论,却并不是佩服你,因为我明白和你讲道理讲不明白。但是如果你总是拿着想“侮辱别人”的态度来说话,我会和你斗到底,无论是网络上的还是现实中的。有问题可以QQ、电话什么的联系。

使用特权

评论回复
39
冷漠|  楼主 | 2010-1-7 17:26 | 只看该作者
还真不知道mCount有什么用?是Push ( )要用还是Pop ( ) ,如果不是2者都要用,就无所谓临界资源,如果仅仅Push ( )用,谈互斥?

莫须有的东西,也拿来争论?

        并没看到KEIL程序用到这个变量,难道是咱们中国人考虑问题更全面?看上去都挺懂的,互斥啦,队列啦,一个比一个厉害,就是不知道互斥保护的资源是个啥。

LS的每天上21IC的目的就是求得尊重来了。跟所长一样啊。最后一查,原来所长有心理问题。——这不是我瞎说,天才总是有点心理问题。在我心中,您是天下第一天才。我就是找骂来了,在骂声中学到很多东西,结识了很多高水平的人。

越来表现越差劲,hotpower算老几啦,我看都懒得看啦,再推荐你看看《代码大全》,别又是懒得看吧。没钱买送你一本。98元而已。别老电子版的免费,看看什么叫攻击窗口,看看为什么要缩小变量的作用域。我还懒得贴。

使用特权

评论回复
40
sz_kd| | 2010-1-7 17:35 | 只看该作者
呵呵。又互相斗了

使用特权

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

本版积分规则