字符设备驱动-使用alloc_chrdev_region+cdev注册设备驱动

Lalloc_chrdev_region函数原型如下,它是我们用来向内核申请主设备号时用的,与register_chrdev_region不同的是,alloc_chrdev_region是让内核分配给我们一个尚未使用的主设备号,不是由我们自己指定的,该函数的四个传参意义如下:

dev :alloc_chrdev_region函数向内核申请下来的设备号

baseminor :次设备号的起始

count: 申请次设备号的个数

name :执行 cat /proc/devices显示的名称

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
            const char *name)
{
    struct char_device_struct *cd;
    cd = __register_chrdev_region(0, baseminor, count, name);
    if (IS_ERR(cd))
        return PTR_ERR(cd);
    *dev = MKDEV(cd->major, cd->baseminor);
    return 0;
}
cdev的使用:

1.执行cdev_init函数,将cdev和file_operations关联起来

2.使用cdev_add函数,将cdev和设备号关联起来

void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
    memset(cdev, 0, sizeof *cdev);
    INIT_LIST_HEAD(&cdev->list);
    kobject_init(&cdev->kobj, &ktype_cdev_default);
    cdev->ops = fops;
}
demo

#include <linux/module.h>       // module_init  module_exit
#include <linux/init.h>         // __init   __exit
#include <linux/cdev.h>
#include <linux/fs.h>
#define MYMAJOR     200
#define MYNAME      "chardev_test_byHc"
 
 
//DEVICE ID
dev_t devid;
 
static int chardev_open(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "chardev open\n");
    return 0;
}
 
static ssize_t chardev_read(struct file *file, char __user *buf,
          size_t size, loff_t *ppos)
{
    return 0;
}
 
 
static const struct file_operations chardev_fops = { 
 
    .open = chardev_open,
    .read = chardev_read,
};
 
static struct
{
    struct cdev cdev;
}chardev;
 
static int __init mymodule_init(void)
{   
    int ret = 0;
    printk(KERN_INFO "chrdev_init helloworld init\n");
    cdev_init(&chardev.cdev,&chardev_fops);
        
    alloc_chrdev_region(&devid,2,255,MYNAME);
    printk(KERN_INFO "MAJOR Number is %d\n",MAJOR(devid));
    printk(KERN_INFO "MINOR Number is %d\n",MINOR(devid));
    cdev_add(&chardev.cdev,devid,255);
        
    return 0;
}
static void __exit mymodule_exit(void)
{
    printk(KERN_INFO "chrdev_exit helloworld exit\n");
    cdev_del(&chardev.cdev);
    unregister_chrdev_region(devid,255);
 
}
 
 
module_init(mymodule_init);
module_exit(mymodule_exit);
 
// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");              // 描述模块的许可证
MODULE_AUTHOR("Hanc");              // 描述模块的作者
MODULE_DESCRIPTION("module test");  // 描述模块的介绍信息
MODULE_ALIAS("alias xxx");          // 描述模块的别名信息
 

--------------------- 
作者:明故宫的记忆 
来源:CSDN 
原文:https://blog.csdn.net/weixin_42314225/article/details/81112217 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值