仅在 ISR 中读取的变量的易失性?
volatile for variable that is only read in ISR?
对于在主循环中读写但在 ISR 中只读的变量是否需要 volatile
?
编辑:在写入 main 时,ISR 被禁用。因此,变量被有效地原子使用。
编辑:(非常相关):
Is volatile needed for a variable that is read&write in main loop, but read-only in ISR?
volatile
不是这里的问题,只要确保 main
循环的写入不会被分解即可。
在没有 ISR 调用保护的情况下 main()
中的任何更改都可能导致问题,volatile
或没有。声明它 volatile
不会保存该问题的代码。
volatile some_type obj;
void ISR() {
foo(obj);
}
int main() {
for (;;) {
// volatile useful here to prevent the assignment from being optimized away.
some_type tmp = bar();
// protect from potential interruption need here.
// Without protection, ISR(),
// doesn't know it is working with a completely written `obj`
obj = tmp;
// release from potential interruption
}
volatile
在两个方向上都有用,因为 main()
知道 ISR()
可能已经改变 obj
并且 main()
不优化离开分配。
但由于ISR()
不会改变obj
,所以不需要volatile
。
声明 obj
atomic
可能会有所帮助 - 但这是另一个问题。
volatile
是一种糟糕的同步访问方式。这是一个优化障碍,但仅此而已。
它不是原子的;例如当您的 some_type
在没有本机 64 位数据类型的平台上是 uint64_t
时,可能有一部分是只读的。例如
main() irq()
/* initialization */
var[0..31] = 4
var[32..63] = 8
/* modificatoin */
var[32..63] = 23
/* read */
a_hi = var[32..64] = 32
a_lo = var[0..31] = 4
var[0..31] = 42
根据体系结构,可能需要内存屏障操作。例如。当 main
和 irq
在具有专用缓存的不同内核上运行时,irq
将永远不会看到更新的值
第一个问题需要锁定,但锁定操作通常意味着优化障碍,因此 volatile
是多余的。
同上第二个问题,其中内存屏障也充当优化屏障。
volatile
对于实现对处理器内存的访问很有用(这可能会在两次读取之间发生变化或在写入时产生副作用)。但通常,它是不需要的,而且太贵了。
对于在主循环中读写但在 ISR 中只读的变量是否需要 volatile
?
编辑:在写入 main 时,ISR 被禁用。因此,变量被有效地原子使用。
编辑:(非常相关):
Is volatile needed for a variable that is read&write in main loop, but read-only in ISR?
volatile
不是这里的问题,只要确保 main
循环的写入不会被分解即可。
在没有 ISR 调用保护的情况下 main()
中的任何更改都可能导致问题,volatile
或没有。声明它 volatile
不会保存该问题的代码。
volatile some_type obj;
void ISR() {
foo(obj);
}
int main() {
for (;;) {
// volatile useful here to prevent the assignment from being optimized away.
some_type tmp = bar();
// protect from potential interruption need here.
// Without protection, ISR(),
// doesn't know it is working with a completely written `obj`
obj = tmp;
// release from potential interruption
}
volatile
在两个方向上都有用,因为 main()
知道 ISR()
可能已经改变 obj
并且 main()
不优化离开分配。
但由于ISR()
不会改变obj
,所以不需要volatile
。
声明 obj
atomic
可能会有所帮助 - 但这是另一个问题。
volatile
是一种糟糕的同步访问方式。这是一个优化障碍,但仅此而已。
它不是原子的;例如当您的
some_type
在没有本机 64 位数据类型的平台上是uint64_t
时,可能有一部分是只读的。例如main() irq() /* initialization */ var[0..31] = 4 var[32..63] = 8 /* modificatoin */ var[32..63] = 23 /* read */ a_hi = var[32..64] = 32 a_lo = var[0..31] = 4 var[0..31] = 42
根据体系结构,可能需要内存屏障操作。例如。当
main
和irq
在具有专用缓存的不同内核上运行时,irq
将永远不会看到更新的值
第一个问题需要锁定,但锁定操作通常意味着优化障碍,因此 volatile
是多余的。
同上第二个问题,其中内存屏障也充当优化屏障。
volatile
对于实现对处理器内存的访问很有用(这可能会在两次读取之间发生变化或在写入时产生副作用)。但通常,它是不需要的,而且太贵了。