简体   繁体   中英

Correct Interface for non-blocking slow sampling sensor driver

I am writing a device driver for an i2c connected temperature/pressure gauge.

To operate the sensor, once first requests a new reading. The sensor will then perform the necessary sampling over a period of time and then report back the final readings. This process is expected to take some time.

Userspace is expected to connect to the device driver using the Character Device interface using file based read s and possibly ioctl s.

I can easily create a blocking interface where the user thread attempts a read and remains blocked until I am able to report back the sensor reading.

I would like to allow the driver to work in non-blocking mode since sampling is expected to take some time. The user thread can the either do other stuff or block on poll/select until the sampling is complete.

The problem is that I need the read to instruct the driver to start sampling but the driver cannot complete the read until the sampling is completed and in non-blocking mode, the driver is not allowed to block the thread between these two states.

As an added consideration, I would like to minimize the number of kernel calls invoked to perform this operation. I also need to ensure that precious power is not wasted on unnecessary sampling.

What is the correct Linux pattern for doing this?

Update: I am not interested in the implementation details, what I am really after is the design of the user/kernel interface that follows good practice.

Do the necessary sampling on sensor use work queue or other asynchronous primitive in the open method. In the work function, use wait_queue to notify poll the device is readable.

in the open method:

work_function()
{
    /*perform the necessary sampling*/
    /*after done, use wait queue to notify poll the device is readable.*/
}
DECLARE_WORK(name, work_function, data);

static int open(struct inode *inode, struct file *filp)
{
    /*do other stuff....*/
    queue_work(.......);   
}

static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
    poll_wait(filp, &dev->outq, wait);
    .......
    return mask;
}

LDD chapter 7 will helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM