如何比较和ARM7原子交换? [英] How to compare and swap atomically in ARM7?

查看:541
本文介绍了如何比较和ARM7原子交换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想修改的是通过在RTOS不同的任务和IRQ共享环境的全局变量。因此,我需要修改原子这个变量。
在我目前的实现中,我一直在使用enable_irq / disable_irq功能原子修改声明。

I would like to modify a global variable which is shared by different tasks and IRQ contexts in a RTOS. Therefore I need to modify this variable atomically. In my current implementation, I have been using enable_irq/disable_irq functions to modify the statement atomically.

extern int g_var;

void set_bit_atomic(int mask)
{
    disable_irq();
    g_var |= mask;
    enable_irq();
}

我发现在GCC的 __ sync_bool_compare_and_swap 函数=htt​​p://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/原子Builtins.html相对=nofollow>文档作为原子操作的辅助工具。

I've found the __sync_bool_compare_and_swap function in GCC documentation as a helper for atomic operations.

我目前的工具链是KEIL MDK,我想切换到下图所示的方法,

My current toolchain is KEIL MDK, and I would like to switch to the approach shown below,

void set_bit_atomic(int mask)
{
    volatile int tmp;
    do {
        tmp = g_var;
    } while (!__sync_bool_compare_and_swap(&g_var, tmp, tmp | mask));
}

ARM版本的命令集

我怎么能写 __ sync_bool_compare_and_swap 功能(如内联汇编)?

How can I write __sync_bool_compare_and_swap function in ARMv4 command set(as inline assembly)?

推荐答案

我已经找到了在Linux内核源代码 __ kernel_cmpxchg 功能相似的应用。

I have found a similar implementation for __kernel_cmpxchg function in Linux kernel source.

它已被写入的ARMv5及更早版本,它似乎为ARM7TDMI(ARM版本)工作。

It has been written for ARMv5 and earlier, and It seems to work for ARM7TDMI (ARMv4).

1:      ldr     r3, [r2]        @ load current val
        subs    r3, r3, r0      @ compare with oldval
2:      streq   r1, [r2]        @ store newval if eq
        rsbs    r0, r3, #0      @ set return val and C flag
        bx      lr              @ or "mov pc, lr" if no thumb support

详细信息可以在找到这个链接。

有,我想提醒的两个重要问题,

There are two important issues that I would like to warn,

1 __ kernel_cmpxchg 返回0交换发生时,而 __ sync_bool_compare_and_swap 函数返回true。

1- __kernel_cmpxchg returns 0 when swap occurred, while __sync_bool_compare_and_swap function returns true.

2 - 函数原型是不同的。

2- function prototypes are different.

typedef int (*__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
#define __kernel_cmpxchg ((__kernel_cmpxchg_t)0xffff0fc0)

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

所以我不得不改变如下使用,

Therefore I had to change the usage as below,

void set_bit_atomic(int mask)
{
    volatile int tmp;
    do {
        tmp = g_var;
    } while (my_compare_and_swap(tmp, tmp | mask, &g_var));
}

警告:此code不无内核支持正常工作。请参阅下面的注释。

Caveat: This code does not work properly without kernel support. See the comments below.

这篇关于如何比较和ARM7原子交换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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