Joe*_*lav 5 c assembly arm atomic interrupt
我想知道是否有可能确保line原子执行,因为它可以由ISR和Main上下文执行.我正在研究ARM9(LPC313x)并使用RealView 4(armcc).
foo() {
..
stack_var = ++volatile_var; // line
..
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找像_atomic_C166,直接汇编代码等任何例程.我宁愿不必禁用中断.
非常感谢你.
不,++volatile_var即使你没有作业,我也不认为你曾经期望成为原子.为此使用适当的原子基元.如果您的编译器没有提供这样的扩展,您可以轻松地在Web上找到简短的内联汇编程序.我认为汇编程序指令是调用ldrex和strex手臂上的原子交换.
编辑:似乎问题中要求的特定处理器类型不实现这些说明.
编辑:以下应该与gcc一起使用,对于另一个编译器,可能需要调整__asm__部件.
inline
size_t arm_ldrex(size_t volatile*ptr) {
size_t ret;
__asm__ volatile ("ldrex %0,[%1]\t@ load exclusive\n"
: "=&r" (ret)
: "r" (ptr)
: "cc", "memory"
);
return ret;
}
inline
_Bool arm_strex(size_t volatile*ptr, size_t val) {
size_t error;
__asm__ volatile ("strex %0,%1,[%2]\t@ store exclusive\n"
: "=&r" (error)
: "r" (val), "r" (ptr)
: "cc", "memory"
);
return !error;
}
inline
size_t atomic_add_fetch(size_t volatile *object, size_t operand) {
for (;;) {
size_t oldval = arm_ldrex(object);
size_t newval = oldval + operand;
if (arm_strex(object, newval)) return newval;
}
}
Run Code Online (Sandbox Code Playgroud)
从快速看,C166 _atomic_宏似乎利用一条指令,在指定数量的指令持续时间内有效地屏蔽中断.没有什么能与ARM体系结构中的内容直接对应.
您当然可以使用swp指令(或RealView工具链中的__swp内在函数)来实现关键部分的锁定.ARM体系结构版本5(包括ARM9处理器)中不存在另一个答案中提到的ldrex/strex. http://infocenter.arm.com/help/topic/com.arm.doc.dui0491c/CJAHDCHB.html和http://infocenter.arm.com/help/topic/com.arm.doc.dui0489c/Chdbbbai.分别是html.
围绕此实现的简单锁定实现(使用RealView工具链)将是:
{
/* Loop until lock acquired */
while (__swp(LOCKED, &lockvar) == LOCKED);
..
/* Critical section */
..
lockvar = UNLOCKED;
}
Run Code Online (Sandbox Code Playgroud)
但是,当主线程持有锁时,这将导致ISR上下文中的死锁.
我认为围绕操作屏蔽中断可能是最不好用的解决方案,但如果您的Main上下文在用户模式下执行,则需要系统调用才能实现.
| 归档时间: |
|
| 查看次数: |
1167 次 |
| 最近记录: |