Linux 字符设备驱动 之 无法归类的《杂项设备驱动》

学习目标:

了解 杂项设备驱动 和普通字符设备的异同,及杂项设备驱动程序的写法


学习内容:

一、杂项设备驱动的特别之处

杂项设备(Miscellaneous Devices)是一种通用的设备类型,用于表示那些不适合其他设备类型的设备。这些设备通常是不规则的,没有标准的通信协议或接口。

在Linux中,把无法归类的设备定义成杂项设备。相对于一般字符设备来说,杂项设备主设备号固定位10。而一般字符设备不管是动态分配还是静态分配设备号,都会一个区别其他类别的唯一主设备号。

杂项设备也会和一般的字符设备一样在/dev下创建设备节点。只是在编写设备驱动时用的函数大有不同。

二、杂项设备编写

1、miscdevice 结构体

杂项设备使用结构体miscdevice 描述,该结构体定义在 include/linux/misdevice.h 文件中。如下图所示:

其中,次设备号minor 一般使用宏 MISC_DYNAMIC_MINOR,表示自动分配次设备号。杂项设备主要依赖次设备号来管理。

#define MISC_DYNAMIC_MINOR 255

name: 就是要告诉系统创建设备节点的名称

fops: 就是系统调用 和 驱动功能的连接桥梁,即包含设备操作的 struct file_operations 结构的指针。

2、杂项设备的注册与卸载

注册和卸载杂项设备的函数声明在 include/linux/miscdevice.h 中,定义在drivers/char/misc.c 文件中。

注册函数 misc_register :

函数原型:int misc_register(struct miscdevice *misc);

参数:杂项设备的结构体指针

返回值:0:成功,负数:失败

卸载函数 misc_deregister:

函数原型:void misc_deregister(struct miscdevice *misc);

参数:杂项设备的结构体指针

3、代码

cpp 复制代码
#include <linux/module.h>
#include <linux/init.h>

#include <linux/fs.h>
#include <linux/miscdevice.h>

static int my_misc_open(struct inode *inode, struct file *file)
{
        printk("This is my_misc_open\n");
        return 0;
}

static ssize_t my_misc_read(struct file *file, char __user *buf, size_t size, loff_t *off)
{
        printk("This is my_misc_read\n");
        return 0;
}

static ssize_t my_misc_write(struct file *file, const char __user *buf, size_t size, loff_t *off)
{
        printk("copy_from_user kbuf = %s\n", kbuf);
        return 0;
}

static int my_misc_release(struct inode *inode, struct file *file)
{
        printk("This is my_misc_release\n");
        return 0;
}


static struct file_operations my_misc_ops={
        .owner = THIS_MODULE,
        .open = my_misc_open,
        .release = my_misc_release,
        .read = my_misc_read,
        .write = my_misc_write,
};

// 定义杂项设备结构体
struct miscdevice misc_dev={
        .minor = MISC_DYNAMIC_MINOR,
        .name = "my_misc",
        .fops = &my_misc_ops
};

// 驱动入口函数
static int module_misc_init(void)
{
        int ret = 0;

        ret = misc_register(&misc_dev);
        if(ret < 0)
        {
                printk("misc_register failed\n");
                return -1;
        }
        return 0;
}

// 驱动卸载函数
static void module_misc_exit(void)
{
        misc_deregister(&misc_dev);
        printk("misc_deregister test module bye!\n");
}

module_init(module_misc_init);
module_exit(module_misc_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("BF");
MODULE_VERSION("V1.0");

编译完成后,加载驱动,我们可以查看设备节点中是否创建了杂项设备my_misc,以及主设备号是不是之前说的10, 如图:

相关推荐
希忘auto14 小时前
详解Redis的常用命令
redis·1024程序员节
yaosheng_VALVE1 天前
探究全金属硬密封蝶阀的奥秘-耀圣控制
运维·eclipse·自动化·pyqt·1024程序员节
dami_king1 天前
SSH特性|组成|SSH是什么?
运维·ssh·1024程序员节
一个通信老学姐6 天前
专业125+总分400+南京理工大学818考研经验南理工电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
sheng12345678rui6 天前
mfc140.dll文件缺失的修复方法分享,全面分析mfc140.dll的几种解决方法
游戏·电脑·dll文件·dll修复工具·1024程序员节
huipeng9267 天前
第十章 类和对象(二)
java·开发语言·学习·1024程序员节
earthzhang20217 天前
《深入浅出HTTPS》读书笔记(19):密钥
开发语言·网络协议·算法·https·1024程序员节
爱吃生蚝的于勒8 天前
计算机基础 原码反码补码问题
经验分享·笔记·计算机网络·其他·1024程序员节
earthzhang20218 天前
《深入浅出HTTPS》读书笔记(20):口令和PEB算法
开发语言·网络协议·算法·https·1024程序员节
一个通信老学姐8 天前
专业140+总分410+浙江大学842信号系统与数字电路考研经验浙大电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节