新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 嵌入式Linux設(shè)備驅(qū)動開發(fā)之:按鍵驅(qū)動程序?qū)嵗?/p>

        嵌入式Linux設(shè)備驅(qū)動開發(fā)之:按鍵驅(qū)動程序?qū)嵗?/h1>
        作者: 時間:2013-09-13 來源:網(wǎng)絡(luò) 收藏

        本文引用地址:http://www.104case.com/article/257107.htm

        按鍵字符設(shè)備的file_operations結(jié)構(gòu)定義為:

        staticstructfile_operationsbutton_fops=

        {

        .owner=THIS_MODULE,

        .ioctl=button_ioctl,

        .open=button_open,

        .read=button_read,

        .release=button_release,

        };

        以下為open和release函數(shù)接口的實現(xiàn)。

        /*打開文件,申請中斷*/

        staticintbutton_open(structinode*inode,structfile*filp)

        {

        intret=nonseekable_open(inode,filp);

        if(ret0)

        {

        returnret;

        }

        init_gpio();/*相關(guān)GPIO端口的初始化*/

        ret=request_irqs();/*申請4個中斷*/

        if(ret0)

        {

        returnret;

        }

        init_keybuffer();/*初始化按鍵緩沖數(shù)據(jù)結(jié)構(gòu)*/

        returnret;

        }

        /*關(guān)閉文件,屏蔽中斷*/

        staticintbutton_release(structinode*inode,structfile*filp)

        {

        free_irqs();/*屏蔽中斷*/

        return0;

        }

        在open函數(shù)接口中,進行了GPIO端口的初始化、申請硬件中斷以及按鍵緩沖的初始化等工作。在以前的章節(jié)中提過,中斷端口是比較寶貴而且數(shù)量有限的資源。因此需要注意,最好要在第一次打開設(shè)備時申請(調(diào)用request_irq函數(shù))中斷端口,而不是在驅(qū)動模塊加載的時候申請。如果已加載的占用而在一定時間段內(nèi)不使用某些中斷資源,則這些資源不會被其他驅(qū)動所使用,只能白白浪費掉。而在打開設(shè)備的時候(調(diào)用open函數(shù)接口)申請中斷,則不同的可以共享這些寶貴的中斷資源。

        以下為中斷申請和釋放的部分以及中斷處理函數(shù)。

        /*中斷處理函數(shù),其中irq為中斷號*/

        staticirqreturn_tbutton_irq(intirq,void*dev_id,structpt_regs*regs)

        {

        unsignedcharucKey=0;

        disable_irqs();/*屏蔽中斷*/

        /*延遲50ms,屏蔽按鍵毛刺*/

        udelay(50000);

        ucKey=button_scan(irq);/*掃描按鍵,獲得進行操作的按鍵的ID*/

        if((ucKey>=1)(ucKey=16))

        {

        /*如果緩沖區(qū)已滿,則不添加*/

        if(((key_buffer.head+1)(MAX_KEY_COUNT-1))!=key_buffer.tail)

        {

        spin_lock_irq(buffer_lock);

        key_buffer.buf[key_buffer.tail]=ucKey;

        key_buffer.jiffy[key_buffer.tail]=get_tick_count();

        key_buffer.tail++;

        key_buffer.tail=(MAX_KEY_COUNT-1);

        spin_unlock_irq(buffer_lock);

        }

        }

        init_gpio();/*初始化GPIO端口,主要是為了恢復(fù)中斷端口配置*/

        enable_irqs();/*開啟中斷*/

        returnIRQ_HANDLED;/*2.6內(nèi)核返回值一般是這個宏*/

        }

        /*申請4個中斷*/

        staticintrequest_irqs(void)

        {

        intret,i,j;

        for(i=0;iMAX_COLUMN;i++)

        {

        ret=request_irq(key_info_matrix[i][0].irq_no,

        button_irq,SA_INTERRUPT,BUTTONS_DEVICE_NAME,NULL);

        if(ret0)

        {

        for(j=0;ji;j++)

        {

        free_irq(key_info_matrix[j][0].irq_no,NULL);

        }

        return-EFAULT;

        }

        }

        return0;

        }

        /*釋放中斷*/

        static__inlinevoidfree_irqs(void)

        {

        inti;

        for(i=0;iMAX_COLUMN;i++)

        {

        free_irq(key_info_matrix[i][0].irq_no,NULL);

        }

        }

        中斷處理函數(shù)在每次中斷產(chǎn)生的時候會被調(diào)用,因此它的執(zhí)行時間要盡可能得短。通常中斷處理函數(shù)只是簡單地喚醒等待資源的任務(wù),而復(fù)雜且耗時的工作則讓這個任務(wù)去完成。中斷處理函數(shù)不能向用戶空間發(fā)送數(shù)據(jù)或者接收數(shù)據(jù),不能做任何可能發(fā)生睡眠的操作,而且不能調(diào)用schedule()函數(shù)。

        為了簡單起見,而且考慮到按鍵操作的時間比較長,在本實例中的中斷處理函數(shù)button_irq()里,通過調(diào)用睡眠函數(shù)來消除毛刺信號。讀者可以根據(jù)以上介紹的對中斷處理函數(shù)的要求改進該部分代碼。

        linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

        linux相關(guān)文章:linux教程


        蜂鳴器相關(guān)文章:蜂鳴器原理


        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 晋江市| 加查县| 秭归县| 鄄城县| 沧州市| 嘉兴市| 肇州县| 阿图什市| 中山市| 崇明县| 安阳市| 西安市| 霍林郭勒市| 新安县| 栖霞市| 通江县| 红桥区| 大兴区| 尖扎县| 堆龙德庆县| 洪泽县| 乐山市| 荔浦县| 慈溪市| 津南区| 长葛市| 吉首市| 勃利县| 竹北市| 枞阳县| 库车县| 尼木县| 清徐县| 蓬莱市| 青川县| 玉屏| 昌平区| 北票市| 庆安县| 阜新市| 阿拉善右旗|