且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

çvolatile变量与高速缓存

更新时间:2022-03-27 22:43:22

固件开发人员在这里。这是嵌入式编程标准的问题,一个旅行了许多(甚至是非常有经验)的开发。

Firmware developer here. This is a standard problem in embedded programming, and one that trips up many (even very experienced) developers.

我的假设是,您试图访问硬件寄存器,而寄存器的值可随时间变化(无论是中断状态,定时器,GPIO迹象,等等)。

My assumption is that you are attempting to access a hardware register, and that register value can change over time (be it interrupt status, timer, GPIO indications, etc.).

挥发性参数仅解决方案的一部分,并且在许多情况下,可能没有必要。这将导致从被重新读出的变量的存储器的每次使用(而不是由编译器被优化了或存储在多个用途一个寄存器),但时间是否在 记忆的读取是一个实际的硬件寄存器与缓存的位置是未知到code和影响由挥发性关键字。如果你的函数只读取寄存器一次,然后你可以或许离开了挥发性,但作为一般规则,我会建议,大多数硬件寄存器应该被定义为挥发性

The volatile keyword is only part of the solution, and in many cases may not be necessary. This causes the variable to be re-read from memory each time it is used (as opposed to being optimized out by the compiler or stored in a processor register across multiple uses), but whether the "memory" being read is an actual hardware register versus a cached location is unknown to your code and unaffected by the volatile keyword. If your function only reads the register once then you can probably leave off volatile, but as a general rule I will suggest that most hardware registers should be defined as volatile.

更大的问题是缓存和高速缓存一致性。这里最简单的方法是,以确保您的注册是未缓存地址空间。这意味着每次访问你保证读/写实际的硬件寄存器,而不是高速缓冲存储器的注册时间。一个更复杂的,但可能效果更好的办法是使用缓存的地址空间,让你的code手动强制为这样的特殊情况下缓存更新。对于这两种方法,这是怎么实现的是体系结构相关的,超出了问题的范围。这可能涉及MTRRs(用于x86),MMU,页表的修改等。

The bigger issue is caching and cache coherency. The easiest approach here is to make sure your register is in uncached address space. That means every time you access the register you are guaranteed to read/write the actual hardware register and not cache memory. A more complex but potentially better performing approach is to use cached address space and have your code manually force cache updates for specific situations like this. For both approaches, how this is accomplished is architecture-dependent and beyond the scope of the question. It could involve MTRRs (for x86), MMU, page table modifications, etc.

希望有所帮助。如果我错过了一些东西,让我知道,我会扩大我的答案。

Hope that helps. If I've missed something, let me know and I'll expand my answer.