使用内存映射的 memcpy 和朋友 I/O
Using memcpy and friends with memory-mapped I/O
我正在从事一个嵌入式项目,其中涉及 I/O 内存映射 FPGA 寄存器。指向这些内存区域的指针需要标记为 volatile
,这样编译器就不会 "optimize out" 通过在 CPU 寄存器中缓存值来读取和写入 FPGA。
在少数情况下,我们希望将一系列FPGA寄存器复制到缓冲区中以供进一步使用。由于寄存器映射到连续地址,memcpy
似乎是合适的,但是将我们的 volatile
指针作为源参数传递会给出关于丢弃 volatile
限定符的警告。
放弃指针的 volatile
特性以抑制此警告是否安全(且理智)?除非编译器做了一些神奇的事情,否则我无法想象调用 memcpy
将无法执行实际复制的场景。另一种方法是只使用 for
循环并逐字节复制,但是 memcpy
实现可以(并且确实)根据副本的大小、对齐等优化副本。
绝对不安全。无法保证 memcpy 将以何种顺序复制数据,以及一次复制多少字节。
作为 FPGA 和嵌入式软件两者的开发者,只有一个明确的答案:不要使用 memcpy
等。为此
一些原因:
- 不能保证 memcpy 将以任何特定顺序工作。
- 编译器很可能会用内联代码替换调用。
- 此类访问通常需要一定的字数。
memcpy
不保证。
- 寄存器映射中的间隙可能会导致未定义的行为。
但是,您可以使用简单的 for
循环并自己复制。这是安全的,如果寄存器是 volatile
(见下文)。
根据您的平台,仅 volatile
可能不够。内存区域也必须是 non-cachable 和 strictly ordered (并且 - 可能 - 非共享)。否则,系统总线可能(并且将对某些平台)重新排序访问。
此外,您可能需要 barriers/fences 才能 CPU 不重新排序访问。请仔细阅读您的硬件规格。
如果您需要更频繁地传输更大的块,请考虑使用 DMA。如果 FPGA 使用 PCI(e),您可以将 busmaster DMA 与 scatter/gather 一起使用(但是,这不容易实现;我自己做了,但可能值得付出努力)。
最好(也是最理智)的方法实际上取决于多种因素,例如平台、所需速度等。在所有可能的方法中,我认为使用 mempcy()
较不理智的方法之一 (1)最佳 (1):不确定这是否是正确的语法,但我希望你明白我的意思)。
我正在从事一个嵌入式项目,其中涉及 I/O 内存映射 FPGA 寄存器。指向这些内存区域的指针需要标记为 volatile
,这样编译器就不会 "optimize out" 通过在 CPU 寄存器中缓存值来读取和写入 FPGA。
在少数情况下,我们希望将一系列FPGA寄存器复制到缓冲区中以供进一步使用。由于寄存器映射到连续地址,memcpy
似乎是合适的,但是将我们的 volatile
指针作为源参数传递会给出关于丢弃 volatile
限定符的警告。
放弃指针的 volatile
特性以抑制此警告是否安全(且理智)?除非编译器做了一些神奇的事情,否则我无法想象调用 memcpy
将无法执行实际复制的场景。另一种方法是只使用 for
循环并逐字节复制,但是 memcpy
实现可以(并且确实)根据副本的大小、对齐等优化副本。
绝对不安全。无法保证 memcpy 将以何种顺序复制数据,以及一次复制多少字节。
作为 FPGA 和嵌入式软件两者的开发者,只有一个明确的答案:不要使用 memcpy
等。为此
一些原因:
- 不能保证 memcpy 将以任何特定顺序工作。
- 编译器很可能会用内联代码替换调用。
- 此类访问通常需要一定的字数。
memcpy
不保证。 - 寄存器映射中的间隙可能会导致未定义的行为。
但是,您可以使用简单的 for
循环并自己复制。这是安全的,如果寄存器是 volatile
(见下文)。
根据您的平台,仅 volatile
可能不够。内存区域也必须是 non-cachable 和 strictly ordered (并且 - 可能 - 非共享)。否则,系统总线可能(并且将对某些平台)重新排序访问。
此外,您可能需要 barriers/fences 才能 CPU 不重新排序访问。请仔细阅读您的硬件规格。
如果您需要更频繁地传输更大的块,请考虑使用 DMA。如果 FPGA 使用 PCI(e),您可以将 busmaster DMA 与 scatter/gather 一起使用(但是,这不容易实现;我自己做了,但可能值得付出努力)。
最好(也是最理智)的方法实际上取决于多种因素,例如平台、所需速度等。在所有可能的方法中,我认为使用 mempcy()
较不理智的方法之一 (1)最佳 (1):不确定这是否是正确的语法,但我希望你明白我的意思)。