Assembly ARM Cortex-M4互斥锁。DMB指令

Assembly ARM Cortex-M4互斥锁。DMB指令,assembly,arm,mutex,semaphore,Assembly,Arm,Mutex,Semaphore,我读了以下文件:用手臂 第7.2节显示了获取互斥/信号量的代码 Loop LDREX R5, [R1] ; read lock CMP R5, #0 ; check if 0 STREXEQ R5, R0, [R1] ; attempt to store new value CMPEQ R5, #0 ; test if store suceeded BNE Loop ; retry if not DMB LDREX指令请求对内存地址进行独占访问。只有当处理器

我读了以下文件:用手臂

第7.2节显示了获取互斥/信号量的代码

Loop
   LDREX R5, [R1] ; read lock
   CMP R5, #0 ; check if 0
   STREXEQ R5, R0, [R1] ; attempt to store new value
   CMPEQ R5, #0 ; test if store suceeded
   BNE Loop ; retry if not
   DMB
LDREX指令请求对内存地址进行独占访问。只有当处理器具有独占访问权限时,使用STREX的写入才会成功。 它们使用DMB指令来确保独占写入同步到所有处理器

我有一个小问题。假设处理器以独占方式访问内存地址并锁定它。STREX指令完成后,将删除独占访问。从现在起,其他处理器可以访问此内存。但是,在DMB完成之前,写操作仍在处理器的缓存中。如果另一个处理器试图获取对锁的访问权限,而第一个处理器已经锁定了锁,但它尚未同步到RAM,会发生什么情况。内存地址未以独占方式锁定到第一个处理器,但写入未完成


谁能解释一下,为什么这样做是安全的。我对此有意见。

我认为你把事情复杂化了。查看amba/axi规范(以及您在哪里找到多核cortex-m4?)。ldrex/strex用于在多处理器芯片中跨处理器共享资源。一段时间以来,它们一直被错误地用于其他用途。不幸的是,ARM在正确记录所有这些方面做得非常糟糕

ldr的唯一部分是processorid和地址(范围)保存在一个表中。当strex发生时,将检查该地址(范围)的processorid是否与EXOKAY匹配,如果不合适,则执行存储。Strex没有清除任何内容,有趣的是,他们有这个clrex指令,我假设它将processorid设置为某个不会命中的值,或者根据他们构建表的方式释放一个表条目

我可能会在写完这篇文章后尝试,但你也可以很容易地在ldrex然后strex然后strex上尝试,相当肯定我在全尺寸手臂上做过int,将在cortex-m4 ldrex上尝试,strex,strex,clrex,strex,看看会发生什么

在单处理器系统中,ldrex/strex预期在ARM逻辑中工作,但不需要芯片供应商支持,可能只是返回OK(而不是EXOKAY)。L1当然也可能是L2是arm逻辑,超出了芯片供应商的范围。(cortex ms是否有l2?)。通常情况下,您不必担心会碰到芯片供应商代码,您可以运行很长时间(如果不是无限期的话),而不知道这些,因为您将保留在其中一个缓存中。例如,在Linux中禁用这两个缓存是一个非常重要的问题,它们可能会使它看起来像是一个编译时选项,但深入研究,看看实际情况。如果只有一个处理器,如何获得不同的处理器id

在多处理器芯片中,芯片供应商应该在缓存之外正确地支持它,如果您甚至可以通过独占访问、ldrex/strex的正常使用方式到达缓存,那么您最有可能在一级缓存中,并且永远不会接触到芯片供应商提供的内容,但是,如果你在这段时间被打断,你很可能会被L2解救出来,这种情况就会发生。在这种情况下,芯片中有多个processorid是有意义的,因为有多个处理器

这很好

Cortex-M4处理器实现本地专用监视器。这个 处理器内的本地监视器已构造为 不包含任何物理地址,而是将任何访问视为 与前一个LDREX的地址匹配。这意味着 实现的独占保留颗粒是整个内存 地址范围

m7 trm也说了同样的话

没有多个核心,一个怎么可能/会生成不同的ID? 文档使用术语processorid来表示正在使用哪个处理器。cortex-m中有多少个处理器?也许其他地方用不同的字符串/名称记录了它,但此时我不知道cortex-m中的processorid是如何生成的,作为一个单处理器是否不止一个?我无法确定是否可以访问核心

<> p>因此,尽管逻辑不支持每个地址独占访问,但他们并没有说他们没有检查PosialID,而是简单地考虑所有被标记为共享的内存的Strux访问,以与其地址无关的最后一个LDERX的Surror ID进行检查。 编辑

生产

00000001 
00000001 
00000001 
00000600 <-- ldrex
00000000 <-- strex pass
00000001 <-- strex fail
00000001 
00006666 
00000000 
00000001 
00006666 
00007777 
00000800 
AABBCCDD 
00006666 
00000001 
00006666 
打开数据缓存不会改变结果

测试功能:

.thumb_func
.globl LDREX
LDREX:
    ldrex r0,[r0]
    bx lr

.thumb_func
.globl CLREX
CLREX:
    clrex
    bx lr

.thumb_func
.globl STREX
STREX:
    strex r0,r1,[r0]
    bx lr
与“老大哥武器”不同:

CLREX();
hexstring(STREX(0x20000600,0x12345678));
hexstring(LDREX(0x20000600));
hexstring(STREX(0x20000600,0x6666));
hexstring(LDREX(0x20000600));
PUT32(0x20000600,0x11);
hexstring(STREX(0x20000600,0x6666));

00000001 
00000600 
00000000 
00006666 
00000000 
strex在这两者之间的非独占访问中幸存下来,至少根据您发布的文档,非独占存储应该会破坏先前的ldrex(在armv7-a上)


注:上述内容在cortex-m4 r0p1 CPUID 0x410FC241上,它是安全的,因为芯片设计者使其安全。整个指令要点将由操作系统用于语义电话和互斥命令。在多核/多处理器环境中,除了通过内置的汇编命令外,没有其他方法可以准确地实现此功能。

DMB
通过使内存访问在内存层次结构的各个点(即缓存)可见来对内存访问进行排序。缓存一致性机制是允许处理器窥探另一个缓存所必需的,否则,您假设的情况很可能会发生。ARM缓存是一致的。此外,没有选项的
DMB
将执行完整的系统同步,我不知道这意味着什么,但我可能会写入内存。
DMB
对于读修改写的原子性来说是不必要的。
DMB
确保其他内存操作与RMW操作有关。DMB将推动加载和存储,让它们完成,以便其他人看到……“确保所有观察者在观察任何后续加载或存储之前都能观察到锁的成功申领。”JU
.thumb_func
.globl LDREX
LDREX:
    ldrex r0,[r0]
    bx lr

.thumb_func
.globl CLREX
CLREX:
    clrex
    bx lr

.thumb_func
.globl STREX
STREX:
    strex r0,r1,[r0]
    bx lr
CLREX();
hexstring(STREX(0x20000600,0x12345678));
hexstring(LDREX(0x20000600));
hexstring(STREX(0x20000600,0x6666));
hexstring(LDREX(0x20000600));
PUT32(0x20000600,0x11);
hexstring(STREX(0x20000600,0x6666));

00000001 
00000600 
00000000 
00006666 
00000000