c - Using select() to detect a block on a UIO device file -
i'm working on embedded processor running yocto. have modified uio_pdrv_genirq.c uio driver.
i writing library control dma. there 1 function writes device file , initiates dma. second function intended wait dma complete calling select(). whilst dma in progress device file blocks. on completion dma controller issues interrupt releases block on device file.
i have system working expected using read() want switch select() can include time out. however, when use select(), doesn't seem recognising block , returns (before dma has completed). have included simple version of code:
int gannet_dma_interrupt_wait(dma_device_t *dma_device, dma_direction dma_transfer_direction) { fd_set rfds; struct timeval timeout; int select_res; /* initialize file descriptor set , add device file */ fd_zero(&rfds); fd_set(dma_device->fd, &rfds); /* set timeout period. */ timeout.tv_sec = 5; timeout.tv_usec = 0; /* device file block until dma transfer has completed. */ select_res = select(fd_setsize, &rfds, null, null, &timeout); /* reset channel */ gannet_dma_reset(dma_device, dma_transfer_direction); if (select_res == -1) { /* select has encountered error */ perror("error <interrupt select failed>\n"); exit(0); } else if (select_res == 1) { /* device file descriptor block released */ return 0; } else { /* device file descriptor block exceeded timeout */ return eintr; } }
is there wrong code? or can suggest alternative select?
this answer assumes possible use select() intented specified device file (i use select() socket descriptors only). alternative function select(), may want check out poll() family of functions. follows @ least offer hints can done resolve problem calling select().
the first parameter select() function has maximum despriptor number plus 1. since have 1 descriptor, can pass directly select() first parameter , add 1. consider file descriptor in dma_device invalid. returning eintr on timeout may intend should not case , test invalid descriptor, here different version consider. select() call interrupted signal, in case, return value -1 , errno set eintr. handled internally function in:
fd_zero(&rfds); fd_set(dma_device->fd, &rfds); timeout.tv_sec = 5; timeout.tv_usec = 0; // restart select() if it's interrupted signal; { select_res = select(dma_device->fd + 1, &rfds, null, null, &timeout); } while( select_res < 0 && errno == eintr); if (select_res > 0) { // file descriptor legible } else { if (select_res == 0) { // select() timed-out } else { // error other signal occurred if (errno == ebadf) { // file descriptor invalid } } }
Comments
Post a Comment