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
    等待队列和设备
    ---------------------------------

  • 相关阅读:
    DRUPAL-PSA-CORE-2014-005 && CVE-2014-3704 Drupal 7.31 SQL Injection Vulnerability /includes/database/database.inc Analysis
    WDCP(WDlinux Control Panel) mysql/add_user.php、mysql/add_db.php Authentication Loss
    Penetration Testing、Security Testing、Automation Testing
    Tomcat Server Configuration Automation Reinforcement
    Xcon2014 && Geekpwn2014
    phpMyadmin /scripts/setup.php Remote Code Injection && Execution CVE-2009-1151
    Linux System Log Collection、Log Integration、Log Analysis System Building Learning
    The Linux Process Principle,NameSpace, PID、TID、PGID、PPID、SID、TID、TTY
    Windows Management Instrumentation WMI Security Technology Learning
    IIS FTP Server Anonymous Writeable Reinforcement, WEBDAV Anonymous Writeable Reinforcement(undone)
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3106838.html
Copyright © 2011-2022 走看看