0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用Linux系統(tǒng)下的輸入設(shè)備進行應(yīng)用編程

嵌入式開發(fā)愛好者 ? 來源:嵌入式開發(fā)愛好者 ? 作者:嵌入式開發(fā)愛好者 ? 2022-11-10 10:10 ? 次閱讀

今天主要來聊一聊,如何使用Linux系統(tǒng)下的輸入設(shè)備進行應(yīng)用編程。

第一:什么是輸入設(shè)備

先來了解一下什么是輸入設(shè)備(稱為input設(shè)備),常見的輸入設(shè)備有鼠標、鍵盤、觸摸屏、遙控器、畫圖板等,用戶通過輸入設(shè)備與系統(tǒng)進行交互。

由上面可知,輸入設(shè)備種類非常多,那么Linux系統(tǒng)如何管理呢?Linux系統(tǒng)為了統(tǒng)一管理這些輸入設(shè)備,實現(xiàn)了一套能夠兼容所有輸入設(shè)備的框架,那么這個框架就是input子系統(tǒng)。驅(qū)動開發(fā)人員基于input子系統(tǒng)開發(fā)輸入設(shè)備的驅(qū)動程序,input子系統(tǒng)可以屏蔽硬件的差異,向應(yīng)用層提供一套統(tǒng)一的接口。

基于input子系統(tǒng)注冊成功的輸入設(shè)備,都會在/dev/input目錄下生產(chǎn)對應(yīng)的設(shè)備節(jié)點(設(shè)備文件),設(shè)備文件節(jié)點名稱通常為eventX()(X表示一個數(shù)字編號0,1,2,3,等),譬如/dev/input/event0、/dev/input/event1、/dev/input/event2 等,通過讀取這些設(shè)備節(jié)點可以獲取輸入設(shè)備上報的數(shù)據(jù)。

第二:讀取數(shù)據(jù)的流程

如果我們要讀取觸摸屏的數(shù)據(jù),假設(shè)觸摸屏設(shè)備對應(yīng)的設(shè)備節(jié)點為/dev/input/event0,那么數(shù)據(jù)讀取流程如下:

1、應(yīng)用程序打開/dev/input/event0設(shè)備文件。

2、應(yīng)用程序發(fā)去讀操作(譬如調(diào)用read),如果沒有數(shù)據(jù)可讀則會進入休眠(阻塞I/O情況下)。

3、當有數(shù)據(jù)可讀時,應(yīng)用程序會被喚醒,讀操作獲取到數(shù)據(jù)返回。

4、應(yīng)用程序?qū)ψx取到的數(shù)據(jù)進行解析。

當無數(shù)據(jù)可讀時,程序會進入休眠狀態(tài)(也就是阻塞),譬如應(yīng)用程序讀觸摸屏數(shù)據(jù),如果當前并沒有去觸碰觸摸屏,自然是無數(shù)據(jù)可讀。當我們用手指觸摸觸摸屏或者在屏上滑動時,此時就會產(chǎn)生觸摸數(shù)據(jù)、應(yīng)用程序就有數(shù)據(jù)可讀了,應(yīng)用程序會被喚醒,成功讀取到數(shù)據(jù)。那么對于其它輸入設(shè)備亦是如此,無數(shù)據(jù)可讀時應(yīng)用程序會進入休眠狀態(tài)(阻塞式 I/O 方式下),當有數(shù)據(jù)可讀時才會被喚醒。

第三:應(yīng)用程序該如何解析

應(yīng)用程序打開輸入設(shè)備對應(yīng)的設(shè)備文件,向其發(fā)起讀操作,那么這個讀操作獲取到的是什么樣的數(shù)據(jù)呢?其實每一次read操作獲取的都是一個struct input_event結(jié)構(gòu)體數(shù)據(jù),該結(jié)構(gòu)體定義在頭文件中,它的定義如下:

structinput_event{
structtimeval time;
__u16 type;
__u16 code;
__s32value;
};

結(jié)構(gòu)體中的time成員變量是一個struct timeval類型的變量,該結(jié)構(gòu)體在前面給大家介紹過,內(nèi)核會記錄每個上報的事件及發(fā)生的時間,并通過變量 time 返回給應(yīng)用程序。時間參數(shù)通常不是那么重要,而其它3 個成員變量 type、code、value 更為重要。

type:用于描述發(fā)生了哪一種類型的事件,Linux系統(tǒng)所支持的輸入事件類型如下所示:

#define EV_SYN 0x00 //同步類事件,用于同步事件
#define EV_KEY 0x01 //按鍵類事件
#define EV_REL 0x02 //相對位移類事件(譬如鼠標)
#define EV_ABS 0x03 //絕對位移類事件(譬如觸摸屏)
#define EV_MSC 0x04 //其它雜類事件

以上這些宏定義也是在頭文件中,所以在有應(yīng)用程序中需要包含該頭文件:一種輸入設(shè)備通??梢援a(chǎn)生多種不同類型的事件,譬如點擊鼠標按鍵(左鍵、右鍵,或鼠標上的其他按鍵)時會上報按鍵類事件,移動鼠標時則會上報相對位移類事件。

code:code表示該類事件中的哪一個具體事件,以上列舉的每一種事件類型中都包含一系列具體事件,譬如一個鍵盤通常有很多按鍵,譬如字母A、B、C、D或者數(shù)字1、2、3、4等,而code變量則告知應(yīng)用程序是哪一個按鍵發(fā)生了輸入事件。每一種事件類型包含多種不同的事件,譬如按鍵類事件;

#define KEY_RESERVED 0
#define KEY_ESC 1 //ESC 鍵
#define KEY_1 2 //數(shù)字 1 鍵
#define KEY_2 3 //數(shù)字 2 鍵
#define KEY_TAB 15 //TAB 鍵
#define KEY_Q 16 //字母 Q 鍵
#define KEY_W 17 //字母 W 鍵
#define KEY_E 18 //字母 E 鍵
#define KEY_R 19 //字母 R 鍵

相對位移事件

#define REL_X 0x00 //X 軸
#define REL_Y 0x01 //Y 軸
#define REL_Z 0x02 //Z 軸
#define REL_RX 0x03
#define REL_RY 0x04

絕對位移事件

觸摸屏設(shè)備是一種絕對位移設(shè)備,它能產(chǎn)生絕對位移事件;譬如對于觸摸屏來說,一個觸摸點所包含的信息可能有多種,譬如觸摸點的X軸坐標、Y軸坐標、Z軸坐標,按壓大小以及接觸面積等,所以code變量告知應(yīng)用程序當前上報的是觸摸點的哪一種信息。

#define ABS_X 0x00 //X 軸
#define ABS_Y 0x01 //Y 軸
#define ABS_Z 0x02 //Z 軸
#define ABS_RX 0x03
#define ABS_RY 0x04
#define ABS_RZ 0x05
#define ABS_THROTTLE 0x06
#define ABS_RUDDER 0x07
#define ABS_WHEEL 0x08
#define ABS_GAS 0x09

以上除了列舉出來的之外,還有很多,大家可以預(yù)覽頭文件。

value:內(nèi)核每次上報事件都會向應(yīng)用層發(fā)送一個數(shù)據(jù)value,對value值的解釋隨著code的變化而變化。譬如對于按鍵事件(type=1)來說,如果code=2(鍵盤上的數(shù)字鍵1,也就是KEY_1),那么如果value等于1,則表示KEY_1鍵按下;value等于0表示KEY_1鍵松開,如果value等于2則表示KEY_1鍵長按。在絕對位移事件中(type=3),如果 code=0(觸摸點 X 坐標 ABS_X),那么 value 值就等于觸摸點的 X 軸坐標值;同理,如果 code=1(觸摸點 Y 坐標 ABS_Y),此時value 值便等于觸摸點的 Y 軸坐標值;所以對 value 值的解釋需要根據(jù)不同的 code 值而定!

第四:數(shù)據(jù)同步方法

應(yīng)用程序讀取輸入設(shè)備上報的數(shù)據(jù)時,一次 read 操作只能讀取一個 struct input_event 類型數(shù)據(jù),譬如對于觸摸屏來說,一個觸摸點的信息包含了 X 坐標、Y 坐標以及其它信息,對于這樣情況,應(yīng)用程序需要執(zhí)行多次 read 操作才能把一個觸摸點的信息全部讀取出來,這樣才能得到觸摸點的完整信息。那么應(yīng)用程序如何得知本輪已經(jīng)讀取到完整的數(shù)據(jù)了呢?其實這就是通過同步事件來實現(xiàn)的,內(nèi)核將本輪需要上報、發(fā)送給接收者的數(shù)據(jù)全部上報完畢后,接著會上報一個同步事件,以告知應(yīng)用程序本輪數(shù)據(jù)已經(jīng)完整、可以進行同步了。

所有的輸入設(shè)備都需要上報同步事件通常是SYN_REPORT,而value值通常為0。

第五:讀取struct input_event數(shù)據(jù)代碼實現(xiàn)

對輸入設(shè)備調(diào)用read()會讀取到一個struct input_event類型數(shù)據(jù)。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{
 struct input_event in_ev = {0};
 int fd = -1;
  /* 校驗傳參 */
 if (2 != argc) {
 fprintf(stderr, "usage: %s 
", argv[0]);
 exit(-1);
 }
 /* 打開文件 */
 if (0 > (fd = open(argv[1], O_RDONLY))) {
 perror("open error");
 exit(-1);
 }
 for ( ; ; ) {
 /* 循環(huán)讀取數(shù)據(jù) */
 if (sizeof(struct input_event) !=
 read(fd, &in_ev, sizeof(struct input_event))) {
 perror("read error");
 exit(-1);
 }
 printf("type:%d code:%d value:%d
",
 in_ev.type, in_ev.code, in_ev.value);
 }
}

分析:該案件是,在出廠系統(tǒng)中,該案件驅(qū)動基于input子系統(tǒng)而實現(xiàn),所以在/dev/input目錄下存在KEY0的設(shè)備節(jié)點,具體是哪個設(shè)備節(jié)點,可以查看/proc/bus/input/devices文件得知。

3121c894-6042-11ed-8abf-dac502259ad0.png

執(zhí)行結(jié)果如下:

3163918e-6042-11ed-8abf-dac502259ad0.png

程序運行后,執(zhí)行按下 KEY0、松開 KEY0 等操作,終端將會打印出相應(yīng)的信息,如上圖所示。

第一行中 type 等于 1,表示上報的是按鍵事件 EV_KEY,code=114,打開 input-event-codes.h 頭文件進行查找,可以發(fā)現(xiàn) cpde=114 對應(yīng)的是鍵盤上的 KEY_VOLUMEDOWN 按鍵,這個開發(fā)板出廠系統(tǒng)已經(jīng)配置好的。而 value=1 表示按鍵按下,所以整個第一行的意思就是按鍵 KEY_VOLUMEDOWN被按下。

第二行,表示上報了 EV_SYN 同步類事件(type=0)中的 SYN_REPORT 事件(code=0),表示本輪數(shù)據(jù)已經(jīng)完整、報告同步。

第三行,type 等于 1,表示按鍵類事件,code 等于 114、value 等于 0,所以表示按鍵 KEY_VOLUMEDOWN被松開。

第四行,又上報了同步事件。

所以整個上面 4 行的打印信息就是開發(fā)板上的 KEY0 按鍵被按下以及松開這個過程,內(nèi)核所上報的事件以及發(fā)送給應(yīng)用層的數(shù)據(jù) value。我們試試長按按鍵 KEY0,按住不放,如下所示:

31915678-6042-11ed-8abf-dac502259ad0.png

可以看到上報按鍵事件時,對應(yīng)的 value 等于 2,表示長按狀態(tài)。

總結(jié):使用好標準的輸入設(shè)備系統(tǒng),對實現(xiàn)輸入功能具有重要意義。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 觸摸屏
    +關(guān)注

    關(guān)注

    42

    文章

    2276

    瀏覽量

    115614
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11173

    瀏覽量

    208485

原文標題:Linux系統(tǒng)中輸入設(shè)備的控制方法

文章出處:【微信號:嵌入式開發(fā)愛好者,微信公眾號:嵌入式開發(fā)愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    linux系統(tǒng)設(shè)備驅(qū)動一般分幾類

    視頻設(shè)備驅(qū)動 USB設(shè)備驅(qū)動 其他設(shè)備驅(qū)動 下面將對這些設(shè)備驅(qū)動進行詳細的介紹。 字符設(shè)備驅(qū)動
    的頭像 發(fā)表于 08-30 15:13 ?288次閱讀

    Linux設(shè)備驅(qū)動程序分類有哪些

    Linux設(shè)備驅(qū)動程序是操作系統(tǒng)與硬件設(shè)備之間的橋梁,負責實現(xiàn)硬件設(shè)備與操作系統(tǒng)之間的通信和控制
    的頭像 發(fā)表于 08-30 15:11 ?323次閱讀

    Linux 驅(qū)動開發(fā)與應(yīng)用開發(fā),你知道多少?

    一、Linux驅(qū)動開發(fā)與應(yīng)用開發(fā)的區(qū)別開發(fā)層次不同:Linux驅(qū)動開發(fā)主要是針對硬件設(shè)備進行編程,處于操作
    的頭像 發(fā)表于 08-30 12:16 ?366次閱讀
    <b class='flag-5'>Linux</b> 驅(qū)動開發(fā)與應(yīng)用開發(fā),你知道多少?

    PLC輸入設(shè)備有哪些

    在工業(yè)自動化領(lǐng)域,PLC(可編程邏輯控制器)作為核心控制設(shè)備,其輸入設(shè)備扮演著至關(guān)重要的角色。這些輸入設(shè)
    的頭像 發(fā)表于 06-15 11:25 ?1058次閱讀

    虹科干貨 |?多設(shè)備協(xié)同無憂:Linux環(huán)境PCAN固定設(shè)備ID/通道分配指南

    在車輛網(wǎng)絡(luò)系統(tǒng)和工業(yè)自動化等多設(shè)備環(huán)境中,確保設(shè)備識別的一致性對于維護系統(tǒng)穩(wěn)定性至關(guān)重要。虹科PCAN適配器提供了一種解決方案,允許用戶在Linux
    的頭像 發(fā)表于 06-11 15:03 ?358次閱讀
    虹科干貨 |?多<b class='flag-5'>設(shè)備</b>協(xié)同無憂:<b class='flag-5'>Linux</b>環(huán)境<b class='flag-5'>下</b>PCAN固定<b class='flag-5'>設(shè)備</b>ID/通道分配指南

    util-linux修復(fù)WallEscape漏洞,影響Linux系統(tǒng)wall命令使用

    WallEscape 主要影響“wall”命令操作,Linux 系統(tǒng)中的常規(guī),該指令被用作向系統(tǒng)所有登錄用戶的終端發(fā)布消息。然而在處理命令行參數(shù)
    的頭像 發(fā)表于 03-29 14:35 ?886次閱讀

    cyusb3014將固件程序編程到SPI Flash中進行調(diào)試,系統(tǒng)會提示我重置設(shè)備怎么解決?

    你好,我現(xiàn)在想把我的固件程序編程到 SPI Flash 中進行調(diào)試。 但是,在第一次燒錄之后,如果我想再次燒錄它,系統(tǒng)會提示我重置設(shè)備。 重置或關(guān)閉電源不允許我重新
    發(fā)表于 02-27 08:21

    FCX3使用cyusb_linux通過Linux對其進行編程,報SPI扇區(qū)擦除失敗怎么解決?

    我有一個 FCX3 定制板,我嘗試使用 cyusb_linux 通過 Linux 對其進行編程。 我 CAN 看到設(shè)備 VID (04b4)
    發(fā)表于 02-26 06:39

    Linux操作系統(tǒng)中如何按PCIe的復(fù)位鍵

    Linux操作系統(tǒng)中,看如何按PCIe的復(fù)位鍵
    的頭像 發(fā)表于 01-20 09:31 ?1320次閱讀
    <b class='flag-5'>Linux</b>操作<b class='flag-5'>系統(tǒng)</b>中如何按<b class='flag-5'>下</b>PCIe的復(fù)位鍵

    linux系統(tǒng)如何進行磁盤分區(qū)?

    linux系統(tǒng)如何進行磁盤分區(qū)? 磁盤分區(qū)是在Linux系統(tǒng)進行硬盤劃分的一種方法,它可以將一
    的頭像 發(fā)表于 12-19 11:35 ?940次閱讀

    vm虛擬機linux系統(tǒng)怎么編程

    不同的操作系統(tǒng)之間切換,并在Linux系統(tǒng)進行編程和開發(fā)。 以下是使用虛擬機在Linux
    的頭像 發(fā)表于 11-17 10:10 ?1673次閱讀

    linux系統(tǒng)基礎(chǔ)入門教程

    1991年,由芬蘭學生林納斯·托瓦茲(Linus Torvalds)開始開發(fā)。與其他操作系統(tǒng)不同,Linux采用了開源的模式,這意味著任何人都可以查看、使用和修改其源代碼。 Linux系統(tǒng)
    的頭像 發(fā)表于 11-16 16:45 ?948次閱讀

    Linux系統(tǒng)I/O操作講解

    Linux系統(tǒng)I/O 一、I/O簡介 I/O(輸入/輸出)是在主存和外部設(shè)備(磁盤驅(qū)動器、網(wǎng)絡(luò)、終端)之間復(fù)制數(shù)據(jù)的過程。
    的頭像 發(fā)表于 11-08 15:13 ?1016次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統(tǒng)</b><b class='flag-5'>下</b>I/O操作講解

    linux命令和shell編程有什么聯(lián)系

    Linux命令和Shell編程之間存在密切的聯(lián)系。 首先,Shell是Linux命令行的解釋器,它提供了一個用戶界面,使用戶能夠與Linux
    的頭像 發(fā)表于 11-08 10:53 ?842次閱讀

    基于Linux的嵌入式Web Server系統(tǒng)在溫室設(shè)備監(jiān)控系統(tǒng)中的應(yīng)用

    電子發(fā)燒友網(wǎng)站提供《基于Linux的嵌入式Web Server系統(tǒng)在溫室設(shè)備監(jiān)控系統(tǒng)中的應(yīng)用.pdf》資料免費下載
    發(fā)表于 10-27 09:29 ?0次下載
    基于<b class='flag-5'>Linux</b>的嵌入式Web Server<b class='flag-5'>系統(tǒng)</b>在溫室<b class='flag-5'>設(shè)備</b>監(jiān)控<b class='flag-5'>系統(tǒng)</b>中的應(yīng)用