MISC驱动简介
misc的意思是混合、杂项的,因此misc驱动也叫杂项驱动。当我们板子上的某些外设无法进行分类的时候就可以使用该项驱动。
所有杂项设备都共用一个主设备号(10),不同的子杂项设备使用不同的子设备号。
重要接口
定义在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 char *nodename;
umode_t mode;
};
minor:子设备号
因为主设备号已经固定,所以我们只需要申请,或者是注册一个子设备号。为什么说是注册呢?因为Linux内核已经定义好了许多子设备号,我们只要拿来使用即可。
#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
在我们纠结要定义哪一个子设备号时,我们可以直接使用MISC_DYNAMIC_MINOR这个宏来注册,它会根据杂项驱动的使用状态来动态注册子设备号。
name:设备名字
当misc设备驱动注册成功之后,就会在/dev/
下生成一个叫做name的文件节点。
fops:文件操作合集
写过或者了解过字符设备驱动的朋友应该知道这个是什么。用户可以通过/dev/
下的文件节点,来进行open、close、read、write、ioctl等操作,以此实现用户层和内核层的交互。
好的,当我们设置好上面的参数后,我们就可以调用接口,向Linux内核注册这个miscdevice了。
需要用到的接口如下:
int misc_register(struct miscdevice * misc)
/*函数参数和返回值含义如下:
misc:要注册的 MISC 设备。
返回值:负数,失败;0,成功。*/
int misc_deregister(struct miscdevice *misc)
/*函数参数和返回值含义如下:
misc:要注销的 MISC 设备。
返回值:负数,失败;0,成功。*/
示例
/*
* Silicon Integrated Co., Ltd haptic sih688x haptic driver file
*
* Copyright (c) 2021 heater <daokuan.zhu@si-in.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation
*/
#include <linux/init.h> //包含宏定义的头文件
#include <linux/module.h> //包含初始化加载模块的头文件
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#define HAPTICS_MISC_DEV_NAME "haptics"
//打开设备
static int haptics_open(struct inode* inode,struct file * filp)
{
printk("%s\n",__FUNCTION__);
return 0;
}
//关闭设备
static int haptics_release(struct inode* inode ,struct file* filp)
{
printk("%s\n",__FUNCTION__);
return 0;
}
//ioctl
static long haptics_ioctl(struct file * filp, unsigned int cmd, unsigned long arg)
{
return 0;
}
static struct file_operations haptics_fops=
{
.owner = THIS_MODULE,
.open = haptics_open,
.release = haptics_release,
.unlocked_ioctl = haptics_ioctl,
};
struct miscdevice mdev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = HAPTICS_MISC_DEV_NAME,
.fops = &haptics_fops,
};//定义一个杂项设备结构体
static int __init haptics_init(void)
{
int ret = 0;
//内核层只能使用printk,不能使用printf
printk(KERN_EMERG "%s\n",__FUNCTION__); //输出等级为0
ret = misc_register(&mdev);
if(0 == ret)
{
printk(KERN_EMERG "misc_register ok minor=%d\n",mdev.minor);
}
return 0;
}
static void __exit haptics_exit(void)
{
misc_deregister(&mdev);
printk(KERN_EMERG "%s\n",__FUNCTION__); //输出等级为0
}
module_init(haptics_init);//驱动入口
module_exit(haptics_exit);//驱动出口
MODULE_AUTHOR("<daokuan.zhug@si-in.com>");//声明作者信息
MODULE_DESCRIPTION("Haptics Driver V1.0.0"); //对这个模块作一个简单的描述
MODULE_LICENSE("GPL v2");//声明开源许可证
// "GPL" 是指明 这是GNU General Public License的任意版本
// “GPL v2” 是指明 这仅声明为GPL的第二版本
上述源码在设备节点操作接口时使用了ioctl
,这个东西怎么使用后续再介绍。