c - 尝试对由 mmap() 生成的指针使用 memcpy() 时出现总线错误

标签 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;

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

最佳答案

我怀疑您的 memcpy 实现与您的硬件想要的读取方式根本不兼容。

这可能是那些实现 mmap 另一侧任何 FPGA 外设的“硬件人员”的问题。

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

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

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

关于c - 尝试对由 mmap() 生成的指针使用 memcpy() 时出现总线错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23553550/

相关文章:

c - 使用 syscall() 链接 initramfs 中的 key 环

c - 返回错误答案

c - C中字符串上的指针

c++ - 在 32 位字位模式中找到 "edges"

C 编程-如何从文件中删除包含特定单词的行?

python - Windows 与 Python Hook

c - 为什么 scanf 在读取字符串时会崩溃?

c - 解释 malloc、free 和对象大小

C/C++ 'continue' 等价于 VB6

c# - bluemix vm openstack 使用c++语言