• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > 嵌入式Linux設備驅動開發之:按鍵驅動程序實例

    嵌入式Linux設備驅動開發之:按鍵驅動程序實例

    作者: 時間:2013-09-13 來源:網絡 收藏

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

    按鍵字符設備的file_operations結構定義為:

    staticstructfile_operationsbutton_fops=

    {

    .owner=THIS_MODULE,

    .ioctl=button_ioctl,

    .open=button_open,

    .read=button_read,

    .release=button_release,

    };

    以下為open和release函數接口的實現。

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

    staticintbutton_open(structinode*inode,structfile*filp)

    {

    intret=nonseekable_open(inode,filp);

    if(ret0)

    {

    returnret;

    }

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

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

    if(ret0)

    {

    returnret;

    }

    init_keybuffer();/*初始化按鍵緩沖數據結構*/

    returnret;

    }

    /*關閉文件,屏蔽中斷*/

    staticintbutton_release(structinode*inode,structfile*filp)

    {

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

    return0;

    }

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

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

    /*中斷處理函數,其中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))

    {

    /*如果緩沖區已滿,則不添加*/

    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端口,主要是為了恢復中斷端口配置*/

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

    returnIRQ_HANDLED;/*2.6內核返回值一般是這個宏*/

    }

    /*申請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);

    }

    }

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

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

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

    linux相關文章:linux教程


    蜂鳴器相關文章:蜂鳴器原理


    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 潍坊市| 塔城市| 子长县| 敦化市| 肇源县| 运城市| 和政县| 庆阳市| 文成县| 将乐县| 泽普县| 长顺县| 化隆| 新源县| 田东县| 武宣县| 嘉定区| 巧家县| 金阳县| 龙口市| 札达县| 青阳县| 石柱| 德庆县| 北海市| 墨脱县| 阿尔山市| 上思县| 远安县| 镇平县| 赤水市| 贵溪市| 凤台县| 广宗县| 云阳县| 醴陵市| 江城| 平邑县| 滨海县| 湘阴县| 眉山市|