【问题标题】:Can I make a variable temporarily volatile?我可以使变量暂时易变吗?
【发布时间】:2014-10-26 04:49:09
【问题描述】:

PSoC 中,可以在内存空间mapped to flash 中声明变量。由于闪存读取比 RAM 读取慢,因此程序将受益于编译器优化 - 允许将值存储在寄存器中或以其他方式缓存。除非修改闪光灯的值。这可以是即时的done,程序员知道发生的确切时刻。这也很少进行(以保护闪存免受写入磨损)并且需要相对较长的时间。在这种写入的情况下,最好让变量从底层内存中恢复其值(表现得像 volatile),然后像往常一样继续进行所有优化,直到下一次写入。

因此,从本质上讲,一些通过使用底层存储单元来强制刷新变量的机制是有用的;无论是时间限制(写入后不久)还是代码的某些部分(写入操作后跳转到“刷新”功能)。 C中是否有这样的机制,或者特别是在GCC中?

(此外,考虑到内存限制(2-4KB RAM),如果将 RAM/寄存器的分配留给优化器是可取的 - 将每个变量镜像到两个持久版本中的简单方法:易失性(在闪存中)和非-volatile(在 RAM 中),在刷新期间将 volatile 重写为 non-volatile,然后从那时起在任何地方都使用 non-volatile。)

【问题讨论】:

    标签: c gcc optimization volatile


    【解决方案1】:

    您应该通过在 RAM 中显式维护一个变量来自己进行缓存。 CPU 经常没有可用的寄存器,编译器也不会使用堆栈来缓存全局。

    您可以尝试将变量声明为非易失性,然后通过易失性指针访问它,例如通过* (volatile int *) & foo。就个人而言,我会称之为灾难的秘诀。它可能不会更新foo 的“缓存”值。

    做相反的事情并声明它volatile 但用指针删除限定符,会产生未定义的行为。编译器可能无论如何都不会提升对寄存器的指针取消引用。

    【讨论】:

    • 我想知道如果我明确重写它是否会更新非易失性foofoo = * (volatile int *) & foo;
    • @SF。是的,这应该可行,但反过来:* (volatile int *) & foo = foo;,因为您需要保证写入,而不是读取。剩下的一个问题是,即使没有volatile,更新频率仍然可能足以耗尽 Flash 单元。
    • 不是真的;要写入闪存,您需要跳过一些环节(使用一些专用功能重写底层闪存);通常您将这些创建为volatile const。只是为了使它们成为非常量,但在闪存中,您需要应用一些 __attribute()__ 魔法。如果您只是写入变量,则写入不会真正发生,它只是用底层闪存发生的情况更新其缓存值。
    【解决方案2】:

    您可以尝试使用两个变量:

    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 镜像变量。
    猜你喜欢
    • 1970-01-01
    • 2019-12-13
    • 2023-03-26
    • 2019-02-14
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多