一. 简介
misc 的意思是混合、杂项的
所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。
二. 结构体 struct miscdevice
三. API
1.注册/销毁
int misc_register(struct miscdevice * misc)
int misc_deregister(struct miscdevice *misc)
misc_register替换:
alloc_chrdev_region(); /* 申请设备号 */
cdev_init(); /* 初始化 cdev */
cdev_add(); /* 添加 cdev */
class_create(); /* 创建类 */
device_create(); /* 创建设备 */
四.示例 beep
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
/* LED数据资源结构体 */
struct beep_data {
struct miscdevice mdev; // led设备
int gpio; // gpio编号
};
struct beep_data gbeep_data;
static int gpio_init(struct platform_device *pdev)
{
struct beep_data *beep = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
int ret;
/* 从设备树中获取GPIO */
beep->gpio = of_get_named_gpio(dev->of_node, "beep-gpio", 0);
if(!gpio_is_valid(beep->gpio)) {
dev_err(dev, "Failed to get gpio");
return -EINVAL;
}
/* 申请使用GPIO */
ret = devm_gpio_request(dev, beep->gpio, "BEEP Gpio");
if (ret) {
dev_err(dev, "Failed to request gpio");
return ret;
}
/* 将GPIO设置为输出模式并将输出低电平 */
gpio_direction_output(beep->gpio, 0);
return 0;
}
ssize_t beep_write (struct file *filp, const char __user *buff, size_t cnt, loff_t *offset)
{
char kbuff[1];
int ret = copy_from_user(&kbuff, buff, sizeof(kbuff));
gpio_set_value(gbeep_data.gpio,kbuff[0]);
}
static const struct file_operations beep_fops={
.write = beep_write,
};
static int beep_probe(struct platform_device *pdev)
{
struct beep_data *beep;
struct led_classdev *led_cdev;
int ret;
dev_info(&pdev->dev, "beep device and driver matched successfully!\n");
beep = &gbeep_data;
platform_set_drvdata(pdev, beep);
/* 初始化LED */
ret = gpio_init(pdev);
if (ret)
return ret;
/* 注册misc BEEP设备 */
beep->mdev.name = "beep";
beep->mdev.fops = &beep_fops;
beep->mdev.minor = MISC_DYNAMIC_MINOR;
return misc_register(&beep->mdev);
}
static int beep_remove(struct platform_device *pdev)
{
struct beep_data *beep = platform_get_drvdata(pdev);
misc_deregister(&beep->mdev);
dev_info(&pdev->dev, "beep driver has been removed!\n");
return 0;
}
/* 匹配列表 */
static const struct of_device_id beep_of_match[] = {
{ .compatible = "m0mo,beep" },
{ /* Sentinel */ }
};
/* platform驱动结构体 */
static struct platform_driver beep_driver = {
.driver = {
.name = "m0mo_beep", // 驱动名字,用于和设备匹配
.of_match_table = beep_of_match, // 设备树匹配表,用于和设备树中定义的设备匹配
},
.probe = beep_probe, // probe函数
.remove = beep_remove, // remove函数
};
module_platform_driver(beep_driver);
MODULE_AUTHOR("DengTao <773904075@qq.com>");
MODULE_DESCRIPTION("LED Driver Based on LED Driver Framework");
MODULE_LICENSE("GPL");