使用read()函数和指向缓冲区的指针从字符设备中读取数据

3

我正在开发一个运行在嵌入式ARM GNU/Linux系统用户空间的C程序。我需要从字符设备节点/dev/fpga_sram读取数据。在C程序中,已经使用malloc分配了一个缓冲区,如下所示。

uint16_t *buff;
uint32_t num = 4194304 * 3;
buff = (uint16_t *)malloc(num * sizeof(uint16_t));

使用read()函数,我想将数据读入缓冲区的特定索引中,如下面代码片段所示。
int ret;
int fd;
int ptr_loc;

ptr_loc = 0;    
fd = open("/dev/fpga_sram", O_RDONLY);
ret = read(fd, &(buff[ptr_loc]), 4194304 * sizeof(uint16_t));
close(fd);

我想这样做的原因是因为缓冲区需要在不同时间从设备节点/dev/fpga_sram中填充不同的读取。缓冲区大小大于读取的总字节数,因此我预计将ptr_loc分配给另一个索引,如下所示。

ptr_loc = 4194304;    
fd = open("/dev/fpga_sram", O_RDONLY);
ret = read(fd, &(buff[ptr_loc]), 4194304 * sizeof(uint16_t));
close(fd);  

然而,当我尝试访问缓冲区中存储的数据时,我收到了一个段错误:
printf("i = 0, data = %u\n", buff[0]);   // this line of code causes segfault

我在这里做错了什么?是否可能使用指向缓冲区位置的指针从设备节点读取数据?我认为从设备节点读取数据类似于在GNU/Linux中从文件中读取数据。


4
你检查了malloc的返回值吗?你有8Mb的RAM可以分配吗? - Martin Beckett
1
我强烈建议始终检查返回值,例如malloc和open。 - mdec
1
你确定你没有超出缓冲区的范围进行 read() 操作吗?如果 ptr_loc > 1,看起来你是这样做了。 - Dave
@Martin Beckett:我已经检查了malloc的返回值,以确保buff不是NULL,并且我总共有128MB的RAM。如果我不使用指针,那么ret = read(fd, buff, 4194304 * sizeof(uint16_t))可以正常工作,但读取将从缓冲区的开头开始。 - Nicholas Kinar
1
@NicholasKinar 实际上,ptr_loc需要大于(4<<20)*2才会出现问题。 - Dave
显示剩余2条评论
1个回答

4
忽略阅读业务,printf导致SEGV的唯一原因是buff指向了进程无效内存之外的某个位置。因此,请使用printf("%p", buff)并查找buff指向的位置,并在代码中添加这些内容,直到您发现它停止指向malloc返回的地址。

1
你是对的;问题与指针在另一个函数中被修改有关。我编写了一些测试程序,并发现读取(如上面的代码片段所示)运行良好。我在整个代码中使用 printf("%p",buff),并成功找到了我的错误。谢谢你指出这一点。 - Nicholas Kinar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接