加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 實(shí)現(xiàn)原理
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Linux input子系統(tǒng)(二)uinput 原理和用途

05/11 11:27
5013
閱讀需 8 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

哈嘍,大家好,我是程序員秘書LittleG。

前言

uinputUserspace Input,uinput 的實(shí)現(xiàn)是基于 Linux input子系統(tǒng)(Input Subsystem),允許用戶空間程序創(chuàng)建虛擬的輸入設(shè)備并向內(nèi)核發(fā)送輸入事件,比如鍵盤敲擊、鼠標(biāo)移動(dòng)等,就像這些事件來(lái)自真實(shí)的物理設(shè)備一樣。對(duì)于開發(fā)自定義輸入設(shè)備驅(qū)動(dòng)、自動(dòng)化測(cè)試、游戲控制模擬以及各種人機(jī)交互實(shí)驗(yàn)等場(chǎng)景非常有用。

可能的使用場(chǎng)景有:

自動(dòng)化測(cè)試:模擬用戶操作,如點(diǎn)擊、滑動(dòng)等,進(jìn)行UI自動(dòng)化測(cè)試。在自動(dòng)化測(cè)試過程中,可以模擬用戶的輸入操作來(lái)測(cè)試軟件的功能。

自定義輸入設(shè)備:為沒有驅(qū)動(dòng)支持的新奇設(shè)備創(chuàng)建虛擬驅(qū)動(dòng)。

游戲控制模擬:模擬游戲手柄或其他特殊控制器。一些游戲玩家可能會(huì)使用腳本來(lái)自動(dòng)執(zhí)行一些復(fù)雜的操作。

輔助工具開發(fā):如屏幕鍵盤、宏命令工具等。實(shí)現(xiàn)一些輔助工具(如屏幕閱讀器、殘疾人輔助工具等)可能需要模擬輸入設(shè)備來(lái)與操作系統(tǒng)或其他應(yīng)用程序進(jìn)行交互。

uinput的使用場(chǎng)景非常廣泛,包括但不限于以上場(chǎng)景。下面就學(xué)習(xí)看下原理和如何使用。

實(shí)現(xiàn)原理

uinput?通過在內(nèi)核和用戶空間之間創(chuàng)建一個(gè)特殊的設(shè)備文件(通常是?/dev/uinput)來(lái)工作。用戶空間程序可以打開這個(gè)文件,并向其中寫入數(shù)據(jù)來(lái)模擬輸入事件。這些數(shù)據(jù)會(huì)被內(nèi)核的輸入子系統(tǒng)接收,并像真實(shí)的輸入設(shè)備產(chǎn)生的事件一樣進(jìn)行處理。

具體來(lái)說,uinput?的實(shí)現(xiàn)包括以下幾個(gè)步驟:

創(chuàng)建 uinput 設(shè)備:用戶空間程序通過?ioctl?調(diào)用?UINPUT_CREATE_DEVICE?請(qǐng)求來(lái)創(chuàng)建一個(gè)?uinput?設(shè)備。這個(gè)請(qǐng)求需要指定模擬的輸入設(shè)備的類型和屬性。

設(shè)置輸入事件:用戶空間程序通過寫入?/dev/uinput?設(shè)備文件來(lái)設(shè)置要模擬的輸入事件。這些事件可以是鍵盤按鍵、鼠標(biāo)移動(dòng)、觸摸屏觸摸等。

啟用 uinput 設(shè)備:在設(shè)置完所有需要的輸入事件后,用戶空間程序通過?ioctl?調(diào)用?UINPUT_START_DEVICE?請(qǐng)求來(lái)啟用?uinput?設(shè)備。此時(shí),內(nèi)核的輸入子系統(tǒng)會(huì)開始處理這些模擬的輸入事件。

發(fā)送輸入事件:一旦?uinput?設(shè)備被啟用,用戶空間程序就可以通過寫入?/dev/uinput?設(shè)備文件來(lái)發(fā)送輸入事件了。這些事件會(huì)被內(nèi)核的輸入子系統(tǒng)接收,并像真實(shí)的輸入設(shè)備產(chǎn)生的事件一樣進(jìn)行處理。

銷毀 uinput 設(shè)備:當(dāng)用戶空間程序不再需要模擬輸入設(shè)備時(shí),它可以通過?ioctl?調(diào)用?UINPUT_DESTROY_DEVICE?請(qǐng)求來(lái)銷毀?uinput?設(shè)備。

補(bǔ)充說明

關(guān)于配置設(shè)備屬性
在創(chuàng)建虛擬設(shè)備之前,需要通過ioctl調(diào)用配置設(shè)備的各種屬性,比如設(shè)備名稱、ID(廠商ID、產(chǎn)品ID、版本等)、支持的事件類型(EV_KEY、EV_REL、EV_ABS等)和具體的事件代碼(如BTN_LEFT、KEY_A、REL_X等)。

關(guān)于發(fā)送事件
一旦設(shè)備被創(chuàng)建,就可以通過寫入input_event結(jié)構(gòu)體到文件描述符來(lái)模擬輸入事件。每個(gè)事件包括類型(EV_KEY、EV_REL等)、代碼(按鍵、軸等)、值(按鍵狀態(tài)、移動(dòng)距離等)以及一個(gè)同步事件(EV_SYN)來(lái)標(biāo)記事件包的結(jié)束。

使用舉例

下面是一個(gè)簡(jiǎn)單的使用例子,通過uinput創(chuàng)建虛擬鍵盤并發(fā)送一次鍵擊事件:

#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd;
    struct uinput_user_dev uidev;
    struct input_event ev;

    /* 打開uinput設(shè)備 */
    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("Error opening /dev/uinput");
        return 1;
    }

    /* 配置虛擬設(shè)備 */
    memset(&uidev, 0, sizeof(uidev));
    strncpy(uidev.name, "Virtual Keyboard", UINPUT_MAX_NAME_SIZE);
    uidev.id.bustype = BUS_USB;
    uidev.id.vendor = 0x1234;
    uidev.id.product = 0x5678;
    uidev.id.version = 1;

    /* 設(shè)置支持的事件類型 */
    ioctl(fd, UI_SET_EVBIT, EV_KEY);
    ioctl(fd, UI_SET_KEYBIT, KEY_A);

    /* 創(chuàng)建虛擬設(shè)備 */
    write(fd, &uidev, sizeof(uidev));
    ioctl(fd, UI_DEV_CREATE);

    /* 發(fā)送按鍵事件 */
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_KEY;
    ev.code = KEY_A;
    ev.value = 1; // 按下
    write(fd, &ev, sizeof(ev));

    ev.value = 0; // 抬起
    write(fd, &ev, sizeof(ev));

    /* 發(fā)送同步事件 */
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    write(fd, &ev, sizeof(ev));

    /* 銷毀設(shè)備 */
    ioctl(fd, UI_DEV_DESTROY);
    close(fd);

    return 0;
}

說明:以上代碼中,創(chuàng)建了一個(gè)名為"Virtual Keyboard"的虛擬鍵盤設(shè)備,發(fā)送了一個(gè)"A"鍵的按下與釋放事件,并在最后銷毀了虛擬設(shè)備。

注意,調(diào)試運(yùn)行時(shí),可能會(huì)存在相應(yīng)的權(quán)限問題,可以使用root登錄運(yùn)行或chmod修改/dev/uinput權(quán)限。

下期見~

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
LS027B7DH01A 1 Sharp Corp Graphic Dot Matrix LCD Display,
$40.78 查看
ZL62034UBJA 1 Microsemi Corporation FIBER OPTIC RECEIVER, 6250Mbps
暫無(wú)數(shù)據(jù) 查看
ABS10-32.768KHZ-T 1 Abracon Corporation CRYSTAL 32.7680KHZ 12.5PF SMD

ECAD模型

下載ECAD模型
$1.5 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

記錄和分享C/C++、Linux、ARM、Android、IoT相關(guān)知識(shí)。技術(shù)相伴于生活和成長(zhǎng),愿你我永為少年,心中有火,眼中有光,始保熱情。