Linux misc子系統(tǒng)框架驅(qū)動4412蜂鳴器
掃描二維碼
隨時隨地手機看文章
關(guān)于如何來寫一個misc設(shè)備,在前面有篇文章已經(jīng)介紹了大致的流程,現(xiàn)在就讓我們來實現(xiàn)一個最簡單的misc設(shè)備驅(qū)動。
http://blog.csdn.net/morixinguan/article/details/52700146
關(guān)于前面的字符設(shè)備有以下四篇文章,可以做參考:
http://blog.csdn.net/morixinguan/article/details/55002774
http://blog.csdn.net/morixinguan/article/details/55003176
http://blog.csdn.net/morixinguan/article/details/55004646
http://blog.csdn.net/morixinguan/article/details/55006654
為什么要學(xué)習(xí)misc設(shè)備的編程?
因為,如果我們 每個驅(qū)動設(shè)備都要像最初那樣子去寫一個字符設(shè)備驅(qū)動一樣,要分配主設(shè)備號,次設(shè)備號,實現(xiàn)對應(yīng)的文件操作函數(shù)等等的步驟,未免就有點多了,而且也不好記住它,為此,Linux內(nèi)核提供了一系列偷懶的技巧,那就是實現(xiàn)了misc設(shè)備,其實misc設(shè)備,也算是字符設(shè)備,只不過對字符設(shè)備進行了封裝,看看下面的介紹就知道了。
我們先來看看misc設(shè)備的結(jié)構(gòu)體:
//miscdevice結(jié)構(gòu)體
struct miscdevice {
//次設(shè)備號一般賦值為MISC_DYNAMIC_MINOR---->由內(nèi)核自動去分配次設(shè)備號
int minor;
//misc設(shè)備的名稱
const char *name;
//文件操作結(jié)構(gòu)體
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
umode_t mode;
};
這里,我們寫最簡單的misc設(shè)備,我們只需要關(guān)注minor(次設(shè)備號),name(設(shè)備名稱),fops(文件操作函數(shù)).
看到這里我們可以想象到,misc設(shè)備是對字符設(shè)備做了一個再次的封裝,而且,在misc設(shè)備中,主設(shè)備號都是一樣的,都是10,只有次設(shè)備號不同,當我們不知道內(nèi)核中應(yīng)該去分配那個此設(shè)備號時,可以直接給minor賦值為MISC_DYNAMIC_MINOR這個宏,意思就是由內(nèi)核來幫我們分配次設(shè)備號。
name就不用說了,如果設(shè)備注冊成功,在根文件系統(tǒng)/dev/下就會有注冊設(shè)備后的name。
fops就是一系列的文件操作函數(shù)啦,什么open , read ,write , ioctl等等,很多,跟寫字符設(shè)備是一樣的。
那么,接下來,我們來看一個例子,這里我就省略我的Makefile還有Kcofig了,可以參考前面的文章,輕松實現(xiàn)。
實現(xiàn)一個簡單的Misc設(shè)備驅(qū)動程序(在TINY4412開發(fā)板上編寫)
cdev_test.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
//misc設(shè)備名稱--->就是字符設(shè)備
#define DEVICE_NAME "misc_dev"
//實現(xiàn)open函數(shù)
int tiny4412_misc_dev_open(struct inode *inode, struct file *filp)
{
printk("tiny4412 misc dev open!\n");
return 0 ;
}
//實現(xiàn)close函數(shù)
int tiny4412_misc_dev_close(struct inode *inode, struct file *filp)
{
printk("tiny4412 misc dev close!\n");
return 0 ;
}
//初始化文件操作結(jié)構(gòu)體
struct file_operations tiny4412_file_ops = {
.owner = THIS_MODULE ,
.open = tiny4412_misc_dev_open,
.release = tiny4412_misc_dev_close,
};
//初始化misc設(shè)備結(jié)構(gòu)體
struct miscdevice tiny4412_misc_dev = {
//由內(nèi)核自動分配次設(shè)備號
.minor = MISC_DYNAMIC_MINOR ,
//初始化設(shè)備名稱
.name = DEVICE_NAME ,
//初始化文件操作結(jié)構(gòu)體
.fops = &tiny4412_file_ops,
};
static int __init tiny4412_misc_dev_init(void)
{
int ret_error ;
//注冊misc設(shè)備
int ret = misc_register(&tiny4412_misc_dev);
if(ret != 0){
ret_error = ret ;
printk("misc register fair!\n");
goto fair ;
}
printk("misc init success!\n");
return ret ;
fair:
return ret_error ;
}
static void __exit tiny4412_misc_dev_exit(void)
{
//注銷misc設(shè)備
misc_deregister(&tiny4412_misc_dev);
}
module_init(tiny4412_misc_dev_init);
module_exit(tiny4412_misc_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YYX add misc driver");
然后,將驅(qū)動程序編譯后,講zImage下載到板子上。
我們可以看到,在開機的時候,misc init成功打印,證明,misc設(shè)備注冊成功。
接下來,到安卓的根文件系統(tǒng)里,我們打開/dev/下,可以看到設(shè)備名稱為misc_dev的設(shè)備:
我們可以看到,misc_dev的主設(shè)備號是10,次設(shè)備號是39
接下來,cat /proc/misc:
說明,misc已經(jīng)被注冊到proc文件系統(tǒng)中去了。
下節(jié),我們將實現(xiàn)一個真正的misc設(shè)備驅(qū)動。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!