新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > arm上ldrex和strexeq指令

arm上ldrex和strexeq指令

作者: 時間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
__raw_spin_lock在ARM處理器上的實現(xiàn)

/******include/asm-arm/spinlock_types.h***/

本文引用地址:http://m.butianyuan.cn/article/201611/317537.htm

typedef struct {
volatile unsigned int lock;
} raw_spinlock_t;

#define __RAW_SPIN_LOCK_UNLOCKED { 0 }

/******include/asm-arm/spinlock.h***/

#if __LINUX_ARM_ARCH__ < 6
#error SMP not supported on pre-ARMv6 CPUs //ARMv6后,才有多核ARM處理器
#endif
……
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp;
__asm__ __volatile__(
"1: ldrex%0, [%1]n"
//取lock->lock放在 tmp里,并且設(shè)置&lock->lock這個內(nèi)存地址為獨占訪問
"teq %0, #0n"
// 測試lock_lock是否為0,影響標(biāo)志位z
#ifdef CONFIG_CPU_32v6K
"wfenen"
#endif
"strexeq %0, %2, [%1]n"
//如果lock_lock是0,并且是獨占訪問這個內(nèi)存,就向lock->lock里 寫入1,并向tmp返回0,同時清除獨占標(biāo)記
"teqeq %0, #0n"
//如 果lock_lock是0,并且strexeq返回了0,表示加鎖成功,返回
" bne 1b"
//如 果上面的條件(1:lock->lock里不為0,2:strexeq失敗)有一個符合,就在原地打轉(zhuǎn)
: "=&r" (tmp) //%0:輸出放在tmp里,可以是任意寄存器
: "r" (&lock->lock), "r" (1)
//%1:取&lock->lock放在任意寄存 器,%2:任意寄存器放入1
: "cc"); //狀態(tài)寄存器可能會改變
smp_mb();
}

上述代碼關(guān)鍵在于LDREX和STREX指令的應(yīng)用。DREX和STREX指令是在V6以后才出現(xiàn)的,代替了V6以前的 swp指令。可以讓bus監(jiān)控LDREX和STREX指令之間有無其它CPU和DMA來存取過這個地址,若有的話STREX指令的第一個寄存器里設(shè)置為 1(動作失?。?,若沒有,指令的第一個寄存器里設(shè)置為0(動作成功)。

不僅是自旋鎖用到LDREX和STREX指令,信號量的實現(xiàn)也是利用LDREX和STREX指令來實現(xiàn)的。



關(guān)鍵詞: armldrexstrexeq指

評論


技術(shù)專區(qū)

關(guān)閉