新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > arm上ldrex和strexeq指令

        arm上ldrex和strexeq指令

        作者: 時間:2016-11-10 來源:網絡 收藏
        __raw_spin_lock在ARM處理器上的實現

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

        本文引用地址:http://www.104case.com/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里,并且設置&lock->lock這個內存地址為獨占訪問
        "teq %0, #0n"
        // 測試lock_lock是否為0,影響標志位z
        #ifdef CONFIG_CPU_32v6K
        "wfenen"
        #endif
        "strexeq %0, %2, [%1]n"
        //如果lock_lock是0,并且是獨占訪問這個內存,就向lock->lock里 寫入1,并向tmp返回0,同時清除獨占標記
        "teqeq %0, #0n"
        //如 果lock_lock是0,并且strexeq返回了0,表示加鎖成功,返回
        " bne 1b"
        //如 果上面的條件(1:lock->lock里不為0,2:strexeq失敗)有一個符合,就在原地打轉
        : "=&r" (tmp) //%0:輸出放在tmp里,可以是任意寄存器
        : "r" (&lock->lock), "r" (1)
        //%1:取&lock->lock放在任意寄存 器,%2:任意寄存器放入1
        : "cc"); //狀態寄存器可能會改變
        smp_mb();
        }

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

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



        關鍵詞: armldrexstrexeq指

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 郸城县| 唐河县| 合山市| 齐河县| 兴化市| 鸡西市| 淮南市| 盘山县| 阳城县| 长武县| 鲜城| 临清市| 陇南市| 得荣县| 鹤岗市| 阳朔县| 竹山县| 济南市| 吉安市| 昌平区| 汉中市| 江北区| 九江县| 饶河县| 成安县| 大兴区| 宜宾市| 仪征市| 扎鲁特旗| 城步| 马鞍山市| 桦川县| 泸定县| 鄂托克旗| 班玛县| 镇宁| 资源县| 道孚县| 阿勒泰市| 遂川县| 枣庄市|