当前位置: 首页 > backend >正文

驱动——miscdevice框架 vs 标准字符设备cdev框架

二者本质都是 Linux 内核中字符设备的实现方式,但 miscdevice 是 cdev 的 “简化子集”,针对特定场景做了封装优化,以下是详细对比:
  • 标准 cdev 框架:是 Linux 内核字符设备的通用基础框架,所有字符设备(包括 miscdevice 管理的设备)最终都依赖 cdev 结构体实现内核与用户空间的交互。它没有场景限制,提供最完整的字符设备控制能力。
  • miscdevice 框架:是内核为简单字符设备(如传感器、LED、按键等)设计的简化封装框架,本质是在 cdev 基础上做了 “预配置 + 自动化”,减少开发者的重复代码(如设备号管理、注册流程简化)。
维度miscdevice 框架标准 cdev 框架
主设备号固定为 10(内核预定义的 MISC_MAJOR),开发者无需关注主设备号分配。手动指定或动态申请
- 静态指定:需确保主设备号未被其他设备占用(如 MKDEV(240, 0));
- 动态申请:通过 alloc_chrdev_region() 让内核分配未使用的主设备号,避免冲突。
次设备号自动分配:开发者只需将 miscdevice 结构体的 minor 字段设为 MISC_DYNAMIC_MINOR,内核会自动分配一个未使用的次设备号;也可手动指定次设备号(需确保未占用)。完全手动管控:需明确指定次设备号范围(如 “次设备号 0~3” 对应 4 个同类型设备),且需通过 register_chrdev_region()(静态)或 alloc_chrdev_region()(动态)向内核注册。
冲突风险极低:主设备号固定且唯一,次设备号由内核自动分配,无需担心冲突。较高:若手动指定主设备号,可能与其他设备冲突;需开发者自行确保设备号唯一性(或依赖动态申请规避)。
开发复杂度无设备号管理成本,无需写设备号申请 / 释放代码。需手动处理 “申请→注册→释放” 全流程,且需在注销时回滚(如注册失败后需释放已申请的设备号)。

可以理解为:cdev 是 “手动挡汽车”(功能全、需手动控制细节),miscdevice 是 “自动挡汽车”(针对日常场景优化、操作简单,但功能有一定限制)

1. miscdevice 框架(简化版字符设备)
  • 核心特点:主设备号固定为 10(内核预定义),次设备号自动分配,无需手动管理设备号,注册 / 注销接口简化。
  • 适用场景:简单字符设备(如传感器、LED 驱动等),无需复杂设备号规划。

示例代码(注册流程)

#include <linux/miscdevice.h>// 定义文件操作集
static const struct file_operations dht11_fops = {.owner = THIS_MODULE,.read = dht11_read,  // 读数据函数.write = dht11_write,// 写控制函数
};// 定义杂项设备结构体
static struct miscdevice dht11_misc = {.minor = MISC_DYNAMIC_MINOR,  // 自动分配次设备号.name = "dht11",              // 设备名(/dev/dht11).fops = &dht11_fops,          // 绑定操作集
};// 注册设备
int dht11_init(void) {return misc_register(&dht11_misc);  // 一步完成注册
}// 注销设备
void dht11_exit(void) {misc_deregister(&dht11_misc);      // 一步完成注销
}
2. 标准 cdev 框架(通用字符设备)
  • 核心特点:需手动分配主 / 次设备号(静态指定或动态申请),需显式初始化 cdev 结构体并关联操作集。
  • 适用场景:复杂字符设备(如多设备节点、自定义设备号规划)。

示例代码(注册流程)

#include <linux/cdev.h>static dev_t dht11_devno;        // 设备号(主+次)
static struct cdev dht11_cdev;   // cdev结构体
static const struct file_operations dht11_fops = { /* 同上 */ };int dht11_init(void) {int ret;// 1. 分配设备号(动态申请)ret = alloc_chrdev_region(&dht11_devno, 0, 1, "dht11");if (ret) return ret;// 2. 初始化cdev并绑定操作集cdev_init(&dht11_cdev, &dht11_fops);dht11_cdev.owner = THIS_MODULE;// 3. 添加cdev到内核ret = cdev_add(&dht11_cdev, dht11_devno, 1);if (ret) {unregister_chrdev_region(dht11_devno, 1); // 失败回滚return ret;}return 0;
}void dht11_exit(void) {cdev_del(&dht11_cdev);                      // 移除cdevunregister_chrdev_region(dht11_devno, 1);   // 释放设备号
}
http://www.xdnf.cn/news/19453.html

相关文章:

  • Android开发之add方式添加Fragment生命周期不响应
  • 单例模式
  • Selenium 自动化测试实战:绕过登录直接获取 Cookie
  • 希尔排序。
  • Java面试-微服务(业务问题)
  • QT控件QPlainTextEdit、QTextEdit与QTextBrowser的区别
  • 【秋招笔试】2025.08.31小红书秋招笔试真题
  • 解读数据中台建设汇报方案【附全文阅读】
  • 淘天二面总结
  • 链表算法知识汇总
  • lesson51:CSS全攻略:从基础样式到前沿特性的实战指南
  • 【读论文】量子关联增强双梳光谱技术
  • RabbitMinQ(模拟实现消息队列项目)02
  • 【零碎小知识点 】(四) Java多线程编程深入与实践
  • Spring Cloud ------ Gateway
  • 阿里Qoder怎么样?实测对比TRAE SOLO 和 CodeBuddy IDE
  • 【甲烷数据集】全球逐日无缝隙柱平均干空气甲烷浓度(XCH₄)
  • Solid Explorer文件管理器:功能强大的安卓文件管理器及网盘文件管理器
  • FFMPEG AAC
  • 【MySQL详解】索引、事务、锁、日志
  • 【MySQL基础】MySQL核心操作全解析
  • GPT - 5 技术前瞻与开发者高效接入路径探索​
  • Java-113 深入浅出 MySQL 扩容全攻略:触发条件、迁移方案与性能优化
  • Java实现图像像素化
  • VirtualBox7.2安装步骤
  • RT-DETR网络结构
  • 开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信
  • LangChain VectorStores核心:多向量数据库统一交互层与RAG存储中枢
  • 云原生新手入门完整学习指南
  • 14:00面试,15:00就出来了,问的问题过于变态了。。。