Linux MISC 驱动

本贴最后更新于 1678 天前,其中的信息可能已经时移世异

misc 的意思是混合、杂项的,因此 MISC 驱动也叫做杂项驱动,其实就是最简单的字符设备驱
动,通常嵌套在 platform 总线驱动中,实现复杂的驱动。

所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。随着 Linux 字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号, MISC 设备驱动就用于解决此问题。 MISC 设备会自动创建 cdev,不需要手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。我们需要向 Linux 注册一个 miscdevice 设备, miscdevice 是一个结构体,定义在文件 include/linux/miscdevice.h 中,内容如下:

struct miscdevice { int minor; /* 子设备号 */ const char *name; /* 设备名字 */ const struct file_operations *fops; /* 设备操作集 */ struct list_head list; struct device *parent; struct device *this_device; const struct attribute_group **groups; const char *nodename; umode_t mode; };

定义一个 MISC 设备(miscdevice 类型)以后我们需要设置 minor、 name 和 fops 这三个成员变量。 minor 表示子设备号, MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在 include/linux/miscdevice.h 文件中,如下所示:

#define PSMOUSE_MINOR 1 #define MS_BUSMOUSE_MINOR 2 /* unused */ #define ATIXL_BUSMOUSE_MINOR 3 /* unused */ /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */ #define ATARIMOUSE_MINOR 5 /* unused */ #define SUN_MOUSE_MINOR 6 /* unused */ ...... #define MISC_DYNAMIC_MINOR 255

我们在使用的时候可以从这些预定义的子设备号中挑选一个,当然也可以自己定义,只要这个子设备号没有被其他设备使用接口。

name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name 的设备文件。 fops 就是字符设备的操作集合, MISC 设备驱动最终是需要使用用户提供的 fops 操作集合。当设置好 miscdevice 以后就需要使用 misc_register 函数向系统中注册一个 MISC 设备,此函数原型如下:

int misc_register(struct miscdevice * misc)

misc:要注册的 MISC 设备。
返回值: 负数,失败; 0,成功。

ps:之前创建设备的过程:

alloc_chrdev_region(); /* 申请设备号 */ cdev_init(); /* 初始化 cdev */ cdev_add(); /* 添加 cdev */ class_create(); /* 创建类 */ device_create(); /* 创建设备 */

杂项设备之需要调用 misc_register 即可完成上述繁杂的操作,misc_register 函数原型如下:

int misc_register(struct miscdevice *misc)

misc:杂项设备

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

ps:同样的注销设备驱动的时候,我们需要调用一堆的函数去删除此前创建的 cdev、设备等等内容,如下所示:

cdev_del(); /* 删除 cdev */ unregister_chrdev_region(); /* 注销设备号 */ device_destroy(); /* 删除设备 */ class_destroy(); /* 删除类 */

杂项只需要调用 misc_deregister 即可,函数原型如下:

int misc_deregister(struct miscdevice *misc)

misc:要注销的 MISC 设备。
返回值: 负数,失败; 0,成功。

一般杂项设备和 platform 配合使用,利用 platform 完成设备和驱动的分离,杂项设备简化字符设备的各种操作,一般用于一些简单驱动的编写。

example

struct miscxxx_dev misctest_dev; /* misc设备 */ /* * @description : 打开设备 * @param - inode : 传递给驱动的inode * @param - filp : 设备文件,file结构体有个叫做private_data的成员变量 * 一般在open的时候将private_data指向设备结构体。 * @return : 0 成功;其他 失败 */ static int miscxxx_open(struct inode *inode, struct file *filp) { filp->private_data = &miscxxx; /* 设置私有数据 */ return 0; } /* * @description : 向设备写数据 * @param - filp : 设备文件,表示打开的文件描述符 * @param - buf : 要写给设备写入的数据 * @param - cnt : 要写入的数据长度 * @param - offt : 相对于文件首地址的偏移 * @return : 写入的字节数,如果为负值,表示写入失败 */ static ssize_t miscxxx_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) { ...... return 0; } /* 设备操作函数 */ static struct file_operations miscxxx_fops = { .owner = THIS_MODULE, .open = miscxxx_open, .write = miscxxx_write, }; /* MISC设备结构体 */ static struct miscdevice xxx_miscdev = { .minor = MISCBEEP_MINOR, .name = MISCBEEP_NAME, .fops = &miscxxx_fops, }; /* * @description : flatform驱动的probe函数,当驱动与 * 设备匹配以后此函数就会执行 * @param - dev : platform设备 * @return : 0,成功;其他负值,失败 */ static int miscxxx_probe(struct platform_device *dev) { ...... /* 一般情况下会注册对应的字符设备,但是这里我们使用MISC设备 * 所以我们不需要自己注册字符设备驱动,只需要注册misc设备驱动即可 */ ret = misc_register(&xxx_miscdev); if(ret < 0){ printk("misc device register failed!\r\n"); return -EFAULT; } return 0; } /* * @description : platform驱动的remove函数,移除platform驱动的时候此函数会执行 * @param - dev : platform设备 * @return : 0,成功;其他负值,失败 */ static int miscxxx_remove(struct platform_device *dev) { /* 注销misc设备 */ misc_deregister(&xxx_miscdev); return 0; } /* 匹配列表 */ static const struct of_device_id xxx_of_match[] = { { .compatible = "xxxx" }, { /* Sentinel */ } }; /* platform驱动结构体 */ static struct platform_driver xxx_driver = { .driver = { .name = "xxxx", /* 驱动名字,用于和设备匹配 */ .of_match_table = xxx_of_match, /* 设备树匹配表 */ }, .probe = miscxxx_probe, .remove = miscxxx_remove, }; /* * @description : 驱动出口函数 * @param : 无 * @return : 无 */ static int __init xxx_init(void) { return platform_driver_register(&xxx_driver); } /* * @description : 驱动出口函数 * @param : 无 * @return : 无 */ static void __exit xxx_exit(void) { platform_driver_unregister(&xxx_driver); } module_init(xxx_init); module_exit(xxx_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("xxx");
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    950 引用 • 943 回帖
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖
  • 驱动
    10 引用 • 3 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 2 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • sts
    2 引用 • 2 回帖 • 225 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    693 引用 • 537 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 78 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 1 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    36 引用 • 37 回帖 • 545 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • 996
    13 引用 • 200 回帖 • 2 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    169 引用 • 1527 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    946 引用 • 1460 回帖
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    183 引用 • 1010 回帖
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    409 引用 • 3587 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 633 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    31 引用 • 108 回帖
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 595 回帖
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 4 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 739 回帖 • 1 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 56 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    586 引用 • 3538 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 6 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖