2011-03-24 46 views
5

我想知道它是否能够确保line被自动执行,因为它可以由ISR和主要方面都可以执行。我工作的一个ARM9(LPC313x),并使用的RealView 4器(armcc)。这可以原子执行吗?

foo() { 
    .. 
    stack_var = ++volatile_var; // line 
    .. 
} 

我正在寻找像_atomic_为C166,直接汇编代码等任何程序,我宁愿不要有禁用中断。

非常感谢。

回答

6

从快看,C166 _atomic_宏似乎利用了有效地掩蔽中断的指令指定数量的持续时间的指令。 在ARM架构中没有直接对应的东西。

当然你可以使用SWP指令(或工具链的RealView内在__swp)将围绕临界区的锁。另一个答案中提到的ldrex/strex在ARM架构版本5中不存在,其中包含ARM9处理器。分别为 http://infocenter.arm.com/help/topic/com.arm.doc.dui0491c/CJAHDCHB.htmlhttp://infocenter.arm.com/help/topic/com.arm.doc.dui0489c/Chdbbbai.html

对此的一种简单的锁机制(使用RealView工具链)将是:

{ 
    /* Loop until lock acquired */ 
    while (__swp(LOCKED, &lockvar) == LOCKED); 
    .. 
    /* Critical section */ 
    .. 
    lockvar = UNLOCKED; 
} 

然而,这导致ISR背景下死锁时,主线程持有锁。

我认为屏蔽操作周围的中断可能是最毛茸茸的解决方案,但如果您的Main上下文在用户模式下执行,则需要系统调用来实现。

+0

谢谢unixsmurf。 – JoeSlav 2011-03-26 11:43:05

+0

您可以在旧ARM上将'swpb'与'swp'混合使用以获得多个/单个模式。即,**多个标志制定者**和**单个标志清晰**。最多可以使用四个“字节”或“**状态”。 – 2013-02-19 22:44:09

8

不,我不认为你永远可以期待++volatile_var是原子的,即使你没有分配。为此使用适当的原子基元。如果你的编译器没有提供这样的扩展,你可以在网上找到一个简短的内联汇编器。我认为汇编程序的指令是调用ldrexstrex来进行原子交换。

编辑:似乎在问题中要求的特定处理器类型没有实现这些指令。

编辑:下应该用gcc工作,另外一个编译器可能具有对__asm__部分适应。

inline 
size_t arm_ldrex(size_t volatile*ptr) { 
    size_t ret; 
    __asm__ volatile ("ldrex %0,[%1]\[email protected] load exclusive\n" 
        : "=&r" (ret) 
        : "r" (ptr) 
        : "cc", "memory" 
        ); 
    return ret; 
} 

inline 
_Bool arm_strex(size_t volatile*ptr, size_t val) { 
    size_t error; 
    __asm__ volatile ("strex %0,%1,[%2]\[email protected] store exclusive\n" 
        : "=&r" (error) 
        : "r" (val), "r" (ptr) 
        : "cc", "memory" 
        ); 
    return !error; 
} 

inline 
size_t atomic_add_fetch(size_t volatile *object, size_t operand) { 
    for (;;) { 
    size_t oldval = arm_ldrex(object); 
    size_t newval = oldval + operand; 
    if (arm_strex(object, newval)) return newval; 
    } 
} 
+0

它是有益的,如果有人能抛出一些光,但不会以下被认为是原子? ADD r0,r0,#1如何使用ldrex/strex来增加一个值?我肯定错过了一些东西。 – TheLoneJoker 2011-03-24 15:39:26

+0

@Jens,我对此有点新。能否请你点我的一些资源/文件,提供有关代码的详细信息__asm__挥发性( “LDREX%0,[%1] \ t @负荷独家\ n” : “= R”(RET) :“R “(ptr) :”cc“,”memory“ ); 我不是很清楚里面的东西是什么意思。 – TheLoneJoker 2011-03-24 16:27:51

+0

@TheLoneJoker这就是所谓的“内联汇编”,插入到位的汇编程序指令,搜索该术语应该会为您找到更多信息。我在这里使用的变体是gcc,其他人可能也支持这样的扩展,但在实现时可能看起来不同。 – 2011-03-24 17:18:04