当我尝试在 ARM 上运行一些交叉编译代码时,出现“总线错误”,我已将其追溯到:
int * arr;
arr = (int *)malloc(BUF*sizeof(int));
memcpy(arr,&cha_signal[trig_ptr],BUF*sizeof(int));
trig_ptr 是一个整数,指向我的信号开始的位置; BUF 缓冲区的大小(~16000)。
没有意义的是,如果我使用
手动循环 cha_signalfor(i=0; i < BUF; i++) { //do stuff }
我可以很好地访问它的所有元素!由于某种原因,看似等效的 memcpy() 操作被阻塞了。我怀疑,但我的知识不足以证实,这是由于 cha_signal 的制作方式造成的:
/* Map FPGA memory space to page_ptr. */
page_ptr = mmap(NULL, OSC_FPGA_BASE_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, g_osc_fpga_mem_fd, page_addr);
if((void *)page_ptr == MAP_FAILED) {
//cleanup code
}
/* Set FPGA OSC module pointers to correct values. */
g_osc_fpga_reg_mem = page_ptr + page_off;
g_osc_fpga_cha_mem = (uint32_t *)g_osc_fpga_reg_mem +
(OSC_FPGA_CHA_OFFSET / sizeof(uint32_t));
...
*cha_signal = (int *)g_osc_fpga_cha_mem;
有什么想法吗?我注意到另一个人也有类似的问题,但他试图写入未分配的空间。我相信我在这里分配是正确的。
最佳答案
我怀疑您的 memcpy
实现与您的硬件想要的读取方式根本不兼容。
这可能是那些实现 mmap
另一侧任何 FPGA 外设的“硬件人员”的问题。
由于您似乎正在访问硬件寄存器,而不仅仅是普通的旧内存,因此您必须遵守不同的规则。某些硬件要求您按字节、字或涉及对齐的其他规则访问内存。
问题的另一部分是您不知道 memcpy
实际是如何实现的。通常,它是一个人为的、高度优化的版本,它尝试在给定对齐约束的情况下以尽可能大的单位移动数据。可能是这个优化版本导致了您的问题。您可以使用标准 for
循环进行迭代这一事实证实了这一理论。
最好的办法是在调试器下运行应用程序,单步执行memcpy
,以查看从内存中实际读取的位置导致“总线错误”。
关于c - 尝试对由 mmap() 生成的指针使用 memcpy() 时出现总线错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23553550/