使用 ARMv8 程序集和 Uinput 模拟击键
Posted
技术标签:
【中文标题】使用 ARMv8 程序集和 Uinput 模拟击键【英文标题】:Emulating a keystroke using ARMv8 assembly and Uinput 【发布时间】:2018-07-22 08:42:20 【问题描述】:2018 年 7 月 23 日更新:
我有 uinput 的 C 代码实现如下:
#include <linux/uinput.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
void emit(int fd, int type, int code, int val)
struct input_event ie;
ie.type = type;
ie.code = code;
ie.value = val;
/* timestamp values below are ignored */
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
write(fd, &ie, sizeof(ie));
int main(void)
struct uinput_setup usetup;
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
/*
* The ioctls below will enable the device that is about to be
* created, to pass key events, in this case the space key.
*/
ioctl(fd, UI_SET_EVBIT, EV_KEY);
ioctl(fd, UI_SET_KEYBIT, KEY_W);
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234; /* sample vendor */
usetup.id.product = 0x5678; /* sample product */
strcpy(usetup.name, "Example device");
ioctl(fd, UI_DEV_SETUP, &usetup);
ioctl(fd, UI_DEV_CREATE);
/*
* On UI_DEV_CREATE the kernel will create the device node for this
* device. We are inserting a pause here so that userspace has time
* to detect, initialize the new device, and can start listening to
* the event, otherwise it will not notice the event we are about
* to send. This pause is only needed in our example code!
*/
sleep(1);
while(1)
/* Key press, report the event, send key release, and report again */
emit(fd, EV_KEY, KEY_W, 1);
/*
* Give userspace some time to read the events before we destroy the
* device with UI_DEV_DESTOY.
*/
sleep(1);
ioctl(fd, UI_DEV_DESTROY);
close(fd);
return 0;
但是好像没有输出
旧帖 07/22/2018 我已经在这个项目上工作了一段时间,并在这里找到了解决我的一些错误的帮助。
我有工作 ARM 汇编代码,它从我的树莓派 3 的 GPIO 中获取按钮输入,我需要最后一件事来最终让它一劳永逸。
我需要找到某种方法让系统认为按钮按下了某个键,这样游戏就可以将输入解释为游戏代码中的击键。或者更好的是只有一个简单的屏幕,我可以在屏幕上移动一个像素。我发现很难找到 ARM 语言的帮助。
我的代码如下:
//data Section
.data
.align 4
Intro: .asciz "Raspberry Pi - Blinking led test inassembly\n"
ErrMsg: .asciz "Setup didn't work... Aborting...\n"
TestMsg: .asciz "Test stuff\n"
Up: .asciz "Up pressed"
Left: .asciz "Left Pressed"
Down: .asciz "Down Pressed"
Right: .asciz "Right pressed"
Pause: .asciz "Pause pressed"
Quit: .asciz "Quit pressed"
Pressed: .asciz "button pressed"
// WiringPi pin values
pinUp: .int 15
pinLeft: .int 3
pinDown: .int 0
pinRight:.int 7
pinPau: .int 16
pinQu: .int 2
i: .int 10
Compr: .int 1
INPUT = 0
//Code section
.text
.global main
.extern printf
.extern scanf
.extern wiringPiSetup
.extern delay
.extern digitalRead
.extern pinMode
main: push ip, lr
// printf message
ldr r0, =Intro
bl printf
//Check for setup error
bl wiringPiSetup
mov r1,#-1
cmp r0, r1
bne init
ldr r0, =ErrMsg
bl printf
b done
init:
//Set all pins to input
ldr r0, =pinUp
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
ldr r0, =pinLeft
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
ldr r0, =pinDown
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
ldr r0, =pinRight
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
ldr r0, =pinPau
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
ldr r0, =pinQu
ldr r0, [r0]
mov r1, #INPUT
bl pinMode
b while
while:
//Digital Read
ldr r0, =pinUp
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msg
ldr r0, =pinLeft
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msgleft
ldr r0, =pinDown
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msgdown
ldr r0, =pinRight
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msgRight
ldr r0, =pinPau
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msgpause
ldr r0, =pinQu
ldr r0, [r0]
bl digitalRead
cmp r0, #1
beq msgquit
b while // Loop back
// Messages for input
msg:
ldr r0, =Up
bl printf
b while
msgleft:
ldr r0, =Left
bl printf
b while
msgRight:
ldr r0, =Right
bl printf
b while
msgdown:
ldr r0, =Down
bl printf
b while
msgpause:
ldr r0, =Pause
bl printf
b while
msgquit:
ldr r0, =Quit
bl printf
b while
done:
pop ip,pc
任何帮助将不胜感激
【问题讨论】:
【参考方案1】:要为所有 Linux 程序注入按键,您需要使用 uinput interface。
打开/dev/input/uinput
或/dev/uinput
,使用ioctl 调用对其进行配置,然后编写输入事件结构。
【讨论】:
@ Timothy Baldwin 我对此完全陌生,所以我不知道要更改什么或 ioctl 调用做什么。我知道这是输入输出控制,但其他方面我什么都没有。 您是否点击了我提供给文档的链接?你有什么不明白的? 好的,我对你所说的有了更好的理解。我查看了链接,现在正在尝试实现它。我认为我拥有的代码应该连续按“w”,但它似乎不起作用。我正在运行一个游戏来测试输入。我会用新的 C 代码更新问题以上是关于使用 ARMv8 程序集和 Uinput 模拟击键的主要内容,如果未能解决你的问题,请参考以下文章