Linux MISC 驱动

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

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 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    952 引用 • 944 回帖
  • 笔记

    好记性不如烂笔头。

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

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • OpenCV
    15 引用 • 36 回帖 • 7 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 9 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    557 引用 • 675 回帖 • 1 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 3 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    495 引用 • 931 回帖
  • 叶归
    8 引用 • 36 回帖 • 17 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    174 引用 • 538 回帖
  • Access
    1 引用 • 3 回帖 • 2 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 758 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 504 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 400 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 688 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 241 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    133 引用 • 1124 回帖 • 107 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    6 引用 • 15 回帖 • 10 关注
  • AWS
    11 引用 • 28 回帖 • 7 关注
  • Mac

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

    168 引用 • 597 回帖
  • 数据库

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

    345 引用 • 747 回帖
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 336 关注
  • sts
    2 引用 • 2 回帖 • 230 关注
  • Follow
    4 引用 • 12 回帖 • 12 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 613 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 34 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 544 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 29 关注