使用Cortex M3和M4的LDREX/STREX技术问题

3
我正在学习LDREX和STREX来实现互斥锁。从阅读ARM参考手册得知:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100166_0001_00_en/ric1417175928887.html

看起来LDREX/STREX只能以整个内存空间为粒度存储地址,因此您只能在最多一个32位寄存器上使用LDREX/STREX。

这是正确的吗?如果是这样的话,LDREX/STREX的功能就变得非常有限了。我的意思是,您可以做一个位图互斥锁,可能会获得32个互斥锁。

有人在M3或M4上使用LDREX/STREX吗?如果是这样,他们如何使用它?


无论保留粒度如何,每个处理器核心同一时间只能进行一个ldrex/strex链。关键是在ldrexstrex之间不能有其他内存访问,即使是对完全不同的地址也不行。 - EOF
@old_timer,我没有看到任何支持你的说法的内容:“LDREX/STREX的目的是在多处理器解决方案中共享资源。它们已经被错误地用于单核微控制器中很长时间了。” 我所看到的所有内容都表明,该功能旨在用于单个和多个处理器环境中的共享资源。如果您有参考资料,请随意提供,否则我建议其他读者将其视为您的观点,而不一定是事实。 - biscuits
请参考ARM的相关文档:“这些指令在单主系统上实现互斥锁、信号量等功能时非常有用,而无需禁用中断。同样,在多线程系统中也非常有用。” http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka4175.html - biscuits
@biscuits 取决于核心/总线规范的版本,当创建时明确记录了单处理器实现不需要支持独占访问。这基本上意味着它们是为多处理器实现而设计的。当时,swp正在逐步淘汰。不幸的是,在像Linux这样的地方错误使用(经常出错,您不断需要修复和移植到另一芯片),这可能已经改变,在更近期的规范中,因此您必须具体了解哪个核心,以及因此哪个总线规范... - old_timer
它继续说明,从属程序不必支持独占访问并可以返回OKAY。这将破坏不理解ldrex/strex工作原理以及何时何地可以使用它们的代码。 - old_timer
显示剩余12条评论
1个回答

10
我联系了ARM获取了更多信息。例如,如果你这样做,LDREX/STREX将失败:
LDREX 地址1
LDREX 地址2
STREX 地址1
即使最后一个LDREX不是针对地址1的,STREX到地址1仍然会通过。这是正确的,因为LDREX/STREX地址解析是整个内存空间。
所以我担心如果你有两个任务:第一个在第一个LDREX之后被中断,然后第二个任务在第二个LDREX到地址2之后被中断,然后第一个任务重新获取处理器并尝试STREX,它会引起问题。然而,似乎ARM在每次异常/中断进入和退出时都会发出CLREX。因此,STREX将失败,因为任务必须被中断抢占。也就是说,如果在LDREX和STREX之间发生任何中断,STREX将失败。因此,你希望尽可能减少LDREX和STREX之间的代码长度,以降低中断的机会。此外,如果STREX失败,你很可能要在放弃之前再尝试一两次LDREX/STREX过程。
同样,这适用于单核M3/M4/M7。
请注意,我发现CLREX被清除的参考资料只在ArmV7-M架构参考手册的A3.4.4上下文切换支持部分中找到。这份文件比我在网上找到的任何文件都要好,描述了LDREX/STREX的实际工作方式。

1
+1,感谢您澄清CLREX(或等效物)在异常进入和退出时会自动调用。这与我在M4上实际看到的情况相符,但在找到您的答案之前,我找不到任何其他证实该行为的文档。 - John Lindgren
Cortex-M7文档中提到:本地独占访问监视器在异常边界上会自动清除。https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Instruction-Set/Memory-access-instructions/CLREX - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接