搜索
bottom↓
回复: 24

原子操作宏

[复制链接]

出0入0汤圆

发表于 2008-1-27 11:44:02 | 显示全部楼层 |阅读模式
#define ATOMIC()\
  for(uint8 __save_sreg=SREG,__ToDo=1;cli(),__ToDo;__ToDo=0,SREG=__save_sreg)

#define NONATOMIC()\
  for(uint8 __save_sreg=SREG,__ToDo=1;sei(),__ToDo;__ToDo=0,SREG=__save_sreg)

WinAVR-20071221增加原子操作宏util/atomic.h。
以上是改动一下,以便IAR下使用。

出0入0汤圆

发表于 2008-1-27 20:06:23 | 显示全部楼层
没明白

出0入0汤圆

发表于 2008-1-27 20:22:51 | 显示全部楼层
这两年流行纳米,现在流行原子了。

出0入0汤圆

 楼主| 发表于 2008-1-27 20:52:11 | 显示全部楼层
原子操作 是操作过程不能被打断的意思。

出0入0汤圆

发表于 2008-1-27 21:24:34 | 显示全部楼层
哗众取宠

出0入12汤圆

发表于 2008-1-27 23:53:39 | 显示全部楼层
4楼为什么这样说啊,lz推荐的确实有用啊。一般很容易忽略此操作,而埋下隐患。不一定要关全局中断,但此类考虑是重要的。

出0入0汤圆

发表于 2008-1-28 00:13:19 | 显示全部楼层
没明白

出0入0汤圆

发表于 2008-1-28 00:24:18 | 显示全部楼层
【5楼】 kv2004
4楼为什么这样说啊,lz推荐的确实有用啊。一般很容易忽略此操作,而埋下隐患。不一定要关全局中断,但此类考虑是重要的。
----------------------------------------------
【4楼】 zlf667788 “哗众取宠”

出0入0汤圆

发表于 2008-1-28 01:16:02 | 显示全部楼层
我一般只用cli,sei,不知道其它语句有什么用。

出0入0汤圆

发表于 2008-1-28 10:26:02 | 显示全部楼层
原子操作的概念,对单处理器而言主要是开关中断,以保证某些操作的连续性。而对单处理器x86之类还包括了用汇编实现的原子加法等操作,以保证相应的操作是单条汇编指令。
原子操作是系统内核中数据/进程同步的基本方法之一。

出0入0汤圆

 楼主| 发表于 2008-1-28 14:45:05 | 显示全部楼层
主要是为了书写方便。

原子操作一般用
cli();
…………
sei();
但是,如果在进原子操作之前,总中断是关闭的,会误操作把总中断打开。

更好的办法是
uint8 flags=SREG;
cli();
…………
SREG=flags;

为书写更加方便,定义ATOMIC()宏,可以嵌套,
原子操作可以
ATOMIC()
{
…………
}

出0入0汤圆

发表于 2008-1-28 17:38:54 | 显示全部楼层
嗯,有理,不错的宏。

出0入0汤圆

 楼主| 发表于 2008-1-28 23:12:09 | 显示全部楼层
static inline uint8 CriticalEnter(void)
{
      uint8 flags=SREG;
       cli();
      return flags;     
}

static inline void CriticalExit(uint8 flags)
{
SREG=flags;
}

static inline uint8 NonCriticalEnter(void)
{
      uint8 flags=SREG;
       sei();
      return flags;     
}

static inline void NonCriticalExit(uint8 flags)
{
SREG=flags;
}


#define ATOMIC()\
  for(uint8 __flags=CriticalEnter(),__ToDo=1;__ToDo;__ToDo=0,CriticalExit(__flags))

#define NONATOMIC()\
  for(uint8 __flags=NonCriticalEnter(),__ToDo=1;__ToDo;__ToDo=0,NonCriticalExit(__flags))


改动一下,这样编译出来的代码效率更高。

傻孩子:我觉得编译出来是否效率更高,完全取决于编译器,对楼主用的编译器来说,以上代码效率更高,但是对于ICC或者其他,就有待进一步证实了,所以以后还希望大家在说“编译效率更高”的时候强调一下,是经过哪些编译环境测试的。谢谢

出0入0汤圆

发表于 2008-1-29 03:32:51 | 显示全部楼层
原子操作宏

嗯,很不错,留个句号

出0入0汤圆

发表于 2008-1-29 09:19:50 | 显示全部楼层
好。多谢楼主。

出0入0汤圆

 楼主| 发表于 2008-1-30 16:32:03 | 显示全部楼层
原子操作要注意确保里面的语句不被编译器优化掉。

ATOMIC()
{
………………//要注意确保里面的语句不被编译器优化掉,否者并没有进行原子操作
}


一个简单例子:
uint8 test( uint8 data)
{
  uint8 var;
  ATOMIC()
     {
        var=data;    //编译器优化掉了
     }

  return var*var;
}
IAR下编译出来的汇编代码是:
test:
        IN      R17, 0x3F
        CLI
        OUT     0x3F, R17
        MUL     R16, R16
        MOV     R16, R0
        RET

uint8 test(volatile uint8 data)
{
  uint8 var;
  ATOMIC()
     {
        var=data;  
     }
  return var*var;
}
IAR下编译出来的汇编代码是:
test:
        SBIW    R29:R28, 1
        ST      Y, R16
        IN      R16, 0x3F
        CLI
        LD      R17, Y
        OUT     0x3F, R16
        MUL     R17, R17
        MOV     R16, R0
        ADIW    R29:R28, 1
        RET





这种写法同上。
uint8 flags=SREG;
      cli();
   ……………… //要注意确保里面的语句不被编译器优化掉,否者并没有进行原子操作
    SREG=flags;




这种写法同上。
  cli();
……………… //要注意确保里面的语句不被编译器优化掉,否者并没有进行原子操作
  sei();

出0入0汤圆

发表于 2010-5-5 09:59:12 | 显示全部楼层
ji

出0入0汤圆

发表于 2010-5-9 16:50:49 | 显示全部楼层
回复【15楼】ATmega32 上官金虹
原子操作要注意确保里面的语句不被编译器优化掉。
atomic()
{
………………//要注意确保里面的语句不被编译器优化掉,否者并没有进行原子操作
}
一个简单例子:
uint8 test( uint8 data)
{
  uint8 var;
  atomic()
     {
        var=data;    //编译器优化掉了
     }
  return var*var;
}
iar下编译出来的汇编代码是:
test:
        in      r17, 0x3f
        cli
        out     0x3f, r17
        mul     r16, r16
        mov     r16, r0
        ret
uint8 test(volatile uint8 data)......
-----------------------------------------------------------------------

呵呵,赞一个。。。
再请问一下,关于:注意确保里面的语句不被编译器优化掉,大家有什么建议?

出0入0汤圆

发表于 2010-5-9 17:05:45 | 显示全部楼层
我用最新的IAR编译代码:

        RSEG CODE:CODE:NOROOT(1)
//  115 uint8 test( uint8 data)  
test:
//  116 {  
//  117   uint8 var;  
//  118   CRITICAL()  
        IN      R17, 0x3F
        CLI
//  119      {  
//  120         var=data;    //编译器优化掉了  
        MOV     R18, R16
//  121      }  
        OUT     0x3F, R17
//  122   return var*var;  
        MUL     R18, R18
        MOV     R16, R0
        RET
//  123 }


楼主试试加个asm("");

uint8 test( uint8 data)  
{  
  uint8 var;  
  CRITICAL()  
     {  
       asm("");
        var=data;   
     }  
  return var*var;  
}

出0入0汤圆

发表于 2010-5-9 17:27:52 | 显示全部楼层
回复【楼主位】ATmega32 上官金虹
#define atomic()\
  for(uint8 __save_sreg=sreg,__todo=1;cli(),__todo;__todo=0,sreg=__save_sreg)
#define nonatomic()\
  for(uint8 __save_sreg=sreg,__todo=1;sei(),__todo;__todo=0,sreg=__save_sreg)
winavr-20071221增加原子操作宏util/atomic.h。
以上是改动一下,以便iar下使用。
-----------------------------------------------------------------------

请问for语句第三个表达式中__todo=0,sreg=__save_sreg是什么意思?
请解释一下行吗?

出0入0汤圆

发表于 2010-5-9 17:37:03 | 显示全部楼层
更新:
#define CriticalEnterHook() do{}while(0)
#define CriticalExitHook()  do{}while(0)

typedef unsigned char critical_flag_t;

#ifndef __always_inline__
#define __always_inline__  _Pragma("inline=forced") inline
#endif

__always_inline__  static  critical_flag_t CriticalEnter(void)
{
        critical_flag_t flags=__get_interrupt_state();
        __disable_interrupt();
        CriticalEnterHook();
        return flags;
}

__always_inline__  static void CriticalExit(critical_flag_t flags)
{
       __set_interrupt_state(flags);
       CriticalExitHook();
}

#define CRITICAL()\
  for(critical_flag_t __flags=CriticalEnter(),__ToDo=1;__ToDo;__ToDo=0,CriticalExit(__flags))


to楼上,
for(<初始化>; <条件表达式>; <增量表达式>)
{

}
for(uint8 __save_sreg=sreg,__todo=1;sei(),__todo;__todo=0,sreg=__save_sreg)  
{

}

初始化:定义两个uint8变量__save_sreg,__todo,初始值__save_sreg=SREG,__todo=1
条件表达式:__todo!=0
增量表达式:_todo=0,sreg=__save_sreg

循环只运行一次,初始时__save_sreg保存SREG,退出循环前SREG恢复到__save_sreg。

出0入0汤圆

发表于 2010-5-9 20:00:56 | 显示全部楼层
噢,谢谢楼主,我明白了,原来__todo=0是让条件表达式等于0。。。。。。

出0入0汤圆

发表于 2010-5-9 20:57:53 | 显示全部楼层
有分子操作么?

出0入0汤圆

发表于 2010-9-17 16:35:50 | 显示全部楼层
回复【18楼】voidx
-----------------------------------------------------------------------

RSEG CODE:CODE:NOROOT(1)各个标号都代表什么意思?

出0入0汤圆

发表于 2011-1-1 14:08:33 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 06:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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