手把手教你從零實(shí)現(xiàn)Linux misc設(shè)備驅(qū)動(dòng)二(基于友善之臂4412開發(fā)板)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
上一節(jié),我教大家實(shí)現(xiàn)了一個(gè)最簡單的MISC設(shè)備驅(qū)動(dòng),那么這節(jié),我們將用一個(gè)實(shí)例來驅(qū)動(dòng)蜂鳴器,這里為了方便,我就不再寫應(yīng)用程序進(jìn)行測(cè)試,直接在驅(qū)動(dòng)里調(diào)用open函數(shù),這個(gè)程序是在Android系統(tǒng)里跑起來,后面我會(huì)教大家如何在Android下寫應(yīng)用測(cè)試程序。
我們參考以前寫的蜂鳴器驅(qū)動(dòng)程序,將它移植到我們這個(gè)程序里,讓它成為一個(gè)MISC設(shè)備。
參考以前寫的文章:
http://blog.csdn.net/morixinguan/article/details/50628588
接下來,看看代碼:
#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 <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
//定義配置蜂鳴器的IO地址
#define GPD0CON 0x114000A0
volatile unsigned long *bell_config = NULL ;
volatile unsigned long *bell_dat = NULL ;
//misc設(shè)備名稱--->就是字符設(shè)備
#define DEVICE_NAME "misc_dev"
//實(shí)現(xiàn)open函數(shù)
int tiny4412_misc_dev_open(struct inode *inode , struct file *filp)
{
printk("tiny4412 bell dev open!\n");
//配置引腳為輸出狀態(tài)
*bell_config &= ~(0xf);
*bell_config |= (0x1);
//開啟蜂鳴器
*bell_dat |= 0x1 ;
return 0 ;
}
//實(shí)現(xiàn)close函數(shù)
int tiny4412_misc_dev_close(struct inode *inode, struct file *filp)
{
printk("tiny4412 bell dev close!\n");
//關(guān)閉蜂鳴器
*bell_dat &= ~0x1 ;
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)核自動(dòng)分配次設(shè)備號(hào)
.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 ;
//1、映射IO
//映射控制配置引腳IO
bell_config = (volatile unsigned long *)ioremap(GPD0CON , 16);
//加4個(gè)字節(jié)偏移到GP0DAT順便映射該物理地址---引腳狀態(tài)控制IO
bell_dat = bell_config + 1 ;
//2、注冊(cè)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");
//在這里直接調(diào)用open函數(shù),就方便,不用直接寫應(yīng)用程序打開設(shè)備訪問
tiny4412_misc_dev_open(NULL,NULL);
return ret ;
fair:
return ret_error ;
}
static void __exit tiny4412_misc_dev_exit(void)
{
//注銷misc設(shè)備
misc_deregister(&tiny4412_misc_dev);
//取消映射
iounmap(bell_config);
}
module_init(tiny4412_misc_dev_init);
module_exit(tiny4412_misc_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YYX add misc driver");
運(yùn)行結(jié)果:
在開機(jī)log中,我們看到open函數(shù)被正確調(diào)用,蜂鳴器發(fā)出了清脆的響聲。
至此,我們完成了這個(gè)簡單的基于蜂鳴器的misc設(shè)備驅(qū)動(dòng),當(dāng)然,如果有興趣,我們可以在Android上寫一個(gè)C的應(yīng)用程序,在開機(jī)的時(shí)候以服務(wù)的形式加載,一旦加載上,再在里面寫一個(gè)按鍵輸入的程序,當(dāng)按下某個(gè)按鍵就調(diào)用bell open函數(shù),當(dāng)釋放按鍵,就調(diào)用bell close函數(shù)。
以上的程序還可以進(jìn)一步優(yōu)化,做得更好。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!