linux misc device字符杂项设备驱动
?
雜項設備也是在嵌入式系統中用得比較多的一種設備驅動。miscdevice共享一個主設備號MISC_MAJOR(即10),但次設備號不同。misc設備其實就是特殊的字符設備,主設備編號采用10,并且可自動生成設備節點。
雜項設備作為字符設備的封裝,為字符設備提供的簡單的編程接口,如果編寫新的字符驅動,可以考慮使用雜項設備接口,方便簡單,只需要初始化一個miscdevice的結構,調用misc_register就可以了,misc_register最終也是通過調用register_chrdev()來注冊設備。系統最多有255個雜項設備,因為雜項設備模塊自己占用了一個次設備號。
?
1. 實現struct file_operations
static struct file_operations leds_ops = {.owner = THIS_MODULE, .open = leds_open, .release = leds_release, .unlocked_ioctl = leds_ioctl,};?
2. 初始化struct miscdevice,定義一個misc設備
static struct miscdevice leds_dev = {.minor = MISC_DYNAMIC_MINOR, .fops = &leds_ops, .name = "leds", //此名稱將顯示在/dev目錄下面};注:其中minor如果填充MISC_DYNAMIC_MINOR,則是動態動態次設備號。
?
3. 注冊和釋放misc設備
1)注冊
int misc_register(struct miscdevice * misc);
misc_register(&leds_dev);
注:此函數中會自動創建設備節點,即設備文件。無需mknod指令創建設備文件,因為misc_register()會調用device_create()創建設備節點。
2)釋放
int misc_deregister(struct miscdevice *misc);
misc_deregister(&leds_dev);
?
4. 其它
1)頭文件 #include <linux/miscdevice.h>
2)miscdevice 結構體
struct miscdevice { int minor; //次設備號 通常為MISC_DYNAMIC_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; };
通常 miscdevice的 minor 、name 和 fops是需要實現的。
?
5. A33下一個GPIO驅動實例
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <mach/gpio.h> #include <linux/gpio.h> #include <linux/miscdevice.h>static int led_gpios[] = {GPIOH(7),};#define LED_NUM ARRAY_SIZE(led_gpios)int leds_open(struct inode *inode,struct file *filp) {printk("leds device opened success!\n");return nonseekable_open(inode,filp); //通知內核你的設備不支持llseek}int leds_release(struct inode *inode,struct file *filp) {printk("leds device closed success!\n");return 0;}long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) {printk("debug: leds_ioctl cmd is %d\n" , cmd);switch(cmd){case 0: //不加break,執行case1case 1:if (arg > LED_NUM) {return -EINVAL;}gpio_set_value(led_gpios[arg], cmd);break;default:return -EINVAL;}return 0;}static struct file_operations leds_ops = {.owner = THIS_MODULE,.open = leds_open,.release = leds_release,.unlocked_ioctl = leds_ioctl,};static struct miscdevice leds_dev = {.minor = MISC_DYNAMIC_MINOR,.fops = &leds_ops,.name = "leds", //此名稱將顯示在/dev目錄下面};static int __init leds_init(void) {int ret, i;char *banner = "leds Initialize\n";printk(banner);for(i=0; i<LED_NUM; i++){//申請gpio,設置為輸出,高電平ret = gpio_request_one(led_gpios[i], GPIOF_OUT_INIT_HIGH,"LED");if (ret) {printk("leds: request GPIO %d for LED failed, ret = %d\n", led_gpios[i], ret);return ret;}}ret = misc_register(&leds_dev);if(ret<0){printk("leds: register device failed!\n");goto exit;}return 0;exit:misc_deregister(&leds_dev);return ret;}static void __exit leds_exit(void) {misc_deregister(&leds_dev);}module_init(leds_init); module_exit(leds_exit);MODULE_LICENSE("Dual BSD/GPL");?
?
?
總結
以上是生活随笔為你收集整理的linux misc device字符杂项设备驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python模块之snmp-cmds,e
- 下一篇: linux 其他常用命令