Subsistema de entrada del controlador de caracteres avanzado de Linux

El papel y el marco del subsistema de insumos

  • Que es un dispositivo de entrada
  1. Tecla / teclado
  2. ratón
  3. pantalla táctil (pantalla táctil): gt811, ft56xx
  4. joystick joystick
  • Cuando hay varios dispositivos de entrada que necesitan ser controlados, si el subsistema de entrada no se considera

  1. número de dispositivo gt811 , creación de archivos, inicialización de hardware, realización de fop, bloqueo, inicialización de hardware (I2C, etc.)
  2. Número de
    dispositivo ft56xx , creación de archivos, inicialización de hardware, realización de fop, bloqueo, inicialización de hardware (I2C, etc.).
  • El punto común de múltiples dispositivos de entrada :
    obtener datos (operación de hardware) ------- diferenciación e
    informar al usuario (xxx_read, copy_to_user, bloqueo) ------ múltiples dispositivos de entrada son comunes
    , hay algunas diferencias, También hay algunos
    núcleos de propósito general que considerarán, escribirán bien el código general y dejarán el código diferenciado al ingeniero del controlador.
  • Diseñado como un subsistema de entrada: hace que la programación de programadores de aplicaciones y programadores de controladores sea simple y unificada
  1. Compatible con todos los dispositivos de entrada
  2. Método de unidad de programación unificada (para lograr una operación de hardware diferenciada)
  3. Interfaz de operación de la aplicación unificada: / dev / input / event0, event1, open ("/ dev / input / event0, event1"), read (fd, struct input_event) : struct input_event buff puede considerarse como un paquete de datos unificado

cuadro

  • Marco: el controlador está dividido en tres capas: la
    Inserte la descripción de la imagen aquí
    Inserte la descripción de la imagen aquí
    capa del núcleo de entrada y la capa del controlador de entrada. El propio código del kernel, el ingeniero del controlador solo necesita
    programar en la capa del dispositivo de entrada: en la capa del dispositivo de entrada

Cómo programar el subsistema de entrada

  • El método de programación del subsistema de entrada: aprenda la forma sencilla de desarrollar el subsistema de entrada
  • Requisito previo: el código de la capa del núcleo de entrada y el código de la capa del controlador de entrada deben tener /drivers/input/input.c en el kernel
    // código de la capa del núcleo
    /drivers/input/evdev.c // controlador de eventos
  • make menuconfig
    Controladores de dispositivo—> Soporte de dispositivo de entrada—> Capa de
    entrada
    Inserte la descripción de la imagen aquí
    genérica
    Interfaz de eventos // controlador de entrada 层 evdev.c

Pasos de programación:
(1) Asignar un objeto de dispositivo de entrada
(2) Inicializar el objeto de dispositivo de entrada
(3) Registrar el objeto de dispositivo de entrada

  • Informe de datos
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)

Parámetro 1: Los datos
reportados por el dispositivo de entrada actual Parámetro 2: El tipo de datos reportados es EV_KEY, EV_ABS
Parámetro 3: ¿Cuáles son los datos específicos: KEY_POWER
Parámetro 4: Cuál es el valor

  • Lectura de datos en el espacio de usuario: paquete de datos unificado
struct input_event
{
    
    
	struct timeval time;   //时间戳
	__u16 type;  //数据类型
	__u16 code;  //具体数据是什么
	__s32 value;  //值是什么
}
  • Ejemplo de código
#include<linux/init.h>
#include<linux/module.h>
#include<linux/input.h>

struct input_dev *inputdev;

static int __init simple_input_init(void)
{
    
    

    //编写输入子系统代码
    /*
     *(1)分配一个 input device 对象
     *(2)初始化 input device 对象
     *(3)注册 input device 对象
     * */

    int ret;
    inputdev = input_allocate_device(); 
    if(inputdev == NULL)
    {
    
    
        printk(KERN_ERR "input allocate device error\n");
        return -ENOMEM;
    }

    //当前设备能够产生按键数据
    __set_bit(EV_KEY,inputdev->evbit);
    //表示当前设备能够产生power按键
    __set_bit(KEY_POWER,inputdev->keybit);

    ret = input_register_device(inputdev);
    if(ret != 0)
    {
    
    
        printk(KERN_ERR "input register device error\n");
        goto err_0;
        return ret;
    }
    return 0;

err_0:
    input_free_device(inputdev);
    return ret;
}



static void __exit simple_input_exit()
{
    
    
    
    input_unregister_device(inputdev);
    input_free_device(inputdev);

}

module_init(simple_input_init);
module_exit(simple_input_exit);
MODULE_LICENSE("GPL");

Aplicación de espacio de usuario:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(void)
{
    
    
	int fd;
	int ret;
	struct input_event event;
	
	fd = open("/dev/event0",O_RDWR);
	if(fd < 0)
	{
    
    
		perror("open");
		exit(1);
	}
	
	while(1)
	{
    
    
		ret = read(fd,&event,sizeof(struct input_event));
		if(ret < 0)
		{
    
    
			perror("read");
			exit(1);
		}
		
		if(event.type == EV_KEY)
		{
    
    
			if(event.code == KEY_POWER)
			{
    
    
				if(event.value)   //按键按下
				{
    
    
					printf("__APP_USER__:power pressed\n");
				}
				else  //按键抬起
				{
    
    
					printf("__APP_USER__:power up\n");
				}
			}
		}
	}
	close(fd);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_41782149/article/details/99701533
Recomendado
Clasificación