一、设备号

1.1. 什么是设备号

设备号是用来标记一类设备以及区分这类设备中具体个体的一组号码。

设备号由主设备号和次设备号组成。主设备号的作用为标记一类设备、用于标识设备驱动程序,而次设备号的作用是为了区分这类设备中的具体个体设备及用于标识同一驱动程序下的具体设备;通过该区分,系统可以准确的识别和操作每一个设备和对设备的有效管理,提高设备的利用率和可扩展性。

在Linux中设备号的定义通常使用dev_t,该类型需要包含头文件include/linux/types.h,查看其定义我们可以发现它其实就是一个32位的无符号整型变量;其中主设备号为高12位(同类型驱动个数为0~212−10~2^{12}-102121),次设备号为低20位(挂载设备为0~220−10~2^{20}-102201)。

Linux中为我们提供了相关宏用于处理设备号,这些宏位于include/linux/kdev_t.h中:

#define MINORBITS 20      /* 次设备号位数 */
#define MINORMASK ((1U << MINORBITS) - 1)/* 获取主设备号 */
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
/* 获取次设备号 */
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
/* 主+次组成设备号 */
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

1.2. 设备号的获取、释放和查看

1.2.1. 获取设备号

获取设备号的方式有两种:静态分配和动态分配,都是Linux内核提供的接口,该接口位于linux/fs.h中。

  • 静态分配register_chrdev_region
    函数原型:
/*** register_chrdev_region() - register a range of device numbers* @from: the first in the desired range of device numbers; must include the major number.* @count: the number of consecutive device numbers required* @name: the name of the device or driver.** Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name);
  • 动态分配alloc_chrdev_region
    函数原型:
/*** alloc_chrdev_region() - register a range of char device numbers* @dev: output parameter for first assigned number* @baseminor: first of the requested range of minor numbers* @count: the number of minor numbers required* @name: the name of the associated device or driver** Allocates a range of char device numbers. The major number will be* chosen dynamically, and returned (along with the first minor number)* in @dev. Returns zero or a negative error code.*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);

1.2.2. 释放设备号

  • 释放设备号
    函数原型:
/*** unregister_chrdev_region() - return a range of device numbers* @from: the first in the range of numbers to unregister* @count: the number of device numbers to unregister** This function will unregister a range of @count device numbers,* starting with @from. The caller should normally be the one who* allocated those numbers in the first place...*/
void unregister_chrdev_region(dev_t from, unsigned count);

1.2.3. 查看设备号

  • 指令lsblk
    待补充
  • 查看文件/proc/devices
    通过cat /proc/devices将所有的设备号全部打印出来,如下:
Character devices: # 字符设备1 mem4 /dev/vc/04 tty4 ttyS
Block devices: # 块设备7 loop8 sd9 md
254 mdp
259 blkext

1.3. 栗子

驱动代码

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/kdev_t.h>int Isalloc = 0; /* 是否动态申请设备号:0-静态申请、非0-动态申请 */
int Major = 0;
int Minor = 0;module_param(Isalloc, int, S_IRUGO);
MODULE_PARM_DESC(Isalloc, "e.g.是否动态申请: 0-静态申请(需输入设备号),非0-动态申请(输入设备号无效).");
module_param(Major, int, S_IRUGO);
MODULE_PARM_DESC(Major, "e.g.主设备号");
module_param(Minor, int, S_IRUGO);
MODULE_PARM_DESC(Minor, "e.g.次设备号");dev_t chrdev_region = 0;static int chrdev_region_init(void)
{if (0 == Isalloc){/* 静态申请设备号 */chrdev_region = MKDEV(Major, Minor);/* zhf是驱动程序名称 */int i32Ret = register_chrdev_region(chrdev_region, 1, "zhf");if (0 > i32Ret){printk("register_chrdev_region err %d \n", i32Ret);}}else{/* 动态申请设备号 zhf是驱动程序名称 */int i32Ret = alloc_chrdev_region(&chrdev_region, 0, 1, "zhf");if (0 > i32Ret){printk("alloc_chrdev_region err %d \n", i32Ret);}}/* 设备号打印 */printk("chrdev region ok major:%d minor:%d\n", MAJOR(chrdev_region), MINOR(chrdev_region));return 0;
}static void chrdev_region_exit(void)
{/* 设备号销毁 */unregister_chrdev_region(&chrdev_region, 1);printk("unregister_chrdev_region ok \n");
}module_init(chrdev_region_init);
module_exit(chrdev_region_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhf");

二、字符设备驱动

2.1. 什么是字符设备

字符设备是一种用于传输字符或字节流的设备。其实就是传"acnah"这样的ASSIC码。常见的字符设备包括键盘、鼠标、串口等设备。字符设备以字节为单位进行读取和写入。

字符设备的交互方式:字符设备在系统中会被表示为设备文件,用户可通过打开设备文件与字符设备进行交互。

2.2. 字符设备的操作

2.2.1. 注册字符设备

定义字符类设备需要用到cd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91836.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91836.shtml
英文地址,请注明出处:http://en.pswp.cn/web/91836.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uboot armv8 启动流程之 linker script

section 详细说明.text按如下顺序&#xff0c;中断向量表vectors, 启动入口代码start.o,普通text, glue &#xff08;arm thumb2 相互调用时自动生成的代码&#xff09;*(.vectors)CPUDIR/start.o (.text*)*(.text*)*(.glue*)__image_copy_start 标记为text 段入口&#xff0c;…

xxljob总结

XXL-Job 支持多种任务类型&#xff0c;以下是常见任务类型的示例 Demo&#xff0c;包含核心配置和代码片段&#xff0c;帮助快速理解用法&#xff1a;一、Bean模式任务&#xff08;最常用&#xff09;通过注解 XxlJob 定义任务方法&#xff0c;直接在 Spring 容器中管理&…

Python包安全工程实践:构建安全可靠的Python生态系统

在现代计算环境中&#xff0c;性能往往是Python包成功的关键因素。本文将深入探讨Python包的性能优化技术&#xff0c;包括并发编程模型、性能分析工具、内存优化策略以及原生代码集成等高级主题&#xff0c;帮助你构建高性能的Python组件。1. 性能分析基础1.1 性能分析工具矩阵…

kubernetes基础知识

个人博客站—运维鹿: http://www.kervin24.top CSDN博客—做个超努力的小奚&#xff1a; https://blog.csdn.net/qq_52914969?typeblog一、kubernetes介绍Kubernetes本质是一组服务器集群&#xff0c;它可以在集群的每个节点上运行特定的程序&#xff0c;来对节点中的容器进行…

winntsetup安装驱动和光驱安装F6功能一样----NT5.2.3790源代码分析

D:\drv>dir驱动器 D 中的卷是 新加卷卷的序列号是 443D-D64BD:\drv 的目录2025-08-03 23:57 <DIR> . 2025-08-03 23:57 <DIR> .. 2008-05-27 10:01 119,068 yk51x86.cat 2008-05-20 10:01 969,380 yk51x86.inf…

Web 开发 11

今天完成了workshop2&#xff0c;进度有点慢&#xff0c;但是记录一下极为愚蠢的一轮轮问答和思考~&#xff01;&#xff08;还是有点成就感的&#xff09;ps&#xff1a;【】内为我的提问1 导入语句&#xff08;ES6 模块导入语法&#xff09;【import CatHappiness from "…

写作路上的迷茫与突破

曾经&#xff0c;我也是那个在写作面前踌躇不前的人。每次提笔&#xff0c;满心都是“我写不好”“我没什么可写的”“我达不到别人的高度”……这些念头像藤蔓一样&#xff0c;紧紧缠绕着我&#xff0c;让我寸步难行。我看着群里的小伙伴们一个个妙笔生花&#xff0c;自己却只…

23 Active Directory攻击与防护策略解析

引言 Active Directory&#xff08;AD&#xff09;是企业IT环境中用户认证、访问控制和身份管理的核心。因其掌握整个网络的"钥匙"&#xff0c;AD常成为攻击者的首要目标。 从凭证转储到隐蔽侦察&#xff0c;攻击者通过多种手段控制AD。无论您是网络安全分析师、红…

【内容规范】关于标题中【】标记的使用说明

【内容规范】关于标题中【】标记的使用说明 在信息爆炸的时代&#xff0c;如何让内容更易识别、更具条理性&#xff0c;成为内容创作者和平台运营者共同关注的问题。标题中【】标记的使用&#xff0c;正是在这种需求下形成的一种实用规范。 这种规范的核心作用在于建立统一的内…

centos 9 安装docker教程

拉取相关依赖 dnf -y install dnf-plugins-core设置阿里云镜像库 dnf config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plu…

关闭Jetbrains Mono字体连写、连字功能

所谓的关闭Jetbrains Mono字体连写&#xff0c;其实就是更换为Jetbrains Mono NL字体二者的区别就是符号间距的大小不同&#xff0c;也就是有无连字功能。 下图以Visutal Studio为例&#xff1a;

漫花软件集合分享

漫花软件集合分享的各种apk 1、磁盘漫画【推荐】 2、你搜 3、皮皮喵 4、泼辣漫画 5、趣漫画 6、异次元&图源 7、漫 8、再漫画X 9、章鱼漫画 10、芝士漫画&图源 通过网盘分享的文件&#xff1a;漫画软件 链接: https://pan.baidu.com/s/1dlGl50MNzzVOdTP38_…

DB-GPT 0.7.3 版本更新:支持Qwen3 Embedding和Reranker模型、支持知识库自定义检索策略等

V0.7.3版本主要新增、增强了以下核心特性 &#x1f340; 支持Qwen3 Embedding和Reranker模型 &#x1f340; 支持知识库自定义检索策略&#xff1a;语义检索、全文检索、树形检索、混合检索等 &#x1f340; 新增GaussDB数据源支持 &#x1f340; 支持GLM-4.1V多模态模型 …

Django常见模型字段

AutoField:数据库中的自动增长类型&#xff0c;相当于ID自动增长的IntegerField类型字段&#xff0c;对应mysql的Int类型 BooleanField:真/假的布尔类型字段&#xff0c;对应mysql的Tinyint类型 CharField:字符类型字段&#xff0c;对应mysql的varChar类型 DateField:日期字段&…

前端列表封面图如何自不同图片比例不变形

设置图片宽度100%时&#xff0c;若不设置高度&#xff0c;可能导致高度不足导致空白区域。如何实现图片高度自适应填充&#xff0c;避免空白区域&#xff1f;解决方式&#xff1a;加上height&#xff1a;100%&#xff1b;object-fit:cover&#xff1b;就可以始终剪切铺满&#…

记录一次Spring Cloud Gateway配置的跨域处理:解决 ‘Access-Control-Allow-Origin‘ 头包含多个值的问题

在微服务架构中&#xff0c;前端与后端分离已经成为一种常见模式。这种模式下&#xff0c;前后端通常会部署在不同的域名或端口上&#xff0c;这就导致了跨域资源共享&#xff08;CORS&#xff09;问题。最近&#xff0c;在我们的项目中&#xff0c;我们遇到了这样一个问题&…

扫雷游戏完整代码

扫雷游戏完整代码test.cgame.cgame.h

vue打包后如何在本地运行?

1.打包前的配置打开vue.config.js配置如图所示内容//打包配置文件 module.exports {assetsDir: static,parallel: false,publicPath: ./, };这段代码是Vue.js项目的打包配置文件&#xff0c;主要功能包括&#xff1a; - assetsDir: static - 设置静态资源文件夹名为static - p…

Python特性工厂函数详解:优雅管理属性验证

在Python中&#xff0c;特性(property)是一种强大的工具&#xff0c;它允许我们在访问属性时执行自定义逻辑。本文将深入分析一个名为quantity的特性工厂函数&#xff0c;它用于确保属性值必须为正数。 特性工厂函数的概念 特性工厂函数是一种创建并返回property对象的函数&…

Ubuntu系统VScode实现opencv(c++)鼠标操作与响应

在之前的创作中心-CSDN滚动条调整图片亮度-CSDN博客创作中心-CSDN中,我们已经了解了滚动条实现亮度以及对比度调节,为了实现对图像中感兴趣区域&#xff08;ROI, Region of Interest&#xff09;的交互式选取&#xff0c;本文利用 OpenCV 提供的鼠标事件回调机制&#xff0c;设…