zoukankan      html  css  js  c++  java
  • 设备驱动之一 proc文件系统接口

          学习linux设备驱动,第四章;

          关于proc文件系统接口编程参见

          procfs读取信息实例:http://blog.csdn.net/iamonlyme/article/details/7062237

          procfs读写信息实例:http://blog.csdn.net/iamonlyme/article/details/7065243

    本次修改的代码是属于main.c函数,主要是增加proc接口实现代码

    /**********************************************
     * Author: lewiyon@hotmail.com
     * File name: scullmod.c 
     * Description: initialize and release function for scull
     * Date: 2012-07-4
     *********************************************/
    
    #include <linux/init.h>         /* module        */
    #include <linux/module.h>       /* module        */
    #include <linux/moduleparam.h>  /* module        */
    #include <linux/errno.h>        /* error codes   */
    #include <linux/kernel.h>       /* printk        */
    #include <linux/slab.h>         /* kmalloc kfree */
    #include <linux/types.h>        /* dev_t         */
    #include <linux/proc_fs.h>      /* dev_t         */
    
    /* local head files */
    #include "scull.h"
    #include "file.h"
    
    #define SCULL_PROC_NAME "scull"   
    
    /* default parameters of module */
    int scull_major = SCULL_MAJOR;
    int scull_minor = 0;
    int scull_nr_devs = SCULL_NR_DEVS;
    int scull_quantum = SCULL_QUANTUM;
    int scull_qset = SCULL_QSET;
    
    /* input parameters of module */
    module_param(scull_major, int, S_IRUGO);
    module_param(scull_minor, int, S_IRUGO);
    module_param(scull_nr_devs, int, S_IRUGO);
    module_param(scull_quantum, int, S_IRUGO);
    module_param(scull_qset, int, S_IRUGO);
    
    struct scull_dev *scull_devices;
    static struct proc_dir_entry *scull_proc;  
    static struct proc_dir_entry *scull_info; 
    
    int scull_read_procmem(char *buf, char **start, off_t offset,
            int count, int *eof, void *data)
    {
        int len;
        struct scull_dev *dev;
    
        len = 0;
        dev = scull_devices;
        if (down_interruptible(&dev->sem))
            return -ERESTARTSYS;
       len += sprintf(buf + len, "qset:%i\nquantum:%i\nsize:%li\n",
                dev->qset, dev->quantum, dev->size);
    
        up(&dev->sem);
        *eof = 1;
    
        return len;
    }
    
    /*
     * scull_trim -  遍历链表,并释放所有找到的量子和量子集
     * @dev: scull设备
     */
    int scull_trim(struct scull_dev *dev)
    {
        int i, qset;
        struct scull_qset *next, *dptr;
        
        qset = dev->qset;
        for (dptr = dev->data; dptr; dptr = next) {
            if (dptr->data) {
                for (i = 0; i < qset; i++)
                    kfree(dptr->data[i]);
                kfree(dptr->data);
                dptr->data = NULL;
            }
            next = dptr->next;
            kfree(dptr);
        }
        dev->size = 0;
        dev->quantum = scull_quantum;
        dev->qset = scull_qset;
        dev->data = NULL;
    
        return 0;
    }
    
    static void scull_setup_cdev(struct scull_dev *dev, int index)
    {
        int err;
        int devno;
    
        devno = MKDEV(scull_major, scull_minor + index);
        cdev_init(&dev->cdev, &scull_fops);
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &scull_fops;
       
        err = cdev_add(&dev->cdev, devno, 1);
        if (err) 
            printk(KERN_NOTICE "Error %d adding scull%d", err, index);   
    }
    
    static void scull_unregister(void)
    {
        int i;
        dev_t devno;
    
        devno = MKDEV(scull_major, scull_minor);
        /* delete each entry */
        if (scull_devices) {
            for (i = 0; i < scull_nr_devs; i++) {
                scull_trim(scull_devices + i);
                cdev_del(&scull_devices[i].cdev);
            }
            kfree(scull_devices);
        }
    
        /* unregister */
        unregister_chrdev_region(devno, scull_nr_devs);
    }
    
    /*
     * initialze scull module 
     */
    void scull_cleanup_module(void)
    {
        remove_proc_entry("scullmem", scull_proc);
        remove_proc_entry(SCULL_PROC_NAME, NULL);
        scull_unregister();
        printk(KERN_WARNING "scull: Bye!\n");
    }
    
    
    /*
     * initialze scull module 
     */
    int scull_init_module(void)
    {
        int i, res;
        dev_t dev = 0;
        
        if (scull_major) {
            dev = MKDEV(scull_major, scull_minor);
            res = register_chrdev_region(dev, scull_nr_devs, "scull");
        } else {
            res = alloc_chrdev_region(&dev, scull_minor, 
                    scull_nr_devs, "scull");
            scull_major = MAJOR(dev);
        }
        if (res < 0) {
            printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
            return res;
        }
    
        /* 
         * allocate the device struct cache
         */
        scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), 
                GFP_KERNEL);
        if (NULL == scull_devices) {
            res = -ENOMEM;
            printk(KERN_WARNING "scull: NOMEM for scull!\n");
            goto fail;
        }
        memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
        /* initialize each device */
        for (i = 0; i < scull_nr_devs; i++) {
            scull_devices[i].quantum = scull_quantum;
            scull_devices[i].qset = scull_qset;
            sema_init(&scull_devices[i].sem, 1);
            scull_setup_cdev(&scull_devices[i], i);
        }
        printk(KERN_INFO "scull: OK!\n");
    
        scull_proc = proc_mkdir(SCULL_PROC_NAME, NULL);
        if (NULL == scull_proc) 
        { 
            res = -ENOMEM;    
            goto fail;
        }
        scull_info = create_proc_read_entry("scullmem", 0, scull_proc, 
                scull_read_procmem, NULL);
        if (NULL == scull_info)
        {
            res = -ENOMEM;
            goto info_err;
        }
        printk(KERN_INFO "scull proc: OK!\n");
    
        return 0;
    
    info_err:
        remove_proc_entry(SCULL_PROC_NAME, NULL);
    fail:
        scull_unregister();
        return res;
    }
    
    module_init(scull_init_module);
    module_exit(scull_cleanup_module);
    
    MODULE_AUTHOR("lewiyon@hotmail.com");
    MODULE_LICENSE("GPL");


     

  • 相关阅读:
    防止vue文件中的样式出现‘污染’情况(html5 scoped特性)
    Vue.js中滚动条加载更多数据
    本地上传文件至服务器的技巧(linux文件压缩及解压文件)
    ubuntu下apache新建虚拟主机
    laravel5.4+vue+element简单搭建(gulp+laravel Elixir)
    java基础---->Java的格式化输出
    markdown 基本语法(转载)
    谷歌断点调试
    mac 远程连接 云服务器
    棋盘覆盖问题
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624616.html
Copyright © 2011-2022 走看看