<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    迅為i.MX6ULL終結者Linux INPUT子系統實驗Input子系統

    發布時間:2021-1-11 10:29    發布者:就是塔塔
    關鍵詞: 迅為 , Linux , INPUT
    文章目錄
    1 input子系統簡介
    2 input驅動程序編寫流程
    3 input_event結構體
    1 input子系統簡介
    input 子系統就是管理輸入的子系統,和 pinctrl 和 gpio 子系統一樣,都是 Linux 內核針對某一類設備而創建的框架。 input子系統處理輸入事務,任何輸入設備的驅動程序都可以通過input輸入子系統提供的接口注冊到內核,利用子系統提供的功能來與用戶空間交互。輸入設備一般包括鍵盤,鼠標,觸摸屏等,在內核中都是以輸入設備出現的。
    input子系統是分層結構的,總共分為三層: 硬件驅動層,子系統核心層,事件處理層。
    (1)硬件驅動層負責操作具體的硬件設備,這層的代碼是針對具體的驅動程序的,需要驅動程序的作者來編寫。
    (2)子系統核心層是鏈接其他兩個層之間的紐帶與橋梁,向下提供驅動層的接口,向上提供事件處理層的接口。
    (3)事件處理層負責與用戶程序打交道,將硬件驅動層傳來的事件報告給用戶程序。

    各層之間通信的基本單位就是事件,任何一個輸入設備的動作都可以抽象成一種事件,如鍵盤的按下,觸摸屏的按下,鼠標的移動等。事件有三種屬性:類型(type),編碼(code),值(value),input子系統支持的所有事件都定義在input.h中,包括所有支持的類型,所屬類型支持的編碼等。事件傳送的方向是 硬件驅動層–>子系統核心–>事件處理層–>用戶空間。
    2 input驅動程序編寫流程
    首先來看一下在input核心層實現了哪些功能,input核心層文件是input.c,路徑:drivers/input/input.c,部分內容如下:

    第2418行,注冊了一個input類,在系統啟動后會在/sys/class目錄下生成一個input類的子目錄,如圖 2.1所示:

    第2428、2489行,注冊了一個字符設備,所以input子系統本質上也是字符設備驅動,主設備號為 INPUT_MAJOR,INPUT_MAJOR 定義在 include/uapi/linux/major.h 文件中,定義如下:
    #define INPUT_MAJOR 13
    所以input 子系統的所有設備主設備號都為 13,在使用 input 子系統處理輸入設備的時候就不需要去注冊字符設備了,我們只需要向系統注冊一個 input_device 即可。
    1、input_dev 結構體
    input_dev結構體是input設備基本的設備結構,每個input驅動程序中都必須分配初始化這樣一個結構,結構體定義在 include/linux/input.h 文件中,定義如下:

    第 129 行,evbit 表示輸入事件類型,可選的事件類型定義在 include/uapi/linux/input.h 文件中,事件類型如下:

    根據使用的不同設備選擇不同的事件類型,在本章的實驗中我們會用到按鍵設備,那么我們就需要選擇EV_KEY 事件類型。
    在看input_dev結構體中的第129~137行的evbit、keybit等成員變量,都是對應的不同事件類型的值。比如按鍵事件對應的keybit成員,keybit 就是按鍵事件使用的位圖,Linux 內核定義了很多按鍵值,這些按鍵值定義在 include/uapi/linux/input.h 文件中,按鍵值如下:

    當我們編寫input設備驅動時需要先創建一個input_dev 結構體變量,但是不用我們手動創建,input子系統提供了下面兩個函數用于創建和注銷input_dev 結構體變量。

    申請完input_dev結構體后,需要進行初始化,根據自己的設備來指定事件類型和事件值,比如按鍵設備的事件類型是evbit,事件值是keybit。
    input_dev結構體初始化完成后,使用input_register_device 函數向Linux內核注冊input_dev設備。函數原型如下:
    int input_register_device(struct input_dev *dev)
    dev:要注冊的 input_dev 。
    返回值:0,input_dev 注冊成功;負值,input_dev 注冊失敗。
    同樣的,注銷 input 驅動的時候也需要使用 input_unregister_device 函數來注銷掉前面注冊的 input_dev,input_unregister_device 函數原型如下:
    void input_unregister_device(struct input_dev *dev)
    總結上面的內容,input_dev注冊過程分為下面幾步:
    ① 首先使用 input_allocate_device 函數申請一個 input_dev。
    ② 初始化 input_dev 的事件類型以及事件值。
    ③ input_register_device()函數是輸入子系統核心(input core)提供的函數。該函數將input_dev結構體注冊到輸入子系統核心中
    ④ input_register_device()函數如果注冊失敗,必須調用input_free_device()函數釋放分配的空間。如果該函數注冊成功,在卸載函數中應該調用input_unregister_device()函數來注銷輸入設備結構體。
    input_dev注冊過程實例代碼如下:


    第 10~23 行都是初始化 input 設備事件和按鍵值,這里用了三種方法來設置事件和按鍵值。
    2、上報輸入事件
    在input設備驅動中申請、注冊完成input_dev結構體后,還不能正常使用input子系統,因為input設備是輸入一些信息,但是Linux內核還不清楚輸入的信息表示什么意思,有什么作用,所以我們需要驅動獲取到具體的輸入值,或者說輸入事件,然后將輸入事件上報給Linux內核。比如按鍵設備,我們需要在按鍵產生后將按鍵值上報給Linux內核,Linux內核獲取到具體的按鍵值后,才會執行相應的功能。不同的事件上報的函數不同,我們分別來看一下有哪些常用的API函數。
    input_event函數:用于上報指定的事件以及對應的值。函數原型如下:

    函數參數和返回值含義如下:
    dev:需要上報的 input_dev。
    type: 上報的事件類型,比如 EV_KEY。
    code:事件碼,也就是我們注冊的按鍵值,比如 KEY_0、KEY_1 等等。
    value:事件值,比如 1 表示按鍵按下,0 表示按鍵松開。
    返回值:無。
    input_event函數可以用于所有事件類型和事件值的上報。
    input_report_key 函數:上報按鍵事件。具體函數內容如下:

    可以看出,input_report_key 函數的本質就是 input_event 函數,當然使用哪個函數都沒有問題,不同的設備使用對應的函數更加合適一點。
    同樣的還有一些其他事件對應的上報函數:

    input_sync 函數:用來告訴Linux內核input子系統上報結束。input_sync 函數本質上是上報一個同步事件,函數原型如下:
    void input_sync(struct input_dev *dev)
    列舉了好幾個函數,以按鍵設備為例,看一下如何使用:

    獲取按鍵的值,然后判斷按鍵是否按下,通過input_report_key函數上報按鍵的值,input_sync函數表示上報結束。
    3 input_event結構體
    Linux 內核使用 input_event 這個結構體來表示所有的輸入事件,input_envent 結構體定義在include/uapi/linux/input.h 文件中,結構體內容如下:

    依次來看一下 input_event 結構體中的各個成員變量:
    time:時間,也就是此事件發生的時間,為 timeval 結構體類型,timeval 結構體定義如下:

    tv_sec 和 tv_usec 這兩個成員變量都為 long 類型,也就是 32位,這個一定要記住,后面我們分析 event 事件上報數據的時候要用到。
    type:事件類型,比如 EV_KEY,表示此次事件為按鍵事件,此成員變量為 16 位。
    code:事件碼,比如在 EV_KEY 事件中 code 就表示具體的按鍵碼,如:KEY_0、KEY_1等等這些按鍵。此成員變量為 16 位。
    value:值,比如 EV_KEY 事件中 value 就是按鍵值,表示按鍵有沒有被按下,如果為 1 的話說明按鍵按下,如果為 0 的話說明按鍵沒有被按下或者按鍵松開了。
    input_envent 這個結構體非常重要,因為所有的輸入設備最終都是按照 input_event 結構體呈現給用戶的,用戶應用程序可以通過 input_event 來獲取到具體的輸入事件或相關的值,比如按鍵值等。


    終結者資料全開源,不買也可以自由下載軟硬件資源
    您只需要關注VX公眾號:迅為電子 ,  回復 :終結者,免費獲取產品資料

    本文地址:http://www.portaltwn.com/thread-753973-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷