杂项设备(misc device)在Linux内核驱动开发中有以下典型应用场景:
1. 简单字符设备的快速注册
- 适用于功能相对简单、不需要复杂设备管理的字符设备
- 自动分配主设备号(固定为10),只需关心次设备号
- 简化了传统字符设备的注册流程(无需手动申请设备号、创建类和设备节点)
2. 系统级小工具驱动
- 看门狗定时器(watchdog)
- 温度传感器读取
- LED控制
- 蜂鸣器控制
- 按键输入处理
3. 硬件抽象层
- 为上层应用提供简单的硬件访问接口
- 例如:GPIO控制、I2C/SPI设备访问、ADC读取等
4. 调试和测试设备
- 内核模块开发时的测试驱动
- 提供简单的读写接口用于验证内核与用户空间通信
5. 特殊功能设备
- 随机数生成器(/dev/random, /dev/urandom)
- 内存映射设备(/dev/mem, /dev/kmem)
- 日志设备(/dev/kmsg)
杂项设备的优势:
✅ 简化注册流程:只需调用 misc_register(),自动完成设备号分配、设备节点创建
✅ 统一管理:所有杂项设备共享主设备号10,便于系统管理
✅ 自动创建设备节点:在 /dev/ 下自动生成设备文件
✅ 适合小型驱动:代码量少,结构清晰
代码:007_misc.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
static int test_open(struct inode *inode,struct file *file)
{
printk("open\n");
return 0;
}
static ssize_t test_read(struct file *file,char __user *buf, size_t size,loff_t *off){
printk("read\n");
return 0;
}
static ssize_t test_write(struct file *file,const char __user *buf, size_t size,loff_t *off){
*off += size;
printk("write\n");
return size;
}
static int test_release(struct inode *inode,struct file *file)
{
printk("release\n");
return 0;
}
struct file_operations fops = {
.owner = THIS_MODULE,
.open = test_open,
.read = test_read,
.write = test_write,
.release = test_release,
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wyl");
MODULE_DESCRIPTION("007_misc");
// 杂项设备
static struct miscdevice misc_dev = {
.minor = MISC_DYNAMIC_MINOR, //自动分配从设备号
.name = "007_misc", //设备名称
.fops = &fops,
};
static int modulecdev_init(void)
{
int ret;
ret = misc_register(&misc_dev);
if(ret<0){
printk(KERN_ERR "misc_register failed!\n");
return ret;
}
printk(KERN_INFO "misc_register success!\n");
return 0;
}
static void modulecdev_exit(void)
{
misc_deregister(&misc_dev); //卸载
printk("modulecdev exit\n");
}
module_init(modulecdev_init);
module_exit(modulecdev_exit);