Linux---MISC杂项驱动
一、MISC 驱动简介
MISC 驱动其实就是最简单的字符设备驱动,所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。
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;
};
miscdevice 结构体中的name 就是此 MISC 设备名字,当此设备注册成功以后就会在/dev 目录下生成一个名为 name的设备文件(后面驱动实例我们会看到这一点)。 fops 就是字符设备的操作集合, MISC 设备驱动最终是需要使用用户提供的 fops操作集合。
当设置好 miscdevice 以后就需要使用 misc_register 函数向系统中注册一个 MISC 设备,此函数原型如下:
int misc_register(struct miscdevice * misc)
MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在include/linux/miscdevice.h 文件中,如下所示:
/** These allocations are managed by device@lanana.org. If you use an* entry that is not in assigned your entry may well be moved and* reassigned, or set dynamic if a fixed value is not justified.*/#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 APOLLO_MOUSE_MINOR 7 /* unused */
#define PC110PAD_MINOR 9 /* unused */
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
#define WATCHDOG_MINOR 130 /* Watchdog timer */
#define TEMP_MINOR 131 /* Temperature Sensor */
#define RTC_MINOR 135
#define EFI_RTC_MINOR 136 /* EFI Time services */
#define VHCI_MINOR 137
#define SUN_OPENPROM_MINOR 139
#define DMAPI_MINOR 140 /* unused */
#define NVRAM_MINOR 144
#define SGI_MMTIMER 153
#define STORE_QUEUE_MINOR 155 /* unused */
#define I2O_MINOR 166
#define MICROCODE_MINOR 184
#define VFIO_MINOR 196
#define TUN_MINOR 200
#define CUSE_MINOR 203
#define MWAVE_MINOR 219 /* ACP/Mwave Modem */
#define MPT_MINOR 220
#define MPT2SAS_MINOR 221
#define MPT3SAS_MINOR 222
#define UINPUT_MINOR 223
#define MISC_MCELOG_MINOR 227
#define HPET_MINOR 228
#define FUSE_MINOR 229
#define KVM_MINOR 232
#define BTRFS_MINOR 234
#define AUTOFS_MINOR 235
#define MAPPER_CTRL_MINOR 236
#define LOOP_CTRL_MINOR 237
#define VHOST_NET_MINOR 238
#define UHID_MINOR 239
#define USERIO_MINOR 240
#define MISC_DYNAMIC_MINOR 255
字符设备驱动中我们常常会使用如下几个函数完成设备创建过程:
1 alloc_chrdev_region(); /* 申请设备号 */
2 cdev_init(); /* 初始化 cdev */
3 cdev_add(); /* 添加 cdev */
4 class_create(); /* 创建类 */
5 device_create(); /* 创建设备 */
现在我们可以直接使用 misc_register 一个函数来完成上面代码中的这些步骤。
二、MISC驱动实例
这个驱动代码是由之前写过的一个led点灯代码改造而来,我们主要看下一led_gpio_probe() 函数中misc_register() 的使用,它简化了我们创建设备所需要的一系列步骤。
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>static struct gpio_desc *led_gpio;#define MISCLED_NAME "miscled" /* 名字 */
#define MISCLED_MINOR 145static int led_drv_open(struct inode *node, struct file *file)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);gpiod_direction_output(led_gpio, 0);return 0;
}static int led_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset)
{int status = 0;int result = 0;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);status = gpiod_get_value(led_gpio);result = copy_to_user(buf, &status, 1);return 1;
}static int led_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int result;char status;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);result = copy_from_user(&status, buf, 1);gpiod_set_value(led_gpio, status);return 1;
}static int led_drv_release(struct inode *node, struct file *file)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}
/*面朝大海0902*/
static struct file_operations led_drv =
{.owner = THIS_MODULE,.open = led_drv_open,.read = led_drv_read,.write = led_drv_write,.release = led_drv_release,
};/* MISC 设备结构体 */
static struct miscdevice led_miscdev = {.minor = MISCLED_MINOR,
.name = MISCLED_NAME,
.fops = &led_drv,
};static int led_gpio_probe(struct platform_device *pdev)
{int ret =0;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);led_gpio = gpiod_get(&pdev->dev, "led", 0);if(IS_ERR(led_gpio)){printk(KERN_ERR "gpiod_get is err\r\n");return -1;}ret = misc_register(&led_miscdev);if(ret < 0){printk("misc device register failed!\r\n");return -EFAULT;}return 0;
}
/*面朝大海0902*/
static int led_gpio_remove(struct platform_device *pdev)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);misc_deregister(&led_miscdev);gpiod_put(led_gpio);return 0;
}
static const struct of_device_id my_led[] =
{{.compatible = "my,led_driver"},{},
};static struct platform_driver led_gpio_driver =
{.probe = led_gpio_probe,.remove = led_gpio_remove,.driver = {.name = "led_gpio",.of_match_table = my_led,},
};static int __init led_init(void)
{int result;printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);result = platform_driver_register(&led_gpio_driver);return result;
}static void __exit led_exit(void)
{printk(KERN_INFO "%s %s line is %d \r\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&led_gpio_driver);
}module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
/*面朝大海0902*/
驱动加载并且与设备中的device匹配之后,我们在/dev目录下面看到一个名为"miscled"的设备,主设备号为10,此设备号为145,与我们代码设置的一致。
三、MISC实例测试
编写一个简单的测试程序,write()和read()设备节点,进而触发驱动fops文件操作函数。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>/** ./ledtest /dev/miscled on* ./ledtest /dev/miscled off*/
int main(int argc, char **argv)
{int fd;char status;/* 1. 判断参数 */if (argc != 3) {printf("Usage: %s <dev> <on | off>\n", argv[0]);return -1;}/* 2. 打开文件 */fd = open(argv[1], O_RDWR | O_NONBLOCK);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 写文件 */if (0 == strcmp(argv[2], "on")){status = 1;write(fd, &status, 1);}else{status = 0;write(fd, &status, 1);}read(fd, &status, 1);printf("status is %d\n", status);close(fd);return 0;
}
在开发板上进行测试,打印如下:
[root@Joy:/dev]# /mnt/misc_test /dev/miscled on
[ 1133.332943] /home/book/code/test/misc_drv.c led_drv_open line is 27
[ 1133.340139] /home/book/code/test/misc_drv.c led_drv_write line is 46
[ 1133.352154] /home/book/code/test/misc_drv.c led_drv_read line is 36
status is 1
[ 1133.360455] /home/book/code/test/misc_drv.c led_drv_release line is 54[root@Joy:/dev]# /mnt/misc_test /dev/miscled off
[ 1146.420773] /home/book/code/test/misc_drv.c led_drv_open line is 27
[ 1146.428629] /home/book/code/test/misc_drv.c led_drv_write line is 46
[ 1146.436893] /home/book/code/test/misc_drv.c led_drv_read line is 36
status is 0
[ 1146.445773] /home/book/code/test/misc_drv.c led_drv_release line is 54
/*面朝大海0902*/
可以看到fops对应的操作函数得到执行,比起普通的字符设备驱动MISC更加精简一些。
/面朝大海0902/
Linux---MISC杂项驱动相关推荐
- platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架
platform框架 input. pinctrl. gpio 子系统都是 Linux 内核针对某一类设备而创建的框架, input子系统是管理输入的子系统 pinctrl 子系统重点是设置 PIN( ...
- 嵌入式linux MISC设备驱动
misc 的意思是混合.杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某 些外设无法进行分类的时候就可以使用 MISC 驱动.MISC 驱动其实就是最简单的字符设备驱 动,通常嵌套在 ...
- linux MISC设备驱动
系列文章 I.MX6ULL 手册查找使用方法 实战点亮LED(寄存器版) I.MX6ULL 手册查找使用方法 实战点亮LED(固件库版本) linux 字符设备驱动实战 linux LED设备驱动文件 ...
- Linux MISC 驱动实验
目录 MISC 设备驱动简介 硬件原理图分析 实验程序编写 修改设备树 beep 驱动程序编写 编写测试APP 运行测试 编译驱动程序和测试APP 运行测试 misc 的意思是混合.杂项的,因此MIS ...
- linux MISC 驱动模型分析
linux MISC 驱动模型分析 阅读led驱动程序的代码的时候,没有发现ldd3中提到的各种字符设备注册函数,而是发现了一个misc_register函数,这说明led设备是作为杂项设备出现在内核 ...
- linux 杂项设备,浅谈 MISC杂项设备
在虚拟机的 Ubuntu 系统上,如下图所示,使用命令"cat /proc/misc",可以查看到 PC 机 Ubuntu 系统的杂项设备. 启动开发板,在超级终端中输入命令&qu ...
- 韦东山 IMX6ULL和正点原子_正点原子Linux第五十七章Linux MISC驱动实验
1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第五十七章Linux MISC驱动实验 misc的意思是 ...
- Linux MISC 驱动实验-基于正点原子IMX6ULL开发板
misc 的意思是混合.杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动.MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 p ...
- Linux 驱动开发 四十六:Linux MISC驱动实验
misc 的意思是混合.杂项的,因此MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动. MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 p ...
- Misc杂项设备驱动框架
Misc杂项设备驱动框架 由于设备号比较紧张,所以一些不相关的设备可以使用同一个主设备号,不同的次设备号.主设备号通常是10. 杂项设备结构体 struct miscdevice {int minor ...
最新文章
- 求n!中含有质因子p的个数
- (JAVA学习笔记) 关于方法的递归-阶乘方法演示
- .Net下几种日志管理方法
- 南科大计算机系实力a,五大竞赛学科A+高校排行榜发布!北大实力碾压,科大赶超清华...
- xshell进入桌面_Xshell怎么远程桌面连接Linux系统
- 如果番茄花园在美国...
- 装逼神器,5 行 Python 代码 实现一键批量扣图,你get到了吗
- 【GYM-100889 D】Dicy Numbers【数学推导求解】
- DEM数据如何生成高程点
- VMware虚拟机安装WIN7操作系统
- 企业海量数据搜索服务器架构图
- 微信小程序的在线学习每日签到打卡 项目源码介绍
- 上海自来水来自海上,一文掌握这类字符串的验证!
- BiliBili视频下载
- [必看]身份证复印件的正确用法
- 好用的电脑备份软件推荐
- ElementUi Carousel 走马灯,自定义el-carousel箭头左右切换
- 保姆级给电脑分盘,和合并两个盘
- 交叉编译-16:live555交叉编译(Windows和君正平台)
- 进程调度算法FCFS和RR
热门文章
- cpu渲染测试软件,CPU多核渲染大比拼 Corona 引擎测试
- 记录安卓开发工程师的面试题
- EmbedRank论文解读
- B端产品实战课读书笔记05:第四章需求调研
- matlab 图像 高通滤波器,基于matlab数字图像处理之高通滤波器
- 1、脑电基本原理及其经典成分
- android基于gpuimage和photoview的图片编辑(滤镜,饱和度,裁剪)
- openwrt 使用ipv6上网
- TapTap玩家评论——从爬虫到情感分析:APP爬虫、数据清洗、Pyecharts可视化、Word2Vec建模、LSTM建模
- 中睿天下Coremail联合发布《2022年第三季度企业邮箱安全报告》