申请和注销设备号的方法

news/2025/1/11 7:03:41/

一、Linux内核对设备的分类

linux的文件种类:

  1. -:普通文件

  2. d:目录文件

  3. p:管道文件

  4. s:本地socket文件

  5. l:链接文件

  6. c:字符设备

  7. b:块设备

Linux内核按驱动程序实现模型框架的不同,将设备分为三类:

  1. 字符设备:按字节流形式进行数据读写的设备,一般情况下按顺序访问,数据量不大,一般不设缓存

  2. 块设备:按整块进行数据读写的设备,最小的块大小为512字节(一个扇区),块的大小必须是扇区的整数倍,Linux系统的块大小一般为4096字节,随机访问,设缓存以提高效率

  3. 网络设备:针对网络数据收发的设备

总体框架图:

 

二、设备号------内核中同类设备的区分

内核用设备号来区分同类里不同的设备,设备号是一个无符号32位整数,数据类型为dev_t,设备号分为两部分:

  1. 主设备号:占高12位,用来表示驱动程序相同的一类设备

  2. 次设备号:占低20位,用来表示被操作的哪个具体设备

应用程序打开一个设备文件时,通过设备号来查找定位内核中管理的设备。

MKDEV宏用来将主设备号和次设备号组合成32位完整的设备号,用法:

dev_t devno;
int major = 251;//主设备号
int minor = 2;//次设备号
devno = MKDEV(major,minor);//将自定义的主设备号和次设备号结合为内核可以区分的32位的设备号

MAJOR宏用来从32位设备号中分离出主设备号,用法:

dev_t devno = MKDEV(249,1);
int major = MAJOR(devno);

MINOR宏用来从32位设备号中分离出次设备号,用法:

dev_t devno = MKDEV(249,1);
int minor = MINOR(devno);

如果已知一个设备的主次设备号,应用层指定好设备文件名,那么可以用mknod命令在/dev目录创建代表这个设备的文件,即此后应用程序对此文件的操作就是对其代表的设备操作,mknod用法如下:

@ cd /dev
@ mknod 设备文件名 设备种类(c为字符设备,b为块设备)  主设备号  次设备号    //ubuntu下需加sudo执行 ,例如在dev目录下要创建的设备文件名为mydev,其为字符设备,主设备号自定义为20,次设备号为1,则使用命令 sudo mknod /dev/mydev c 20 1 来创建对应的设备驱动文件。

在应用程序中如果要创建设备可以调用系统调用函数mknod,其原型如下:

int mknod(const char *pathname,mode_t mode,dev_t dev);
pathname:带路径的设备文件名,无路径默认为当前目录,一般都创建在/dev下
mode:文件权限 位或 S_IFCHR/S_IFBLK
dev:32位设备号
返回值:成功为0,失败-1

三、申请和注销设备号

字符驱动开发的第一步是通过模块的入口函数向内核添加本设备驱动的代码框架,主要完成:

  1. 申请设备号

  2. 定义、初始化、向内核添加代表本设备的结构体元素

int register_chrdev_region(dev_t from, unsigned count, const char *name)
功能:手动分配设备号,先验证设备号是否被占用,如果没有则申请占用该设备号
参数:from:自己指定的设备号count:申请的设备数量name:/proc/devices文件中与该设备对应的名字,方便用户层查询主设备号
返回值:成功为0,失败负数,绝对值为错误码int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count, const char *name)
功能:动态分配设备号,查询内核里未被占用的设备号,如果找到则占用该设备号
参数:dev:分配设备号成功后用来存放分配到的设备号baseminior:起始的次设备号,一般为0count:申请的设备数量name:/proc/devices文件中与该设备对应的名字,方便用户层查询主次设备号
返回值:成功为0,失败负数,绝对值为错误码

分配成功后在/proc/devices 可以查看到申请到主设备号和对应的设备名,mknod时参数可以参考查到的此设备信息

void unregister_chrdev_region(dev_t from, unsigned count)
功能:释放设备号
参数:from:已成功分配的设备号将被释放count:申请成功的设备数量

释放后/proc/devices文件对应的记录消失

注:在申请时若是动态申请,则需要使用MAJOR来重新为主设备号赋值,因为动态申请使用的主设备号是我们所不知道的。


http://www.ppmy.cn/news/809579.html

相关文章

S3C2440 ARM920T CPU

S3C2440 ARM920T CPU 支持大端/小端模式。共同有8个存储器BANK,每个BANK为128M。BANK0~BANK6为固定起始地址。BANK7可编程BANK起始地址和大小,其开始地址是BANK6的结束地址,灵活可变。BANK0~BANK5用于ROM或者SRAM,BANK6、BANK7用…

linux驱动38:后备高速缓存

设备驱动程序常常会反复地分配同一大小的内存块&#xff0c;为这些反复使用的内存块增加某些特殊的内存池——后备高速缓存。 linux内核的高速缓存管理称为slab分配器&#xff0c;头文件<linux/slab.h>&#xff0c;类型struct kmem_cache。 一、api接口&#xff1a; 1…

socket简介及java实例

网络上的两个程序通过一个双向的通信连接实现数据的交换&#xff0c;这个连接的一端称为一个socket。 建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API)&#xff0c;对TCP/IP的封装&#xff0c;TCP/IP也要提供可供程序员做网络开发所用的接口&#xff0c;…

三星ARM9以上芯片(244X,6410等)和cortex-a8芯片(S5PV210)比较PK

贴2张图&#xff0c;一看便明了&#xff1a;&#xff08;s5pv210开发技术交流群&#xff1a;8334819&#xff09; KEY FEATURES OF S5PV210 The key features of S5PV210 include: •ARM CortexTM-A8 based CPU Subsystem with NEON −32/ 32 KB I/D Cache, 512 KB L2 Cache −…

关于S3C6400 DM9000a 驱动

平台&#xff1a;S3C6400Ethernet :DM9000a由于是A公司的BSP&#xff0c;改了网卡的片选&#xff0c;发现可以找到ID&#xff0c;但是就是ping失败。厂家的帮忙 &#xff0c;加上了一些debug信息&#xff0c;最后发现应该是SROM的设置不对&#xff0c;发的数据高位都没有了。A公…

s3c2440 RTC(实时时钟) 驱动移植

———————————————————————————————————————主机操作系统&#xff1a;Centos 6.7交叉编译器环境&#xff1a;arm-linux-gcc-4.5.4 开发板平台&#xff1a; FL2440 Linux内核版本&#xff1a; linux-3.0 开发模块&#xff1a; RTC&#xf…

MSP430F149程序移植——0.96OLED(ssd1306驱动)

链接&#xff1a;https://pan.baidu.com/s/1ov-lE3sD2nMpV33Q9E7omw 提取码&#xff1a;2333 一、引脚说明 1.1 接口定义 引脚功能说明GND电源地VCC电源正 3.3~5VD0SPI接口时为SPI时钟线&#xff0c;IIC接口时为IIC时钟线D1SPI接口时为SPI数据线&#xff0c;IIC接口时为IIC数…

NUC970 SD卡驱动(SDIO)

在读取SD卡的R2长响应折腾了不少时间&#xff0c;原因是必须开启DMA&#xff0c;不开启DMA&#xff0c;R2响应将不会传输到SDIO的FIFO中&#xff0c;将SDIO接口与STM32保持一致&#xff0c;并兼容应用层SDIO_SDCARD驱动。 寄存器地址 //SDIO #define SDIO_BUFF_BASE …