我在AVR处理器系列的关键部分上有丰富的经验,您要做的就是禁用中断(当然具有内存屏障),执行关键操作,然后重新启用中断:
void my_critical_function()
{
cli(); //Disable interrupts
// Mission critical code here
sei(); //Enable interrupts
}
现在我的问题是这个
这个简单的方法也适用于处理器的ARM体系结构吗?我已经听说过有关处理器在指令上进行前瞻性处理的事情,以及其他不可思议的事情,并且主要是想知道这些类型的事情是否可能对关键部分的实现造成问题。
答案 0 :(得分:10)
假设您使用的是Cortex-M处理器,请查看LDREX
和STREX
指令,它们在C中可以通过__LDREXW()
和__STREXW()
获得CMSIS(Cortex微控制器软件接口标准)提供的宏。它们可用于构建极其轻量级的互斥机制。
基本上
data = __LDREXW(address)
的工作方式与data = *address
相似,只是它在CPU中设置了“独占访问标志”。完成数据处理后,请使用
success = __STREXW(address, data)
,类似于*address = data
,但是只有在仍设置排他访问标志的情况下,写入操作才会成功。如果确实写入成功,那么还将清除该标志。成功返回0,失败返回1。如果STREX
失败,则必须返回LDREX
并重试。
对于共享变量的简单互斥访问,不需要任何其他操作。例如:
do {
data = LDREX(address);
data++;
} while (STREXW(address, data));
关于此机制的有趣之处在于,它实际上是“先到先得”。如果此代码被中断,并且中断使用LDREX
和STREX
,则STREX
中断将成功执行,并且(低优先级)用户代码将必须重试。
如果您使用的是操作系统,则可以使用相同的原语来构建“适当的”信号灯和互斥锁(例如,参见this application note);但是如果您使用的是操作系统,那么您可能已经可以通过其API访问互斥锁了!
答案 1 :(得分:4)
ARM体系结构非常广泛,据我了解,您可能是指ARM Cortex M微控制器。
您可以使用此技术,但是许多ARM uC提供的功能更多。据我所知,实际的硬件是什么,我只能举几个例子:
等等等