Read from a character device using read() and a pointer to a buffer
I am developing a C program that will run in the user space of an embedded ARM GNU/Linux system. I need to read data from the character device node /dev/fpga_sram. In a C program, a buffer is allocated using malloc, as shown below.
uint16_t *buff;
uint32_t num = 4194304 * 3;
buff = (uint16_t *)malloc(num * sizeof(uint16_t));
Using the read
() function, I want to read the data into some index of the buffer, as shown in the following code snippet.
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);
This is done because the buffer needs to read different contents from the device node /dev/fpga_sram at different times. The buffer size is larger than the total bytes read, so I want to assign ptr_loc to another index, as shown below.
ptr_loc = 4194304;
fd = open("/dev/fpga_sram", O_RDONLY);
ret = read(fd, &(buff[ptr_loc]), 4194304 * sizeof(uint16_t));
close(fd);
However, when I try to access the data stored in the buffer, I get a segfault:
printf("i = 0, data = %u\n", buff[0]); this line of code causes segfault
What am I doing wrong here, is it possible to read data from the device node using a pointer to the buffer location? I assume that reading from a device node is similar to reading from a file in GNU/Linux.
Solution
Ignoring the read business, printf generates SEGV only because the buff points somewhere outside of the process’s effective memory. So use printf(“%p”, buff) and find out where the buff points and spread them throughout your code until you find out when it stops pointing to the address returned by malloc.