ARM命令LDREX和STREX实现spinlock

发布者:梦幻微笑最新更新时间:2020-01-19 来源: eefocus关键字:ARM命令  LDREX  STREX  spinlock 手机看文章 扫描二维码
随时随地手机看文章

在 include/asm-arm/spinlock.h 下有這麼一段

#if __LINUX_ARM_ARCH__ < 6
#error SMP not supported on pre-ARMv6 CPUs
#endif

好啦,前提就是:只有 ARM core 版本 >=6 才可以繼續:

all spin lock primitives 到最後都是使用下面這個基本型: 

static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
    unsigned long tmp;

1      __asm__ __volatile__(
2"1:    ldrex    %0, [%1]n"
3"    teq    %0, #0n"
4"    strexeq    %0, %2, [%1]n"
5"    teqeq    %0, #0n"
6"    bne    1b"
7   : "=&r" (tmp)
8  : "r" (&lock->lock), "r" (1)
9 : "cc");

    smp_mb();
}

[指令重點]:

ldrex 指令是 core 6 以後才有的,跟 strex 配成一對指令,可以請 bus 監控從 ldrex 到 strex 之間有無其他的 CPU 或 DMA 來存取這個位址 ,若有的話,strex 會在第一個 register 裡設定值為 1(non-exclusive by this CPU) 並且令 store 動作失敗,若沒有,strex 會在第一個 register 裡設定值為 0(exclusive access by this CPU) 並且令 store 動作成功。

Code Trace Discussion: 

Line 1: __volatile__ 告訴 compiler ,不要對這塊 assembly template 做最佳化動作,因為我們裡面有 loop 讀取 memory 動作,最佳化的結果可能導致 compiler 用一個 register 來 cache 它的值,不會老老實實的去讀 memory... 呵呵,這不是我們想要的動作喔!

Line 2: 把 lock 讀到 tmp,並請 bus monitor 這個 memory

Line 3: 測試 lock 是否為 0,若非 0,表示 lock 已經被別人取得了,則 Line 4,5 都不做了,然後  Line 6 一定 branch,做 spin 的動作。若為 0,表示有機會取得 lock,繼續做 Line 4.5. 

Line 4: 重點來了!,核對 bus monitor 的結果,若是exclusive access 則 tmp 設為 0 並且把 1 儲存到 lock,若是 non-exclusive access(有其他 CPU 來動過) 則 tmp設為 1並且不做儲存 lock 的動作。

Line 5: 測試 tmp

Line 6: 若 tmp 為 0 表示剛剛對 lock 動作是 exclusive,可以離開迴圈,若 tmp 為 1,則做 spin 動作。

Line 7: tmp 用 register 來操作,同時是 input 及 output 令它為 %0

Line 8: &lock->lock 用 register 來操作 ,令它為 %1,值 1 用用 register 來操作 ,令它為 %2

Line 9: 此 template 會改到 condition code,加入 clobber list 以告訴 compiler 有這回事

好了,終於看完了,真的很佩服那些 coding 的 kernel hackers ....

思考問題: ARM v6 以前有個  SWP 指令可以 lock bus and swap memory ,一樣可以用來完成 exclusive access ,但是比起 ldrex,strex 這對指令有什麼缺點呢?

ANS: 用滑鼠反白下幾行

关键字:ARM命令  LDREX  STREX  spinlock 引用地址:ARM命令LDREX和STREX实现spinlock

上一篇:ARM用户层发生异常后软硬件协同处理流程
下一篇:ARM linux内核在内存中的布局

推荐阅读最新更新时间:2024-11-07 09:20

openocd 命令行烧写ARM裸机程序 problems and solutions
摘要: 以前是用RVDS 的IDE来烧写调试ARM程序的,不过RVDS虽然是集成化的调试工具调试起来方便,但是有的时候只知其一,不知其二,只知道按部就班的来点击按钮,忽略了一些本质性的东西。而且RVDS还有一个不好的地方是它只能在windows平台下运行,不支持Linux OS。为了便于学习Linux,使用Openocd会是个不错的选择,可以学习gnu 汇编,Makefile编写,工具链命令行使用。 如果这些命令搞熟悉了,你还可以利用Qt 来做个自己的图形化界面烧写调试工具。(不过这只是个壳子而已,精髓在于openocd ,所以如果有时间你还可以分析一下Openocd的源码,因为它是开源的,开源的东西就是好,它可以满足你的好奇心
[单片机]
openocd <font color='red'>命令</font>行烧写<font color='red'>ARM</font>裸机程序 problems and solutions
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved