当前位置:   article > 正文

02-Linux设备分类和设备编号学习_设备类型 设备节点 设备号

设备类型 设备节点 设备号

Linux设备和分类

字符设备:能够像字节流一样被访问的设备,当对字符设备发出读写请求,相应的I/O操作立即发生。例,字符终端、串口、键盘、鼠标等;
块设备 :Linux系统中进行I/O操作时必须以块为单位进行访问的设备,块设备能够安装文件系统。块设备驱动会利用一块系统内存作为缓冲区,因此对块设备发出读写访问,并不一定立即产生硬件I/O操作。例,硬盘、软驱等;
网络设备:既可以是网卡这样的硬件设备,也可以是一个纯软件设备如回环设备。网络设备由Linux的网络子系统驱动,负责数据包的发送和接收,而不是面向流设备,因此在Linux系统文件系统中网络设备没有节点,对网络设备的访问是通过socket调用产生

1、设备节点和设备编号

在这里插入图片描述dev_t类型来保存设备编号(包括主设备号和次设备号)。

在 2.62.6 版本的Linux内核中,dev_t 是一个 32 位数,高12位是主设备号,低20位是次设备号(从设备号)。
1、主设备号:
如果多个设备使用同一个驱动程序,则它们拥有相同的主设备号。主设备号由系统来维护,但是在使用主设备号的时候,注意一定不要使用系统已经的主设备号。
一般来说,231~239这几个设备是系统没有分配的,用户可以自行安排使用。cat /proc/devices查看运行系统占用了哪些主设备号。
2、次设备号:
用于确定该文件所指定的设备,如果一个设备驱动可以驱动一组相似的设备,此时就需要依赖于次设备号对这些外进行区分。

1.1 操作设备号

从dev_t获取。应当使用 <linux/kdev_t.h>中定义的 宏,而不应当对设备号位数和表述结构做任何假设,因为这样会导致不兼容以前的内核,或者未来版本设备号结构和表述方式发生变化。例如获取一个设备dev的主次设备号,可用:

#include<linux/kdev_t.h>

MAJOR(dev_t dev);		//获取主设备号
MINOR(dev_t dev);		//获取次设备号
  • 1
  • 2
  • 3
  • 4

如果已知一个设备的主次设备号,要转换成dev_t类型的设备编号,则应当使用:

MKDEV(int major,int minor);
  • 1

1.2 获取设备编号:

1)静态获取主设备:
只在特定系统运行,且系统设备号使用情况明确;系统应用所要求;如为了快速启动等。

#include<linux/fs.h>

int register_chrdev_region(dev_t first,unsigned int count,char *name);	//向系统注册1个或多个设备号
//first是起始编号;
//count是主设备号的数量;
//name是设备名称
/*注册成功返回0,否则返回错误码*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2)动态获取主设备号:

如果事先不知道设备的设备号,或者一个驱动可能在多个系统上运行,为了避免出现设备号冲突,必须采用动态设备号。

#include<linux/fs.h>

alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);//该函数可以从系统动态获得一个或者多个主设备号
//dev用于保存已经获得的编号范围的第一个值;
//firstminor是第一个次设备号,通常是0;
//count是获得的编号数量;
//name是设备名称;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

动态获取得到的设备号,一定要用一个全局变量保存下来以便卸载使用,否则该设备号将不能被释放。

1.3 释放设备号

在设备注销的时候必须释放占用的主设备号,调在unregister_chrdev_region 可以释放设备号。函数原型:

void unregister_chrdev_region(dev_t from,unsigned count);
//from要释放的设备号,与注册的设备号一致;
//count释放设备号的个数;
  • 1
  • 2
  • 3

1.4 测试程序

#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/device.h>

static int dev_major;
static int dev_minor;

module_param(dev_major,int,S_IRUGO);
module_param(dev_minor,int,S_IRUGO);
dev_t dev_no;           //dev number

#define DEVICE_NAME     "cdev_hello"
#define MINOR_NUM       0
#define DEVICE_COUNT    1
static int __init hello_init(void)
{
        int ret;
        printk("Hello init!Get number is %d\n",dev_major);
        if(dev_major > 0)       //Static gain                   
        {
                dev_no = MKDEV(dev_major, dev_minor);           //Get the dev_t type.
                ret = register_chrdev_region (dev_no, DEVICE_COUNT, DEVICE_NAME);//Static acquisition device
                if(ret < 0)
                {
                        printk("static no error!\n");   //Fail to get
                        return ret;
                }
                printk("static is ok!\n");              //Gain success
                printk("major = %d,minor = %d\n",dev_major,dev_minor);
        }
        else                    //Dynamic acquisition
        {
                alloc_chrdev_region(&dev_no, MINOR_NUM, DEVICE_COUNT, DEVICE_NAME);
                dev_major = MAJOR(dev_no);      //Get major
                dev_minor = MINOR(dev_no);      //Get minor
                printk("Dynamic is ok!\n");
                printk("major = %d,minor = %d\n",dev_major,dev_minor);
        }
        return 0;
}
static void __exit hello_exit(void)
{
        unregister_chrdev_region(dev_no,DEVICE_COUNT);	//设备个数设置为宏定义后才能取消设备号??
        printk("Hello exit!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

测试结果
1、
在这里插入图片描述
2、
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/243823
推荐阅读
相关标签
  

闽ICP备14008679号