linux 编程--linux创建一个虚拟的按键(power_key模拟)

系统:嵌入式 linux 系统
平台:高通平台
代码:

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

int main() {
    struct uinput_setup usetup;
    struct input_event ev;

    // 1. 打开 /dev/uinput 设备
    int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("Failed to open /dev/uinput");
        return 1;
    }

    // 2. 告诉 uinput 我们需要发送按键事件 (EV_KEY)
    ioctl(fd, UI_SET_EVBIT, EV_KEY);
    ioctl(fd, UI_SET_KEYBIT, KEY_POWER); // 设置支持 KEY_POWER

    // 3. 告诉 uinput 我们将要使用的按键是电源键 (KEY_POWER)
    ioctl(fd, UI_SET_KEYBIT, KEY_POWER);

    // 4. 初始化虚拟设备的信息
    memset(&usetup, 0, sizeof(usetup));
    snprintf(usetup.name, UINPUT_MAX_NAME_SIZE, "Virtual Power Button");
    usetup.id.bustype = BUS_USB;
    usetup.id.vendor  = 0x1234;  // 任意供应商 ID
    usetup.id.product = 0x5678;  // 任意产品 ID
    usetup.id.version = 1;

    // 5. 创建虚拟设备
    ioctl(fd, UI_DEV_SETUP, &usetup);
    ioctl(fd, UI_DEV_CREATE);

    sleep(1); // 休眠 1 秒以确保设备已准备好

while(1){
    printf("power_on: down\n");
    // 6. 模拟电源键按下 (KEY_POWER press)
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = KEY_POWER;
    ev.value = 1;  // 按下状态
    write(fd, &ev, sizeof(struct input_event));

    // 同步事件 (告诉内核事件已结束)
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    write(fd, &ev, sizeof(struct input_event));

    printf("power_on: realse\n");
    // 6. 模拟电源键按下 (KEY_POWER press)
    // 模拟电源键释放 (KEY_POWER release)
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = KEY_POWER;
    ev.value = 0;  // 释放状态
    write(fd, &ev, sizeof(struct input_event));

    // 同步事件
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    write(fd, &ev, sizeof(struct input_event));

    sleep(3);  // 暂停 1 秒以查看效果
}
   // while(1){sleep(1);}

    // 7. 销毁虚拟设备
    ioctl(fd, UI_DEV_DESTROY);
    close(fd);

    return 0;
}

1 将上述代码保存为 virtual_power_button.c。

2 编译代码:
aarch64-oe-linux-gcc -o virtual_power_button virtual_power_button.c
(aarch64-oe-linux-gcc是我的交叉编译环境。
如果是在ubuntu运行可以这样子编译:
gcc -o virtual_power_button virtual_power_button.c)

adb push virtual_power_button /data/ #push到/data/目录

3 使用 root用户该程序,因为操作 uinput 需要超级用户权限:

./virtual_power_button

3.1 运行后会生成类似这样子的设备:

/data # cat /proc/bus/input/devices | grep -A 5 -B 1 “Virtual Power
Button” I: Bus=0003 Vendor=1234 Product=5678 Version=0001 N:
Name=“Virtual Power Button” P: Phys= S:
Sysfs=/devices/virtual/input/input11 U: Uniq= H: Handlers=kbd event5
cpufreq B: PROP=0

3.2 我这里生成的是event5,所以可以监听event5,验证按键按下和释放的过程

/data # ./evtest /dev/input/event5 Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x1234 product 0x5678 version 0x1
Input device name: “Virtual Power Button” Supported events: Event
type 0 (EV_SYN) Event type 1 (EV_KEY)
Event code 116 (KEY_POWER) Properties: Testing … (interrupt to exit) Event: time 1729590307.1729590307, type 1 (EV_KEY), code 116
(KEY_POWER), value 1 Event: time 1729590307.1729590307, --------------
SYN_REPORT ------------ Event: time 1729590307.1729590307, type 1
(EV_KEY), code 116 (KEY_POWER), value 0 Event: time
1729590307.1729590307, -------------- SYN_REPORT ------------ Event: time 1729590310.1729590310, type 1 (EV_KEY), code 116 (KEY_POWER),
value 1 Event: time 1729590310.1729590310, -------------- SYN_REPORT
------------ Event: time 1729590310.1729590310, type 1 (EV_KEY), code 116 (KEY_POWER), value 0 Event: time 1729590310.1729590310,
-------------- SYN_REPORT ------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值