文章目录
- 前言
- 一、misc是什么?
- 二、调用API
- 1.注册
- 2.注销
- 三、驱动框架
- 总结
前言
misc设备即杂项设备,Linux系统中类似按键、触摸屏都有专门框架处理,类似adc、蜂鸣器等设备无法明确其属于什么类型,一般就归属于杂项设备,按misc驱动框架编写驱动程序。
一、misc是什么?
所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。为了解决字符设备驱动的不断增加。MISC设备会自动创建cdev,我们需要向Linux注册一个miscdevice设备,是一个结构体,定义在文件 include/linux/miscdevice.h 中:
struct miscdevice {int minor; // 次设备号const char *name; // 设备名字 /dev目录下生成设备文件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_DYNAMIC_MINOR
也可以在 include/linux/miscdevice.h 中选,也可以自己定义,只要没被使用
二、调用API
1.注册
函数如下:
int misc_register(struct miscdevice * misc)misc:要注册的 MISC 设备。
返回值: 负数,失败; 0,成功
可以代替以前字符驱动的这些步骤:
alloc_chrdev_region(); /* 申请设备号 */cdev_init(); /* 初始化 cdev */cdev_add(); /* 添加 cdev */class_create(); /* 创建类 */device_create(); /* 创建设备 */
2.注销
函数如下:
int misc_deregister(struct miscdevice *misc)misc:要注销的 MISC 设备。
返回值: 负数,失败; 0,成功。
可以代替以前字符驱动的这些步骤:
cdev_del(); /* 删除 cdev */unregister_chrdev_region(); /* 注销设备号 */device_destroy(); /* 删除设备 */class_destroy(); /* 删除类 */
三、驱动框架
下面展示一个基本的misc驱动框架示例
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>struct myled_data {struct miscdevice mdev;int gpio;
};struct myled_data myled;int led_open (struct inode *a, struct file *b)
{return 0;
}ssize_t led_write(struct file *a, const char __user *b, size_t c, loff_t *d)
{char buf[5] = {0};int ret = 0;ret = copy_from_user(buf,b,c);if(ret < 0){printk("misc led failed to copy_from_user\n");return -EFAULT;}if(buf[0] == 0)gpio_set_value(myled.gpio,0);elsegpio_set_value(myled.gpio,1);return ret;
}struct file_operations fop =
{.owner = THIS_MODULE,.open = led_open,.write = led_write,
};int led_probe(struct platform_device *pdev)
{int ret = 0;myled.gpio = of_get_named_gpio(pdev->dev.of_node,"led-gpio",0);ret = devm_gpio_request(&pdev->dev,myled.gpio,"LED GPIO");if(ret){dev_err(&pdev->dev,"devm_gpio_request failed !\n");return ret;}gpio_direction_output(myled.gpio,0);myled.mdev.name = "misc_led";myled.mdev.minor = MISC_DYNAMIC_MINOR; //动态分配myled.mdev.fops = &fop;return misc_register(&myled.mdev);
}int led_exit(struct platform_device *pdev)
{misc_deregister(&myled.mdev);return 0;
}struct of_device_id led_of_match[] = {{.compatible = "misc_led"},
};struct platform_driver myled_driver =
{.driver = {.name = "zynq_misc_led",.of_match_table = led_of_match,},.probe = led_probe,.remove = led_exit,
};module_platform_driver(myled_driver);MODULE_AUTHOR("LZW");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MISC DRIVER BASE ON MISC FRAMEWORK");
编写完ko成功加载后,即可在应用层像操作字符设备节点一样,进行open,read,write等操作。
总结
以上就是今天要讲的内容,本文简单介绍了misc设备驱动的编写及使用,制作不易,多多包涵。