Linux 内核驱动中的混杂设备和字符设备

一、 混杂设备(Mixed/Mixed-mode devices)

        概念:混杂设备是指同时支持字符设备和块设备操作的特殊设备类型,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice)。所有的混杂设备形成一个链表,对设备访问时内核根据次设备号查找到相应的混杂设备。它允许将块设备的访问方式映射为字符设备的操作接口。混杂设备的典型应用场景包括 loop 设备(用于处理块设备镜像文件)和 md 设备(用于软件 RAID)。

混杂设备的操作与字符设备类似,可以使用标准的文件操作函数(如open、read、write、close等)进行设备的访问和控制。

        在内核中创建一个混杂设备步骤:


        1、构建混杂设备结构体      

Linux中使用struct miscdevice来描述一个混杂设备。

混杂设备结构体原型为:

struct miscdevice {

    int minor; /* 次设备号*/

    const char *name; /* 设备名*/
    
    const struct file_operations *fops; /*文件操作*/
    
    struct list_head list;

    struct device *parent;

    struct device *this_device;

};

        其中文件操作结构体如:

struct file_operations ledfods={
	.owner = THIS_MODULE,
	.open = led_open,
	.release = led_close,
	.unlocked_ioctl = led_ioctl
};

         2、将该混杂设备的设备号在内核中注册(没有注册的设备即使创建成功也无法使用)

misc_register(&ledmisc); //注册一个Misc 混杂设备:主设备号

二、 字符设备(Character devices)

        

        概念:字符设备是一种特殊类型的设备,以字符(char)为基本单位进行数据读写。字符设备以流式的方式处理数据,用户每次可以读取或写入一个字符或字符流。典型的字符设备包括终端设备(例如TTY设备)、串口设备(Serial devices)等。

在内核中,字符设备通过字符设备接口进行访问和操作。用户可以使用标准的文件操作函数(如open、read、write、close等)来打开、关闭、读取和写入字符设备。字符设备接口提供了对设备的抽象和标准化,使得用户可以通过文件描述符对设备进行简单而统一的操作。

        在内核中创建一个字符设备的步骤:

        

        1、创建一个设备号

MAJOR(dev_t dev); //用于获取设备的主设备号
MINOR(dev_t dev); //用于获取设备的次设备号
MKDEV(int major, int minor); //根据所给的主次设备号生成dev_t
例:devno = MKDEV(100,0);//创建设备号(其中100为主设备号,0为次设备号)

        2、向内核申请设备号(注册)

        

        分为静态申请和动态申请

        1)静态申请

  int register_chrdev_region(dev_t from, unsigned count, const char * name)
from : 你要申请的 第一个设备号   count :你要申请几个设备号   name: 驱动的名字
返回值: 0 : 成功           其他: 失败
        2)动态申请
alloc_chrdev_region(dev_t * dev, unsigned baseminor, unsigned count, const char * name)

dev : 指针,用来保存申请到的设备号

dev: 指针,用来保存申请到的设备号                       from : 你要申请的 第一个设备号                        count :你要申请几个设备号                                    name: 驱动的名字
返回值: 0 : 成功           其他: 失败

        3、创建字符设备结构体

         结构体原型:

struct cdev {
    struct kobject kobj;//内嵌的kobject 对象
    struct module *owner;//所属模块
    const struct file_operations *ops;//文件操作结构体
    struct list_head list;//链表头
    dev_t dev;//设备号
    unsigned int count;
};

        1)内核分配字符设备结构体

	ledcdev = cdev_alloc();//分配字符设备结构体

        2)初始化结构体

	cdev_init(ledcdev, &ledfops);//初始化字符设备

        3)添加字符设备至内核

cdev_add(ledcdev, devno, 2);//添加字符设备到系统,第2个参数为起始设备号,第3个参数为设备编号范围

        4、创建设备类

        

class_create(THIS_MODULE, "my_class");//创建设备类

        5、在类中创建设备

for(i=0;i<2;i++)
		device_create( mycls, NULL, devno+i, NULL, "cdev_led%d",i);//创建两个
		/*参数 2:父设备 3:设备号 4:私有数据 5:设备名 和参数6一起构成一次打印,类似与printf*/

总结
        混杂设备是可以同时支持字符设备和块设备操作的特殊设备类型,允许将块设备映射到字符设备接口。而字符设备则是以字符为基本单位进行数据读写的设备类型,在内核中通过字符设备接口提供对设备的访问和控制方法。两者在内核的处理方式和应用场景上有所区别,但都提供了简化和统一的设备访问方式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值