zoukankan      html  css  js  c++  java
  • 等待队列设备[置顶] Linux设备驱动,等待队列

    近期一直在学习等待队列设备之类的问题,今天正好有机会和大家讨论一下.

        设备驱动程序:

        #include <linux/module.h>

        #include <linux/fs.h>

        #include <linux/cdev.h>

        #include <linux/uaccess.h>

        #include <linux/timer.h>

        #include <linux/sched.h>

        #include <linux/wait.h>

        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 <stdio.h>

        #include <string.h>

        #include <sys/types.h>

        #include <sys/stat.h>

        #include <fcntl.h>

        #include <unistd.h>

        #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);

        }

        }

    文章结束给大家分享下程序员的一些笑话语录: 祝大家在以后的日子里. 男生象Oracle般健壮; 女生象win7般漂亮; 桃花运象IE中毒般频繁; 钱包如Gmail容量般壮大, 升职速度赶上微软打补丁 , 追女朋友像木马一样猖獗, 生活像重装电脑后一样幸福, 写程序敲代码和聊天一样有**。

    --------------------------------- 原创文章 By
    等待队列和设备
    ---------------------------------

  • 相关阅读:
    代理支持
    CGI
    SSI(服务器端嵌入)
    SSL/TLS 配置
    JSPs
    类加载机制
    JDBC 数据源
    安全管理
    Realm 配置
    Js将序列化成Json格式后日期(毫秒数)转成日期格式
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3106838.html
Copyright © 2011-2022 走看看