繁体   English   中英

使用内存映射I / O的memcpy和朋友

[英]Using memcpy and friends with memory-mapped I/O

我正在研究一个涉及内存映射FPGA寄存器的I / O的嵌入式项目。 这些存储区域的指针需要标记为volatile因此编译器不会通过缓存CPU寄存器中的值来“优化”对FPGA的读写操作。

在少数情况下,我们希望将一系列FPGA寄存器复制到缓冲区中以供进一步使用。 由于寄存器映射到连续的地址, memcpy似乎是合适的,但是传递我们的volatile指针作为source参数会发出关于丢弃volatile限定符的警告。

是否安全(并且理智)抛弃指针的volatile以抑制此警告? 除非编译器做了一些神奇的事情,否则我无法想象调用memcpy会无法执行实际复制的情况。 另一种方法是只使用for循环并逐字节复制,但memcpy实现可以(并且确实)根据副本的大小,对齐等来优化副本。

作为FPGA和嵌入式软件的开发人员,只有一个明确的答案: 不要使用memcpy等。 为了这

一些原因:

  • 无法保证memcpy可以按任何特定顺序运行。
  • 编译器可能会使用内联代码替换调用。
  • 这种接受通常需要一定的字大小。 memcpy不保证。
  • 寄存器映射中的间隙可能导致未定义的行为。

但是,您可以使用简单的for循环并自行复制。 如果寄存器是volatile ,这是安全的( 见下文 )。

根据您的平台,单独使用volatile可能还不够。 内存区域也必须是不可 缓存严格排序的 (并且可能是非共享的)。 否则,系统总线可能(并且将针对某些平台)重新排序访问。

此外,您可能需要CPU的障碍/围栏不要重新排序访问。 请仔细阅读您的硬件规格。

如果您需要更频繁地传输更大的块,请考虑使用DMA。 如果FPGA使用PCI(e),你可以使用带有分散/聚集的busmaster DMA(但是,这不容易实现;自己这样做,但可能值得付出努力)。

最好的(也是最理智的)方法实际上取决于多种因素,例如平台,要求的速度等。在所有可能的方法中,我认为使用mempcy()一个(1)(1):不确定如果这是正确的语法,但我希望你得到我的观点)。

绝对不安全。 无法保证memcpy将复制数据的顺序,以及一次复制多少字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM