Can I make a variable temporarily volatile?

3
PSoC中,一个人可以在映射到闪存的内存空间中声明变量。由于闪存读取速度比RAM读取速度慢,因此程序将受益于编译器优化——允许将值存储在寄存器中或以其他方式缓存。除非修改闪存的值。这可以在运行时完成,程序员知道发生的确切时刻。这也相对很少(为了保护闪存免受写入磨损),并且需要相对较长的时间。在这种写入情况下,如果变量能够从底层内存中恢复其值(像volatile一样行为),然后像通常一样进行所有优化,直到下一次写入,那么就很好了。
因此,本质上,通过使用其基础内存单元强制刷新变量的某种机制将是有用的;无论是限制时间(在写入后不久)还是针对某些代码段(在写入操作后跳转到“刷新”函数)。在C中是否存在任何这样的机制,或者在GCC中是否存在?
(另外,考虑到内存限制(2-4KB RAM),如果将RAM/寄存器的分配留给优化器,则会更加理想 - 将每个变量镜像成两个持久版本:易失性(在Flash中)和非易失性(在RAM中),在刷新期间将易失性重写为非易失性,然后从那时起在所有地方使用非易失性将是相当浪费的。)
2个回答

2
你需要通过显式地在RAM中维护变量来进行缓存。CPU经常没有可用的寄存器,编译器也不会使用堆栈来缓存全局变量。
你可以尝试声明变量为非易失性,然后通过一个易失性指针访问它,例如通过* (volatile int *) & foo。个人认为,这可能会导致灾难性后果。它很可能不会更新foo的“缓存”值。
反过来,声明为volatile但移除指针限定符,则会产生未定义的行为。编译器也不太可能将指针解引用提升到寄存器中。

我想知道如果我明确重写它,是否会更新非易失性的 foofoo = * (volatile int *) & foo; - SF.
@SF。是的,那应该可以工作,但反过来:*(volatile int*)&foo = foo;,因为您需要确保写入而不是读取。 一个未解决的问题是,即使没有 volatile,更新仍可能频繁到足以磨损闪存单元。 - Potatoswatter
不是很准确;要写入闪存,您需要跳过一些障碍(使用一些专用函数重写底层闪存);通常您将它们创建为volatile const。只是为了使它们在闪存中变为非const,您需要应用一些__attribute()__魔法。如果您只是写入变量,则不会真正发生写入,它只是更新其缓存值以反映底层闪存的情况。 - SF.

0
你可以尝试使用两个变量:
int foo;
volatile int foo_vol;

在大部分程序中使用foo,但当进行写操作时,将foo_vol赋值给foo

if (there_was_a_write)
    foo = foo_vol;
process_data(&foo, bar);

这将导致foo获得优化,但它仍然可以使用新值。我不确定这种方法是否适用于您的特定设置,但无论如何祝你好运。


正如上一段所述 - 是的,它可以工作,但这将是浪费的,因为只有2KB的RAM可用来镜像变量。 - SF.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接