尝试在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;
有什么想法吗?我注意到另外一个有类似问题的人,但他在那里试图写入没有分配的空间。我相信我在这里正确分配。
答案 0 :(得分:3)
我怀疑您memcpy
的实施与硬件想要阅读的方式完全不符。
这可能是“硬件人员”的一个问题,它实现了mmap
另一端的FPGA外设。
由于您似乎正在访问硬件寄存器,而不仅仅是普通的旧内存,因此您必须遵循不同的规则。某些硬件需要,您可以按字节,字或其他涉及对齐的规则访问内存。
问题的另一部分是你不知道memcpy
是如何实际实现的。通常情况下,它是一个人为的,高度优化的版本,在给定对齐限制的情况下,它试图以最大的单位移动数据。可能是这个优化版本导致了您的问题。您可以使用标准for
循环来迭代这一事实来证实这一理论。
您最好的选择是在调试器下运行您的应用程序,逐步执行memcpy
,以查看实际内存读取导致“总线错误”的位置。