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

6.misc杂项

Misc(杂项设备)

1. 什么是 Misc

Misc(Miscellaneous Device,杂项设备)是 Linux 提供的一种简化字符设备驱动框架,本质上仍然属于字符设备。

对于 LED、蜂鸣器、ADC 等功能较为简单的设备,如果仍然按照普通字符设备的方式编写驱动,需要完成:

  • 申请设备号
  • 初始化cdev
  • 添加cdev
  • 创建class
  • 创建设备节点

这些步骤在很多驱动中都是重复的,因此 Linux 将这些公共代码进行了封装,形成了Misc 驱动框架

开发者只需要:

  • 定义miscdevice
  • 编写file_operations
  • 调用misc_register()

即可完成字符设备注册,大大减少了代码量。


2. Misc 与普通字符设备的区别

普通字符设备注册流程:

申请设备号 │ ▼ alloc_chrdev_region() │ ▼ cdev_init() │ ▼ cdev_add() │ ▼ class_create() │ ▼ device_create() │ ▼ 生成 /dev/xxx

Misc 注册流程:

填写 miscdevice │ ▼ misc_register() │ ▼ 自动完成以上所有步骤

因此:

misc_register() ≈ alloc_chrdev_region() + cdev_init() + cdev_add() + class_create() + device_create()

3. 设备树修改

3.1 添加 Beep 节点

beep { compatible = "alientek,beep"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_beep>; beep-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>; status = "okay"; };

各属性说明:

属性说明
compatible与 Platform Driver 进行匹配
pinctrl-names默认使用的引脚配置
pinctrl-0指向具体的引脚配置节点
beep-gpio指定蜂鸣器所使用的 GPIO
status"okay"表示启用设备

3.2 添加 pinctrl 节点

iomuxc_snvs节点下添加:

pinctrl_beep: beepgrp { fsl,pins = < MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x10B0 >; };

说明:

配置作用
pinctrl_beep标签,供其它节点引用
beepgrp节点名称
MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01将引脚复用为 GPIO5_IO01
0x10B0PAD 电气属性配置

4. 驱动主体框架

整个 Misc + Platform 驱动主要由六部分组成:

Platform Driver │ ├── file_operations 字符设备操作集 ├── miscdevice Misc设备描述 ├── probe() 设备初始化 ├── remove() 设备移除 ├── of_match_table 设备树匹配 └── platform_driver Platform驱动

5. 驱动模板

#include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#include<linux/fs.h>#include<linux/uaccess.h>#include<linux/gpio.h>#include<linux/of.h>#include<linux/of_gpio.h>#include<linux/platform_device.h>#include<linux/miscdevice.h>#defineXXX_NAME"xxx"#defineXXX_MINOR144/*--------------------设备结构体--------------------*/structxxx_dev{structdevice_node*nd;intxxx_gpio;};staticstructxxx_devxxx;/*--------------------open--------------------*/staticintxxx_open(structinode*inode,structfile*filp){filp->private_data=&xxx;return0;}/*--------------------release--------------------*/staticintxxx_release(structinode*inode,structfile*filp){return0;}/*--------------------write--------------------*/staticssize_txxx_write(structfile*filp,constchar__user*buf,size_tcount,loff_t*ppos){intret;unsignedchardatabuf[1];structxxx_dev*dev=filp->private_data;ret=copy_from_user(databuf,buf,count);if(ret)return-EFAULT;if(databuf[0])gpio_set_value(dev->xxx_gpio,1);elsegpio_set_value(dev->xxx_gpio,0);returncount;}/*--------------------文件操作集--------------------*/staticconststructfile_operationsxxx_fops={.owner=THIS_MODULE,.open=xxx_open,.write=xxx_write,.release=xxx_release,};/*--------------------Misc设备--------------------*/staticstructmiscdevicexxx_miscdev={.minor=XXX_MINOR,.name=XXX_NAME,.fops=&xxx_fops,};/*--------------------probe--------------------*/staticintxxx_probe(structplatform_device*pdev){intret;/* 1. 获取设备树节点 */xxx.nd=pdev->dev.of_node;/* 2. 获取GPIO */xxx.xxx_gpio=of_get_named_gpio(xxx.nd,"xxx-gpio",0);if(xxx.xxx_gpio<0)return-EINVAL;/* 3. 申请GPIO */ret=gpio_request(xxx.xxx_gpio,"xxx-gpio");if(ret)returnret;/* 4. 设置GPIO方向 */ret=gpio_direction_output(xxx.xxx_gpio,1);if(ret)gotofail_gpio;/* 5. 注册Misc设备 */ret=misc_register(&xxx_miscdev);if(ret)gotofail_gpio;printk("probe success!\n");return0;fail_gpio:gpio_free(xxx.xxx_gpio);returnret;}/*--------------------remove--------------------*/staticintxxx_remove(structplatform_device*pdev){gpio_set_value(xxx.xxx_gpio,1);gpio_free(xxx.xxx_gpio);misc_deregister(&xxx_miscdev);printk("remove success!\n");return0;}/*--------------------设备树匹配表--------------------*/staticconststructof_device_idxxx_of_match[]={{.compatible="manufacturer,xxx"},{},};/*--------------------Platform Driver--------------------*/staticstructplatform_driverxxx_driver={.driver={.name="xxx",.of_match_table=xxx_of_match,},.probe=xxx_probe,.remove=xxx_remove,};/*--------------------驱动入口--------------------*/staticint__initxxx_init(void){returnplatform_driver_register(&xxx_driver);}/*--------------------驱动出口--------------------*/staticvoid__exitxxx_exit(void){platform_driver_unregister(&xxx_driver);}module_init(xxx_init);module_exit(xxx_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("huangjiajing");

6. probe() 初始化流程

Platform 总线匹配成功后,会自动调用probe()

整个初始化流程如下:

Platform匹配成功 │ ▼ probe() │ ├──① 获取设备树节点 ├──② 获取GPIO编号 ├──③ 申请GPIO资源 ├──④ 设置GPIO方向 ├──⑤ 注册Misc设备 │ ▼ 生成 /dev/xxx

其中:

misc_register(&xxx_miscdev);

放在最后执行。

原因是:

只有 GPIO 等硬件资源全部初始化完成后,才允许用户访问/dev/xxx,避免设备尚未初始化完成就被应用程序打开。

因此 Linux 驱动遵循:

先初始化硬件,再注册设备。


7. remove() 流程

驱动卸载时,Linux 会自动调用remove()

主要完成以下工作:

remove() │ ├──关闭设备 ├──释放GPIO ├──注销Misc设备 └──释放资源

对应代码:

gpio_set_value(xxx.xxx_gpio,1);gpio_free(xxx.xxx_gpio);misc_deregister(&xxx_miscdev);

8. 开发流程总结

修改设备树 │ ▼ 添加 compatible │ ▼ 编写 file_operations │ ▼ 定义 miscdevice │ ▼ 编写 probe() │ ├──获取设备树 ├──获取GPIO ├──申请GPIO ├──配置GPIO └──misc_register() │ ▼ 编写 remove() │ ├──misc_deregister() └──gpio_free() │ ▼ 注册 Platform Driver │ ▼ Platform 自动匹配 │ ▼ 调用 probe() │ ▼ 生成 /dev/xxx

9. 使用模板时需要修改的内容

修改位置蜂鸣器LED
XXX_NAME"miscbeep""miscled"
XXX_MINOR144145
struct xxx_devbeep_gpioled_gpio
GPIO 属性"beep-gpio""led-gpio"
compatible"alientek,beep""atkalpha,gpioled"
GPIO 控制逻辑控制蜂鸣器高低电平控制 LED 高低电平
.name"miscbeep""gpioled"

10. 普通字符设备与 Misc 对比

普通字符设备Misc 杂项设备
alloc_chrdev_region()misc_register()
cdev_init()不需要
cdev_add()不需要
class_create()不需要
device_create()不需要
device_destroy()misc_deregister()
class_destroy()不需要
unregister_chrdev_region()不需要
代码量较多代码量少,开发效率高

总结:Misc 本质上仍然是字符设备,只是 Linux 对字符设备注册流程进行了封装。对于 LED、蜂鸣器、按键、ADC 等简单外设,优先使用 Misc 驱动可以减少大量重复代码,提高开发效率。

http://www.jsqmd.com/news/1171600/

相关文章:

  • 别再死磕KFS黄金公式了!今年在小红书拿结果的商家,都在偷偷用这套“反同质化”野路子
  • A3908与PIC18F4585实现精密运动控制方案解析
  • 2026扬州漏水检测维修口碑榜TOP5权威推荐:正规防水补漏公司甄选-卫生间/厨房/阳台/屋顶/地下室渗漏水精准查漏:房屋防水补漏避坑指南 - 安佳防水
  • 自动驾驶控制算法落地的七道生死关与MATLAB工业实践
  • 人形机器人商业化真相:物理瓶颈比算法更致命
  • 工业级推荐系统链路实战:召回/粗排/精排/重排4阶段全流程解析与3个关键决策点
  • Arduino IDE 1.8.x 多文件工程管理:3种.h/.cpp组织方式与编译避坑
  • 用NumPy精准掌控数据分布:从统计特征到随机生成
  • HKDSE备考零基础,哪家机构通过率最高有保障?
  • 海钓抽马鲛铁板首选推荐:鲛狼远投速沉铁板
  • Unity动态背景音乐系统:从单例管理器到Audio Mixer的实战实现
  • 软件著作权登记实战指南:从材料准备到中国版权保护中心在线申请的7个步骤
  • ADP5350与PIC18F2525的嵌入式电源管理方案设计
  • 用 WorkBuddy 一小时做出「华语之境」中文学习 App 原型
  • TDA7468与PIC24FJ128GA310音频处理系统设计与优化
  • 齐次变换矩阵:从数学推导到ROS TF库的3个核心应用实例
  • 人形机器人本质是物理智能系统而非AI秀场
  • 基于Levenberg-Marquardt算法的椭圆中心检测C++实战
  • HDFS 文件操作性能对比:`-put` vs `-copyFromLocal` 等 5 对命令的差异与选择
  • 2026浙江省企业GEO布局指南:GEO平台核心能力拆解与核验要点 - 企智芯
  • Arcadia本地智能体工作流基建:Rust+Python轻量编排框架
  • Keil C51 中断号补丁实战:3步突破31限制,支持256中断向量
  • DevEco Code的Plan+Build模式:审方案再执行,重塑高效开发流程
  • 液化天然气制甲烷首次应用于长征系列火箭
  • 怎么找到专业靠谱的 AI 技术老师?4 项硬核筛选标准
  • UniOcc:自动驾驶占用预测的统一基准与实战指南
  • 苹果起诉OpenAI涉嫌窃取商业机密,AI硬件竞争引发关注
  • 遗传算法求解N皇后问题:Python从零实现与工程落地
  • 2026湖北CPPM培训避坑指南:如何辨别机构的靠谱程度? - 企智芯
  • 2026年酒店管理系统怎么选?瑞通酒店管理系统深度评测与横向对比