杂项设备驱动

来源:互联网 发布:定额预算软件破解版 编辑:程序博客网 时间:2024/06/03 16:00

1、简介

Linux杂项驱动出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费。
所有这些设备都统一采用主设备号为10,次设备动态分配的方式注册到内核

杂项设备描述结构体

linux/miscdevice.hstruct miscdevice  {    int minor;//次设备号    const char *name;//设备的名字    const struct file_operations *fops;//设备的操作函数集    struct list_head list;//将miscdevice串成链表使用    struct device *parent;//父设备(设备模型有关)    struct device *this_device;//代表自己的设备(设备模型有关)    const char *nodename;    mode_t mode;};

2、使用

2.1 填充file_operations
2.2 填充miscdevice
2.3 misc_register(&miscdevice); //注册并生成节点

3、代码

#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>//杂项设备需要的头文件#include <linux/miscdevice.h>#include <linux/uaccess.h>#define DEMO_DEBUG#ifdef  DEMO_DEBUG#define dem_dbg(fmt, arg...)        printk(KERN_WARNING fmt, ##arg)#else#define dem_dbg(fmt, arg...)        printk(KERN_DEBUG fmt, ##arg)#endifstatic int demo_open (struct inode *pnode, struct file *filp){    dem_dbg("==>%s  major: %d  minor: %d\n",                    __FUNCTION__, imajor(pnode), iminor(pnode));    return 0;}static ssize_t demo_read (struct file *filp, char __user *buf, size_t count, loff_t *offp){    unsigned char ary[100] = "read successfully\n";    unsigned long len = min(count, sizeof(ary));    int retval;    printk("==>%s  major: %d  minor: %d\n",                    __FUNCTION__, imajor(filp->f_dentry->d_inode),                     iminor(filp->f_dentry->d_inode));    if(copy_to_user(buf, ary, len) != 0){        retval = -EFAULT;        goto cp_err;    }    return len; //成功返回实际传输的字节数cp_err:    return retval;      }static int demo_release (struct inode *pnode, struct file *filp){    dem_dbg("==>%s  major: %d  minor: %d\n",                    __FUNCTION__, imajor(pnode), iminor(pnode));    return 0;}static struct file_operations fops = {    .owner = THIS_MODULE,    .read = demo_read,    .open = demo_open,    .release = demo_release,};  //1 定义miscdevice结构体static struct miscdevice misc = {    //动态获取次设备号    .minor = MISC_DYNAMIC_MINOR,    //填充file_operations结构体    .fops = &fops,    //设备名称    .name = "demo0",};static int __init demo_init(void){       int res;    dem_dbg("==>demo_init\n");    //2 注册杂项设备 将在/dev/目录下自动创建设备文件节点    res = misc_register(&misc);    if(res < 0){        dem_dbg("register misc device failed!\n");        return -EFAULT;    }    return 0;}static void __exit demo_exit(void){    dem_dbg("==>demo_exit\n");    //3 注销杂项设备    misc_deregister(&misc);}module_init(demo_init);module_exit(demo_exit);MODULE_LICENSE("Dual BSD/GPL");

Makefile

ifneq ($(KERNELRELEASE),)    obj-m +=misc.o    #此时由内核构造系统调用else    #定义并记录内核源码路径    KERNELDIR = /home/ms/iTop4412_Kernel_3.0    #记录当前工程目录    PWD := $(shell pwd)default:         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules        @rm -rf *.o .t* .m* .*.cmd *.mod.c *.order *.symversendifclean:        rm -rf *.ko *.o .t* .m* .*.cmd *.mod.c *.order *.symvers
原创粉丝点击