杂项设备驱动

1、简介

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

杂项设备描述结构体

linux/miscdevice.h

struct 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)
#endif

static 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 *.symvers

endif

clean:
        rm -rf *.ko *.o .t* .m* .*.cmd *.mod.c *.order *.symvers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值