/** * Author:hasen * Reference: Linux device Driver Development Details * Introduction: Android Small rookie Linux * device Driver Development Learning Journey * Topic: device drivers that support polling operations * DATE:2014-11-07 */
In
Globalfifo's poll () function, the r_wait and w_wait wait queue headers in the device structure are first added to the wait list.
Then by judging whether the Dev->current_len is equal to zero to obtain the readable state of the device, by judging whether Dev->current_len equals
Globalfifo_size to obtain the writable state of the device.
struct globalfifo_dev{struct cdev cdev;/*cdev struct */unsigned int current_len;/* Valid length of current FIFO */unsigned char mem[ Globalfifo_size];/* Global memory */struct semaphore SEM;/* semaphore for concurrency control */wait_queue_head_t r_wait;/*@@ 读 Waiting queue header */wait_queue_head _t w_wait;/*@@ 写 the wait queue header */}/*globalfifo device-driven poll () function */static unsigned int globalfifo_poll (struct file *filp,poll_table *wait) {unsigned int mask = 0; struct Globalfifo_dev *dev = filp->private_data;/* get device struct pointer */down (&DEV->SEM);p o Ll_wait (filp,&dev->r_wait,wait);p oll_wait (filp,&dev->w_wait,wait),/*@ @fifo non-empty */if (dev->current _len! = 0) Mask |= Pollin | Pollrdnorm; /*@@ 标示 data available *//*@ @fifo non-full */if (Dev->current_len! = globalfifo_size) Mask |= pollout | Pollwrnorm;/*@@ 标示 data can be written to */up (&dev->sem); return mask;}
Note that to assign Globalfifo_poll to the poll members of Global_fops:
static const File_operations Globalfifo_fops = {.... poll = Globalfifo_poll,...};
For poll members of Global_fops see the article "Linux file_operations structure in detail", which is also pasted here for easy access
unsigned int (*poll) (struct file *, struct poll_table_struct *); The poll method is the back-end of 3 system calls: Poll, Epoll, and select are used as queries against one or more file descriptors for read or write blocking. The poll method should return a bitmask indicating whether non-blocking reads or writes are possible, and, possibly, providing kernel information to make the calling process sleep until I/O becomes possible. If a driver's poll method is NULL, the device is assumed to be non-blocking readable and writable.
Monitoring whether GLOBALFIFO can be a non-blocking read-write application
#include ... # Define Fifo_clear 0x1 #define Buffer_len main () {int fd,num; char rd_ch[buffer_len];fd_set RfDs, Efds;/* Read and Write file description descriptor *//* to Non-blocking mode open/dev/globalfifo device file */FD = open ("/dev/globalfifo", O_rdonly | O_nonblock); if (fd! =-1) {/*fifo 0*/if (IOCTL (fd,fifo_clear,0) < 0) printf ("IOCTL command failed\n"); while (1) {Fd_ ZERO (&rfds); Fd_zero (&wfds); Fd_set (Fd,&rfds); Fd_set (Fd,&wfds); Select (Fd+1, &rfds, &wfds, NULL, NULL);/* data is available */if (Fd_isset (Fd,&rfds)) printf (" Poll Monitor:can be read\n ");/* data can be written to */if (Fd_isset (Fd,&wfds)) printf (" Poll monitor:can be Written\n ");}} else{printf ("Open device failed!\n");}}
When the runtime sees that there is no input, that is, the FIFO is empty, the program continuously outputs "Poll Monitor:can be written" when passed
After Echo writes some data to/dev/globalfifo, it will output "Poll Monitor:can be read" and "Poll Monitor:can be written" if
Continuously writes the data through ECHO to the/dev/globalfifo until the FIFO is written, discovering that the Pollmonitor program only outputs "Poll monitor:can be read".
For Globalfifo, there is no case of reading or writing.
For a detailed description of the functions called in the Code, refer to the polling section of the article "Hasen Linux device Driver Development learning journey-blocking and non-blocking I/O".
Hasen Linux device Driver Development learning journey-device driver that supports polling operations