Уинпут и Малина Пи
Я пытался задать этот вопрос на форумах Raspberry Pi, но я не получил никаких ответов вообще. Я подумал, что могу спросить умы сообщества Stackru, которое было так полезно в прошлом.
Я пишу драйвер для пользовательского пространства для Raspberry Pi (в частности, позже он может быть перенесен на другие платформы), который использует библиотеку bcm2835 (GPIO) и uinput (виртуальные устройства пользовательского ввода Linux). Мне нужно прочитать выводы GPIO и перевести их значения в симулированные нажатия клавиш на виртуальной клавиатуре. Часть GPIO была завершена, и часть перевода также завершена. К сожалению, часть виртуальной клавиатуры не была решена. Uinput отказывается сотрудничать.
Теперь точно такой же код отлично работает на настольном компьютере Debian. evdev
а также uinput
Требуются модули, оба из которых были загружены во всех тестовых случаях. На рабочем столе входы могут быть активированы, однако на Raspberry Pi я могу убедиться, что подсистема GPIO зарегистрировала вход, но события uinput не срабатывают. Кто-нибудь знает, что я могу сделать?
Большое спасибо, если вам нужна какая-либо информация, журналы или что-то еще, пожалуйста, дайте мне знать, и я опубликую их, как только смогу.
0 ответов
Это полное решение, которое мне подходит. У меня есть клавиатура, сделанная на заказ, и это те клавиши, которые я определил. Вот ссылка на исходный PDF-файл, который я использовал. Конечно, вы можете определить любой ключ, который хотите, просто добавьте его в массив.
Примечание: этот код работает только с повышенными разрешениями.
int allowed_keys[allowed_KEYS_size][2] = {0};
void main()
{
init_keys();
int fd = open_uinput();
int key_evt = getKeyEVT(49); // ASCII code for 1
// simulate key press and key release
emit(fd, EV_KEY, key_evt, 1);
emit(fd, EV_SYN, SYN_REPORT, 0);
emit(fd, EV_KEY, key_evt, 0);
emit(fd, EV_SYN, SYN_REPORT, 0);
}
long int 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;
long int y = write(fd, &ie, sizeof(ie));
return y;
}
int open_uinput()
{
int fdui = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fdui < 0)
{
printf("uinput fd creation failed!\n");
exit(EXIT_FAILURE);
}
ioctl(fdui, UI_SET_EVBIT, EV_KEY);
ioctl(fdui, UI_SET_EVBIT, EV_SYN); //added by behzad
for (int i = 0; i < allowed_KEYS_size; i++)
ioctl(fdui, UI_SET_KEYBIT, allowed_keys[i][1]);
struct uinput_setup usetup;
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, "My Keypad. Ver 1.1");
ioctl(fdui, UI_DEV_SETUP, &usetup);
ioctl(fdui, UI_DEV_CREATE);
sleep(2);
return fdui;
}
int getKeyEVT(int k)
{
for (int i = 0; i < allowed_KEYS_size; i++)
{
if (allowed_keys[i][0] == k)
return allowed_keys[i][1];
}
return -1;
}
void init_keys()
{
// Reference:
// https://www.alt-codes.net/arrow_alt_codes.php
// /usr/include/linux/input-event-codes.h
allowed_keys[0][0] = 48; //ASCII ---> 0
allowed_keys[0][1] = KEY_0; //LINUX
allowed_keys[1][0] = 49; //ASCII
allowed_keys[1][1] = KEY_1; //LINUX
allowed_keys[2][0] = 50; //ASCII
allowed_keys[2][1] = KEY_2; //LINUX
allowed_keys[3][0] = 51; //ASCII
allowed_keys[3][1] = KEY_3; //LINUX
}