linux字符设备驱动编写

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>//cdev结构体的头文件
#include <linux/device.h>//class、create函数

/*注意:以下代码是申请了设备号 + 注册到内核中,但是并没有创建设备节点,因此需要完成这两部后需要
执行命令 mknod /dev/test c 247 0 来创建一个设备节点test c的意思是test的文件类型 247是主设备号
 0 是次设备号*/


static int major_num,minor_num;//定义主/次设备号,传参的时候只传递主设备号,次设备号默认是0

//dev_t就是int类型,高12位是主设备号,低20位是次设备号
dev_t dev_num;

//向模块传参的函数
module_param(major_num,int,S_IRUSR);
module_param(minor_num,int,S_IRUSR);

struct cdev cdev;

struct class *class;

struct device *device;

int chrdev_open(struct inode *inode,struct file *file)
{
    printk("chrdev_open ok\n");
    return 0;
}

struct file_operations chrdev_ops = {
    .owner = THIS_MODULE,
    .open = chrdev_open
};

static int hello_init(void)
{
    int ret;

    //如果传入了主设备号(大于0),那么使用静态申请的方式申请设备号,否则使用动态申请
    if(major_num > 0)
    {
        //将主次设备号合并成一个 dev_t类型的变量
        dev_num = MKDEV(major_num,minor_num);

        //静态申请一个字符设备号,参数:①设备号②次设备号的个数③设备名称(/proc/devices文件中有 如10 misc)
        ret = register_chrdev_region(dev_num,1,"s_name");
        if(ret == 0)
        {
            printk("静态申请成功\n");
        }else{
            printk("静态申请失败\n");
        }
    }else
    {
        //动态分配设备号,参数①dev_t设备号②次设备号的起始值③次设备号的个数④设备号名称
        ret = alloc_chrdev_region(&dev_num,0,1,"d_name");
        if(ret < 0)
        {
            printk("动态申请失败\n");
        }else
        {
            printk("动态申请成功\n");
        }
        major_num = MAJOR(dev_num);//取出动态分配的主设备号
        minor_num = MINOR(dev_num);//取出次设备号
    }
    
    //cdev成员初始化,cdev_init函数就是添加一个文件操作集
    cdev.owner = THIS_MODULE;
    cdev_init(&cdev,&chrdev_ops);

    //将cdev结构体添加到内核中
    cdev_add(&cdev,dev_num,1);

    //创建一个class类
    class = class_create(THIS_MODULE,"dev_class");

    device = device_create(class,NULL,dev_num,NULL,"/dev/dev_name");

    return 0;
}

static void hello_exit(void)
{
    //注销设备号,参数①dev_t设备号,②申请的次设备号的个数
    unregister_chrdev_region(MKDEV(major_num,minor_num),1);
    //注销cdev结构体
    cdev_del(&cdev);
    //注销设备节点
    device_destroy(class,dev_num);
    //注销class类
    class_destroy(class);
    printk("bye bye\n");
}


module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

步骤:

1、申请设备号。在/proc/devices文件中可以看到,如 10 misc

2、创建cdev结构体 + 编写文件操作集fops。cdev_add(&cdev,dev_num,1) ---> 将结构体和设备号绑定并注册到内核中。

3、创建 class类。class_create函数,在 sys/class目录下可以看到,同一种类型驱动。

4、在class下创建设备节点。device_create函数,在/dev目录下就有了设备节点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值