Linux MISC 驱动实验
创始人
2025-05-31 20:12:19
0

我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动。MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 platform 总线驱动中,实现复杂的驱动。

一、MISC 设备驱动简介

所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。

// miscdevice 结构体代码
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;
};

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

当设置好 miscdevice 以后就需要使用 misc_register 函数向系统中注册一个 MISC 设备,此
函数原型如下:

int misc_register(struct miscdevice * misc)

函数参数和返回值含义如下:
misc:要注册的 MISC 设备。
返回值:负数,失败;0,成功。

调用 misc_deregister 函数来注销掉 MISC 设备,函数原型如下:

int misc_deregister(struct miscdevice *misc)

函数参数和返回值含义如下:
misc:要注销的 MISC 设备。
返回值:负数,失败;0,成功。

用上面这两个函数可以省略之前字符设备驱动框架的大部分代码。

二、实验程序编写

1、 beep 驱动程序编写

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MISCBEEP_NAME		"miscbeep"	/* 名字 	*/#define MISCBEEP_MINOR		144			/* 子设备号 */#define BEEPOFF 			0			/* 关蜂鸣器 */#define BEEPON 				1			/* 开蜂鸣器 *//* miscbeep设备结构体 */struct miscbeep_dev{dev_t devid;			/* 设备号 	 */struct cdev cdev;		/* cdev 	*/struct class *class;	/* 类 		*/struct device *device;	/* 设备 	 */struct device_node	*nd; /* 设备节点 */int beep_gpio;			/* beep所使用的GPIO编号		*/};struct miscbeep_dev miscbeep;		/* beep设备 *//** @description		: 打开设备* @param - inode 	: 传递给驱动的inode* @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量* 					  一般在open的时候将private_data指向设备结构体。* @return 			: 0 成功;其他 失败*/static int miscbeep_open(struct inode *inode, struct file *filp){filp->private_data = &miscbeep; /* 设置私有数据 */return 0;}/** @description		: 向设备写数据 * @param - filp 	: 设备文件,表示打开的文件描述符* @param - buf 	: 要写给设备写入的数据* @param - cnt 	: 要写入的数据长度* @param - offt 	: 相对于文件首地址的偏移* @return 			: 写入的字节数,如果为负值,表示写入失败*/static ssize_t miscbeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt){int retvalue;unsigned char databuf[1];unsigned char beepstat;struct miscbeep_dev *dev = filp->private_data;retvalue = copy_from_user(databuf, buf, cnt);if(retvalue < 0) {printk("kernel write failed!\r\n");return -EFAULT;}beepstat = databuf[0];		/* 获取状态值 */if(beepstat == BEEPON) {	gpio_set_value(dev->beep_gpio, 0);	/* 打开蜂鸣器 */} else if(beepstat == BEEPOFF) {gpio_set_value(dev->beep_gpio, 1);	/* 关闭蜂鸣器 */}return 0;}/* 设备操作函数 */static struct file_operations miscbeep_fops = {.owner = THIS_MODULE,.open = miscbeep_open,.write = miscbeep_write,};/* MISC设备结构体 */static struct miscdevice beep_miscdev = {.minor = MISCBEEP_MINOR,.name = MISCBEEP_NAME,.fops = &miscbeep_fops,};/** @description     : flatform驱动的probe函数,当驱动与*                    设备匹配以后此函数就会执行* @param - dev     : platform设备* @return          : 0,成功;其他负值,失败*/static int miscbeep_probe(struct platform_device *dev){int ret = 0;printk("beep driver and device was matched!\r\n");/* 设置BEEP所使用的GPIO *//* 1、获取设备节点:beep */miscbeep.nd = of_find_node_by_path("/beep");if(miscbeep.nd == NULL) {printk("beep node not find!\r\n");return -EINVAL;} /* 2、 获取设备树中的gpio属性,得到BEEP所使用的BEEP编号 */miscbeep.beep_gpio = of_get_named_gpio(miscbeep.nd, "beep-gpio", 0);if(miscbeep.beep_gpio < 0) {printk("can't get beep-gpio");return -EINVAL;}/* 3、设置GPIO5_IO01为输出,并且输出高电平,默认关闭BEEP */ret = gpio_direction_output(miscbeep.beep_gpio, 1);if(ret < 0) {printk("can't set gpio!\r\n");}/* 一般情况下会注册对应的字符设备,但是这里我们使用MISC设备* 所以我们不需要自己注册字符设备驱动,只需要注册misc设备驱动即可*/ret = misc_register(&beep_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 miscbeep_remove(struct platform_device *dev){/* 注销设备的时候关闭LED灯 */gpio_set_value(miscbeep.beep_gpio, 1);/* 注销misc设备 */misc_deregister(&beep_miscdev);return 0;}/* 匹配列表 */static const struct of_device_id beep_of_match[] = {{ .compatible = "atkalpha-beep" },  //必须与设备树的comparable一致{ /* Sentinel */ }};/* platform驱动结构体 */static struct platform_driver beep_driver = {.driver     = {.name   = "imx6ul-beep",         /* 驱动名字,用于和设备匹配 */.of_match_table = beep_of_match, /* 设备树匹配表          */},.probe      = miscbeep_probe,.remove     = miscbeep_remove,};/** @description	: 驱动出口函数* @param 		: 无* @return 		: 无*/static int __init miscbeep_init(void){return platform_driver_register(&beep_driver);}/** @description	: 驱动出口函数* @param 		: 无* @return 		: 无*/static void __exit miscbeep_exit(void){platform_driver_unregister(&beep_driver);}module_init(miscbeep_init);module_exit(miscbeep_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("hsd");
#include "stdio.h"#include "unistd.h"#include "sys/types.h"#include "sys/stat.h"#include "fcntl.h"#include "stdlib.h"#include "string.h"#define BEEPOFF	0#define BEEPON 	1/** @description		: main主程序* @param - argc 	: argv数组元素个数* @param - argv 	: 具体参数* @return 			: 0 成功;其他 失败*/int main(int argc, char *argv[]){int fd, retvalue;char *filename;unsigned char databuf[1];if(argc != 3){printf("Error Usage!\r\n");return -1;}filename = argv[1];fd = open(filename, O_RDWR);	/* 打开beep驱动 */if(fd < 0){printf("file %s open failed!\r\n", argv[1]);return -1;}databuf[0] = atoi(argv[2]);	/* 要执行的操作:打开或关闭 */retvalue = write(fd, databuf, sizeof(databuf));if(retvalue < 0){printf("BEEP Control Failed!\r\n");close(fd);return -1;}retvalue = close(fd); /* 关闭文件 */if(retvalue < 0){printf("file %s close failed!\r\n", argv[1]);return -1;}return 0;}

相关内容

热门资讯

四川绵竹三大千亿园区布局:循环... 2026新年伊始,四川省人民政府重磅发布《关于推动城市高质量发展的实施意见》,文件明确提到,以城镇化...
70余只基金开年大涨超20%!... 2026年首月过半,已有权益类基金创造惊人收益。Wind数据显示,截至1月15日,有74只权益类基金...
来伊份年度预亏1.7亿元,拟用... 红星资本局1月17日消息,1月16日,来伊份(603777.SH)发布预亏公告,预计2025年度归母...
老贾,赢了么? 昨晚(1月16日),可能不少人原本计划看西贝创始人贾国龙的直播。网上文章也是铺天盖地的。但不想,就在...
新商业周报 | 小红书与美团达... 《CBNData新商业周报》精选本周新商业领域最新动态,公司头条、消费风向、智能创新、营销动态、可持...
高达1340亿美元!美媒:马斯... 来源:环球网【环球网报道】据美国彭博社、路透社当地时间17日报道,美国亿万富翁埃隆·马斯克要求美国开...
605028,突然终止“易主”... 下周合计解禁市值464.99亿元。世茂能源(605028)1月16日晚间公告表示,停牌期间,公司控股...
江波龙股东拟减持3%  市值约... 中经记者 陈佳岚 广州报道2026年1月16日晚间,存储模组龙头江波龙(301308.SZ)发布股东...
被质疑的梦想,才值得追觅 我们都经历过这样一种时刻:你做了一个决定,没人理解;你选择一条路,所有人都说你「太狂」、「不可能实现...
2月1日起,提供“静音车厢”的... 今天(17日),记者从国铁集团获悉, 自2月1日起,“静音车厢”服务将拓展至除动卧列车之外的“D”字...