文章目錄
- 前言
- 一、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設備驅動的編寫及使用,制作不易,多多包涵。