我通过将数据从290字节的块中的“普通”存储器中复制出来,来周期性地用我的数据填充mmap-ed DMA缓冲区。
在第一个周期memcpy
始终通过OK。在第二个周期,它挂在__memcpy_neon
中(至少这是我每次按Ctrl-C时gdb所说的内容)。
反汇编程序始终显示strmi
指令被卡在其中。
仅出于测试目的,我用简单的字节字节memcpy()
替换了memcpy1()
,并且在所有3MB DMA缓冲区上一切正常(但显然速度较慢... :-)。为了排除对齐问题,我测试了库memcpy()
以复制未对齐的缓冲区-未检测到问题。
我在linux 2.6.37
CPU上将glibc 2.23 (gcc 6.3.1 linaro)
与DM8148
一起使用。
为什么此memcpy挂起,尤其是第二次挂起?
更新:经过多次针对memcpy的不同汇编程序变体的实验,我可以说挂起的是带有和不带有预加载的NEON内存复制指令:
Loop:
PLD [r1, #0xC0]
VLDM r1!,{d0-d7}
VSTM r0!,{d0-d7}
SUBS r2,r2,#0x40
BNE Loop
memcpy()的所有其他“正常”变体都可以正常工作。 使用带有NEON指令的DMA未缓存(!)映射内存有什么奥秘吗?
答案 0 :(得分:0)
好吧,答案似乎是“是的!使用带有NEON指令的DMA uncached(!)mmaped内存有很多奥秘”。正如ARM手册所述,“ Cortex A8支持未对齐的内存访问。但是,不支持对强排序内存的未对齐访问” 由于DMA缓冲区很可能是有序内存,因此使用NEON的glibc memcpy在访问该DMA内存时会失败。就我而言,它发生在第二个周期,因为第一次访问是对齐的,而第二次访问是未对齐的。