Linux裝置驅動,等待佇列

2021-06-14 14:42:33 字數 4836 閱讀 6623

裝置驅動程式:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

module_license("gpl");

#define buf_size    256

#define device      ((const char*)"kgrunt")

struct kgrunt_dev 

struct cdev cdev;

char *buf;

int len;

int bytes;

struct timer_list timer;

int timer_flag;

wait_queue_head_t queue;

dev_t dev;

static struct kgrunt_dev kgrunt;

static void kgrunt_timer_fn(unsigned long d)

struct kgrunt_dev *dev = (struct kgrunt_dev *)d;

struct timer_list *timer = &dev->timer;

dev->bytes = snprintf(dev->buf, dev->len,\

"timer experis: %lu,jiffers: %lu, current pid: %d, comm:%s\n",\

timer->expires,jiffies, current->pid, current->comm);

wake_up_interruptible(&dev->queue);//喚醒等待佇列

if (dev->timer_flag)

mod_timer(timer, timer->expires + hz);

static int kgrunt_open(struct inode *inode, struct file *file)

printk("kgrunt open\n");

struct kgrunt_dev *dev = \

container_of(inode->i_cdev, struct kgrunt_dev, cdev);//由

inode

對應的字元裝置指標得到

kgrunt

裝置的位址

file->private_data = dev;

mod_timer(&dev->timer, jiffies + hz);//註冊定時器

dev->timer_flag = 1;

return 0;

static int kgrunt_realse(struct inode *inode, struct file *file)

printk("kgrunt release\n");

struct kgrunt_dev * dev = container_of(inode->i_cdev, struct kgrunt_dev, cdev);

dev->timer_flag = 0;

del_timer_sync(&dev->timer);

return 0;

static ssize_t kgrunt_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

int err;

struct kgrunt_dev *dev = (struct kgrunt_dev *)file->private_data;

printk("read data ,count: %d, pos: %d\n", count, (int)*pos);

if (count < 0)

return -einval;

if (count == 0)

return 0;

if (dev->bytes == 0)

if (file->f_flags & o_nonblock)

return -eagain;

err = wait_event_interruptible(dev->queue, dev->bytes > 0);//等待佇列

if (err == erestartsys)

return -eintr;

if (count > dev->bytes)

count = dev->bytes;

if (copy_to_user(buf, dev->buf, count) > 0)  

printk("copy data to user failed\n");

return -efault;

dev->bytes = 0;

return count;

static ssize_t kgrunt_write(struct file *file, char __user *buf, size_t count, loff_t *pos)

/*nothing to do*/

return -eperm;

static loff_t kgrunt_llseek(struct file *file, loff_t offset, int whence)

/*nothing to do*/

return -eperm;

static struct file_operations kgrunt_fops = 

.owner  =   this_module,

.open   =   kgrunt_open,

.release=   kgrunt_realse,

.read   =   kgrunt_read,

.write  =   kgrunt_write,

.llseek =   kgrunt_llseek,

static __init int kgrunt_init(void)

int err;

printk("init kgrunt\n");

if ((err = alloc_chrdev_region(&kgrunt.dev, 0, 1, device)) < 0)//自動註冊裝置號

printk("alloc_chardev_region err\n");

goto cdev_alloc_fail;

printk("major: %d, minor: %d\n", major(kgrunt.dev), minor(kgrunt.dev));

if ((kgrunt.buf = kmalloc(buf_size, gfp_kernel)) == null)

goto kmalloc_fali;

printk("kmalloc succfull\n");

kgrunt.len = buf_size;

kgrunt.bytes = 0;

cdev_init(&kgrunt.cdev, &kgrunt_fops);//初始化裝置

kgrunt.cdev.owner = kgrunt_fops.owner;

setup_timer(&kgrunt.timer, kgrunt_timer_fn, (unsigned long)&kgrunt);//初始化、設定定時器

kgrunt.timer_flag = 0;

init_waitqueue_head(&kgrunt.queue);//初始化等待佇列

if ((err = cdev_add(&kgrunt.cdev, kgrunt.dev, 1)) < 0)//註冊裝置

printk("cedv_add fail\n");

goto cdev_add_fail;

return 0;

cdev_add_fail:

kfree(&kgrunt.buf);    

kmalloc_fali:

unregister_chrdev_region(kgrunt.dev, 1);

cdev_alloc_fail:

return err;

static __exit void kgrunt_exit(void)

printk("kgrunt exit\n");

cdev_del(&kgrunt.cdev);

kfree(kgrunt.buf);

unregister_chrdev_region(kgrunt.dev, 1);

module_init(kgrunt_init);

module_exit(kgrunt_exit);

應用程式:

#include 

#include 

#include 

#include 

#include 

#include 

#define device (const char*)"/dev/kgrunt"

int main(int argc, char **argv)

char buf[256];

int fd, ret;

memset(buf, 0, sizeof(buf));

if ((fd = open(device, o_rdonly)) < 0)

printf("open device failed\n");

return 0;

while(1)

memset(buf, 0, sizeof(buf));

if ((ret = read(fd, buf, sizeof(buf))) < 0)

sleep(1);

continue;

sleep(1);

printf("read data: %s\n", buf);

Linux 裝置驅動 核心等待佇列

在 linux 驅動程式設計中,可以使用等待佇列來實現程序的阻塞.等待佇列可以看作儲存程序的容器,在阻塞程序時,將程序放入等待佇列 當喚醒程序時,從等待佇列中取出程序.linux 2.6 核心提供了如下關於等待佇列的操作 wait queue head t my queue init waitque...

《Linux裝置驅動開發詳解》 等待佇列

基礎知識 阻塞與非阻塞 阻塞操作是指在執行裝置操作時若不能獲得資源則掛起程序,直到滿足可操作的條件後再進行操作。被掛起的程序進入休眠狀態,被從排程器的執行佇列移走,直到等待的條件被滿足。而非阻塞操作的程序在不能進行裝置操作時並不掛起,它或者放棄,或者不停地查詢,直至可以進行操作為止。驅動程式通常需要...

Linux 裝置驅動阻塞 非阻塞IO 等待佇列

阻塞 顧名思義,就是指在執行裝置操作時若不能獲得資源則掛起操作,直到滿足可操作的條件後再進行操作,被掛起的程序進入休眠狀態,被從排程器的執行佇列移 走,直到等待的條件滿足。非阻塞 就是反過來,程序在不能進行裝置操作時並不掛起,它或者放棄,或者不停的查詢,直到可以進行位置。小王,明白了沒這兩個基本的概...