2011-03-24 48 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