ARM 中的关键部分 [英] Critical sections in ARM

查看:29
本文介绍了ARM 中的关键部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 AVR 系列处理器上实现临界区方面经验丰富,您所做的只是禁用中断(当然有内存屏障),执行关键操作,然后重新启用中断:

I am experienced in implementing critical sections on the AVR family of processors, where all you do is disable interrupts (with a memory barrier of course), do the critical operation, and then reenable interrupts:

void my_critical_function()
{
   cli();  //Disable interrupts
   // Mission critical code here
   sei();  //Enable interrupts
}

现在我的问题是:

这个简单的方法是否也适用于处理器的ARM架构?我听说过关于处理器在指令上进行前瞻和其他黑魔法的事情,主要想知道这些类型的事情是否会对临界区的这种实现造成问题.

Does this simple method apply to the ARM architecture of processor as well? I have heard things about the processor doing lookahead on the instructions, and other black magic, and was wondering primarily if these types of things could be problematic to this implementation of critical sections.

推荐答案

假设您使用的是 Cortex-M 处理器,请查看 LDREXSTREX指令,可通过 CMSIS(Cortex 微控制器软件接口标准)提供的 __LDREXW()__STREXW() 宏在 C 中使用.它们可用于构建极其轻量级的互斥机制.

Assuming you're on a Cortex-M processor, take a look at the LDREX and STREX instructions, which are available in C via the __LDREXW() and __STREXW() macros provided by CMSIS (the Cortex Microcontroller Software Interface Standard). They can be used to build extremely lightweight mutual exclusion mechanisms.

基本上,

data = __LDREXW(address)

的工作方式与 data = *address 类似,只是它在 CPU 中设置了一个独占访问标志".处理完数据后,使用

works like data = *address except that it sets an 'exclusive access flag' in the CPU. When you've finished manipulating your data, write it back using

success = __STREXW(address, data)

类似于 *address = data 但只有在独占访问标志仍然设置时才会成功写入.如果它确实写入成功,那么它也会清除标志.成功时返回 0,失败时返回 1.如果 STREX 失败,你必须回到 LDREX 并重试.

which is like *address = data but will only succeed in writing if the exclusive access flag is still set. If it does succeed in writing then it also clears the flag. It returns 0 on success and 1 on failure. If the STREX fails, you have to go back to the LDREX and try again.

对于共享变量的简单独占访问,不需要其他任何东西.例如:

For simple exclusive access to a shared variable, nothing else is required. For example:

do {
  data = LDREX(address);
  data++;
} while (STREXW(address, data));

这种机制的有趣之处在于它实际上是后到先得";如果这段代码被中断并且中断使用了LDREXSTREXSTREX 中断将会成功并且(低优先级的)用户代码将有重试.

The interesting thing about this mechanism is that it's effectively 'last come, first served'; if this code is interrupted and the interrupt uses LDREX and STREX, the STREX interrupt will succeed and the (lower-priority) user code will have to retry.

如果您使用的是操作系统,则可以使用相同的原语来构建正确的"信号量和互斥体(请参阅 本应用笔记,例如);但话说回来,如果您使用的是操作系统,您可能已经可以通过其 API 访问互斥锁了!

If you're using an operating system, the same primitives can be used to build 'proper' semaphores and mutexes (see this application note, for example); but then again if you're using an OS you probably already have access to mutexes through its API!

这篇关于ARM 中的关键部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆