设备驱动之一 - proc文件系统接口
来源:互联网 发布:coc九本女王升级数据 编辑:程序博客网 时间:2024/05/21 14:57
学习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");
- 设备驱动之一 - proc文件系统接口
- Linux设备驱动---/proc文件系统
- proc文件系统接口
- 51 linux设备驱动的proc调用接口
- 内核驱动之proc文件系统
- 驱动调试之proc文件系统
- linux驱动中在/proc虚拟文件系统目录下自动创建设备
- linux驱动中在/proc虚拟文件系统目录下自动创建设备【转】
- 《linux程序设计学习笔记》之一---/proc文件系统
- 设备驱动之一---Helloworld
- 内核proc文件系统 --和--seq接口
- 内核proc文件系统与seq接口
- 《Linux设备驱动开发详解》源码——proc/proc
- 内核proc文件系统与seq接口----内核proc文件系统编程接口
- 内核proc文件系统与seq接口(2)---内核proc文件系统编程接口
- 内核proc文件系统与seq接口(2)---内核proc文件系统编程接口
- 流接口设备驱动
- 驱动设备模型---sys文件系统
- 在数组A上有序合并数组B
- 推荐两个非常好用的测试工具jmeter和badboy
- Comparable接口
- Android学习笔记————异步图片加载
- HDU 1560 DNA sequence IDA*搜索
- 设备驱动之一 - proc文件系统接口
- 多线程下的单例模式
- Android中的自定义数据适配器
- Binary Indexed Tree实现 国内称作 树状数组
- windows基本窗口
- CGI ASP PHP JSP ASP.net 比较
- 迈出从3K到1W的重要一步——掌握设计模式
- Comparator接口
- MBR完整架构