[英]Using memcpy and friends with memory-mapped I/O
I'm working on an embedded project which involves I/O on memory-mapped FPGA registers. 我正在研究一个涉及内存映射FPGA寄存器的I / O的嵌入式项目。 Pointers to these memory regions need to be marked
volatile
so the compiler does not "optimize out" reads and writes to the FPGA by caching values in CPU registers. 这些存储区域的指针需要标记为
volatile
因此编译器不会通过缓存CPU寄存器中的值来“优化”对FPGA的读写操作。
In a few cases, we want to copy a series of FPGA registers into a buffer for further use. 在少数情况下,我们希望将一系列FPGA寄存器复制到缓冲区中以供进一步使用。 Since the registers are mapped to contiguous addresses,
memcpy
seems appropriate, but passing our volatile
pointer as the source argument gives a warning about discarding the volatile
qualifier. 由于寄存器映射到连续的地址,
memcpy
似乎是合适的,但是传递我们的volatile
指针作为source参数会发出关于丢弃volatile
限定符的警告。
Is it safe (and sane) to cast away the volatile
-ness of the pointer to suppress this warning? 是否安全(并且理智)抛弃指针的
volatile
以抑制此警告? Unless the compiler does something magical, I can't imagine a scenario where calling memcpy
would fail to perform an actual copy. 除非编译器做了一些神奇的事情,否则我无法想象调用
memcpy
会无法执行实际复制的情况。 The alternative is to just use a for
loop and copy byte by byte, but memcpy
implementations can (and do) optimize the copy based on size of the copy, alignment, etc. 另一种方法是只使用
for
循环并逐字节复制,但memcpy
实现可以(并且确实)根据副本的大小,对齐等来优化副本。
As a developer of both: FPGA and embedded software, there is just one clear answer: do not use memcpy
et al. 作为FPGA和嵌入式软件的开发人员,只有一个明确的答案: 不要使用
memcpy
等。 for this 为了这
Some reasons: 一些原因:
memcpy
does not guarantee that. memcpy
不保证。 You can, however, use a simple for
loop and copy yourself. 但是,您可以使用简单的
for
循环并自行复制。 This is safe, if the registers are volatile
( see below ). 如果寄存器是
volatile
,这是安全的( 见下文 )。
Depending on your platform, volatile
alone might not be sufficient. 根据您的平台,单独使用
volatile
可能还不够。 The memory area has also to be non-cachable and strictily ordered (and - possibly - non-shared). 内存区域也必须是不可 缓存且严格排序的 (并且可能是非共享的)。 Otherwise the system busses might (and will for some platforms) reorder accesses.
否则,系统总线可能(并且将针对某些平台)重新排序访问。
Furthermore, you might need barriers/fences for your CPU not to reorder accesses. 此外,您可能需要CPU的障碍/围栏不要重新排序访问。 Please read your hardware-specs very carefully about this.
请仔细阅读您的硬件规格。
If you need to transfer larger blocks more often, think about using DMA. 如果您需要更频繁地传输更大的块,请考虑使用DMA。 If the FPGA uses PCI(e), you could use busmaster DMA with scatter/gather for instance (however, this is not easily implemented; did that myself, but might be worth the effort).
如果FPGA使用PCI(e),你可以使用带有分散/聚集的busmaster DMA(但是,这不容易实现;自己这样做,但可能值得付出努力)。
The best (and most sane) approach depends actually on multiple factors, like platform, required speed, etc. Of all possible approaches, I would deem using mempcy()
one of the lesser sane(1) at best (1): not sure if that is correct grammar, but I hope you got my point). 最好的(也是最理智的)方法实际上取决于多种因素,例如平台,要求的速度等。在所有可能的方法中,我认为使用
mempcy()
一个(1)(1):不确定如果这是正确的语法,但我希望你得到我的观点)。
Absolutely not safe. 绝对不安全。 There is no guarantee whatsoever in which order memcpy will copy the data, and how many bytes are copied at a time.
无法保证memcpy将复制数据的顺序,以及一次复制多少字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.