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, 如图:

相关推荐
惜.己4 小时前
Jmeter中的断言(二)
测试工具·jmeter·1024程序员节
西电研梦13 小时前
考研倒计时30天丨和西电一起向前!再向前!
人工智能·考研·1024程序员节·西电·西安电子科技大学
惜.己14 小时前
Jmeter中的断言(四)
测试工具·jmeter·1024程序员节
·云扬·1 天前
Java IO 与 BIO、NIO、AIO 详解
java·开发语言·笔记·学习·nio·1024程序员节
网安_秋刀鱼1 天前
PHP代码审计 --MVC模型开发框架&rce示例
开发语言·web安全·网络安全·php·mvc·1024程序员节
HUODUNYUN1 天前
小程序免备案:快速部署与优化的全攻略
服务器·网络·web安全·小程序·1024程序员节
惜.己2 天前
Jmeter的后置处理器(二)
测试工具·github·1024程序员节
惜.己2 天前
Jmeter中的断言(一)
测试工具·jmeter·1024程序员节
cainiao0806052 天前
《物理学进展》
1024程序员节·核心期刊·知网期刊·职称评审
FFDUST2 天前
C++ —— string类(上)
c语言·开发语言·数据结构·c++·stl·1024程序员节