c - 尝试在由mmap()创建的指针上使用memcpy()时出现总线错误

时间:2014-05-08 22:19:10

标签: c

尝试在ARM上运行一些交叉编译的代码时出现“总线错误”,我已将其追溯到此:

    int * arr;
    arr = (int *)malloc(BUF*sizeof(int));       

    memcpy(arr,&cha_signal[trig_ptr],BUF*sizeof(int));

trig_ptr是一个指向信号开始位置的整数; BUF缓冲区的大小(~16000)。

没有意义的是,如果我使用

手动循环访问cha_signal
for(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;

有什么想法吗?我注意到另外一个有类似问题的人,但他在那里试图写入没有分配的空间。我相信我在这里正确分配。

1 个答案:

答案 0 :(得分:3)

我怀疑您memcpy的实施与硬件想要阅读的方式完全不符。

这可能是“硬件人员”的一个问题,它实现了mmap另一端的FPGA外设。

由于您似乎正在访问硬件寄存器,而不仅仅是普通的旧内存,因此您必须遵循不同的规则。某些硬件需要,您可以按字节,字或其他涉及对齐的规则访问内存。

问题的另一部分是你不知道memcpy是如何实际实现的。通常情况下,它是一个人为的,高度优化的版本,在给定对齐限制的情况下,它试图以最大的单位移动数据。可能是这个优化版本导致了您的问题。您可以使用标准for循环来迭代这一事实来证实这一理论。

您最好的选择是在调试器下运行您的应用程序,逐步执行memcpy,以查看实际内存读取导致“总线错误”的位置。