【发布时间】:2013-08-30 18:51:18
【问题描述】:
我想修改一个由 RTOS 中不同任务和 IRQ 上下文共享的全局变量。因此我需要原子地修改这个变量。 在我当前的实现中,我一直在使用 enable_irq/disable_irq 函数来原子地修改语句。
extern int g_var;
void set_bit_atomic(int mask)
{
disable_irq();
g_var |= mask;
enable_irq();
}
我在 GCC documentation 中找到了 __sync_bool_compare_and_swap 函数作为原子操作的助手。
我目前的工具链是KEIL MDK,我想切换到如下所示的方法,
void set_bit_atomic(int mask)
{
volatile int tmp;
do {
tmp = g_var;
} while (!__sync_bool_compare_and_swap(&g_var, tmp, tmp | mask));
}
如何在 ARMv4 命令集中编写__sync_bool_compare_and_swap 函数(作为内联汇编)?
【问题讨论】:
-
你可以看到 GCC 在汇编中是如何做到的,并通过修改克隆它 (gcc -S file.c)
-
ARM 使用加载链接/存储条件指令来执行原子操作。 (请参阅this question 中的链接。)
-
我不相信会有很大的不同。据我了解,LDREX/STREX 指令需要 ARMV6,这就是 ARM 上“比较和交换”指令对的作用。
-
@Kerrek SB Link 显示 ARMv6 或更高版本的指令集。我正在使用 ARM7TDMI (ARMv4),不幸的是它不支持这些功能。
-
@KerrekSB:据我了解,这对 AMRv4 架构没有帮助。