entrada subsistema de entrada - conocimientos básicos 1

drivers / input / input.c:
    input_init> err = register_chrdev (INPUT_MAJOR, "input", & input_fops);
    
static const struct file_operations input_fops = {     .owner = THIS_MODULE,     .open = input_open_file, };


P: ¿Cómo leer las claves?

input_open_file
    struct input_handler * handler = input_table [iminor (inode) >> 5];
    new_fops = fops_get (controlador-> fops) // =>
    archivo & evdev_fops- > f_op = new_fops;
    err = new_fops-> open (inodo, archivo);

aplicación: leer> ...> archivo-> f_op-> leer  

¿Quién construye la matriz input_table?

input_register_handler


Registrar input_handler:
input_register_handler
    // poner en la matriz
    input_table [handler-> minor >> 5] = handler;
    
    // poner en la lista enlazada
    list_add_tail (& handler-> node, & input_handler_list);

    // Para cada input_dev, llame a input_attach_handler
    list_for_each_entry (dev, & input_dev_list, node)
        input_attach_handler (dev, handler); // Determine si input_dev puede ser compatible de acuerdo con la id_table de input_handler
    
    


Registrar el dispositivo de entrada:
input_register_device
    // Poner en la lista vinculada
    list_add_tail (& dev-> node, & input_dev_list);
    
    // Para cada input_handler, llame a input_attach_handler
    list_for_each_entry (handler, & input_handler_list, node)
        input_attach_handler (dev, handler_handler); // id_table determina si este input_dev puede ser compatible


input_attach_handler
    id = input_match_device (manejador-> id_table, dev);
    
    error = manejador-> conectar (manejador, dev, id);


Al registrar input_dev o input_handler, comparará input_dev a la izquierda y input_handler a la derecha.
Según la id_table del input_handler, juzgue si input_handler puede soportar input_dev.
Si puede, llame a la función connect de input_handler para establecer una "conexión"

¿Cómo establecer una conexión?
1. Asignar una estructura input_handle
2. 
    input_handle.dev = input_dev; // señalar al input_dev a la izquierda
    input_handle.handler = input_handler; // señalar al input_handler a la derecha
3. Registro:
   input_handler-> h_list = & input_handle;
   inpu_dev-> h_list = & input_handle ;


evdev_connect
    evdev = kzalloc (sizeof (struct evdev), GFP_KERNEL); // asigna un input_handle
    
    // establece
    evdev-> handle.dev = dev; // apunta a la izquierda input_dev
    evdev-> handle.name = evdev-> name;
    evdev -> handle.handler = handler; // Input_handler apuntando a la derecha
    evdev-> handle.private = evdev;
    
    //
    Error de registro = input_register_handle (& evdev-> handle);
    
¿Cómo leer el botón?
app: read
--------------------------
   .......
           evdev_read
               // Si no hay datos y se abre en modo sin bloqueo, volverá inmediatamente
            if (cliente-> cabeza == cliente-> cola && evdev-> existe && (archivo-> f_flags & O_NONBLOCK))
                return -EAGAIN;
            

            retval = wait_event_interruptible (evdev-> espera,
                cliente-> cabeza! = cliente-> cola ||! evdev-> existe);
               

¿Quién se despertará?
evdev_event wake_up_interruptible
    (& evdev-> esperar);


¿Quién llama a evdev_event?
Adivina: debe ser el código relacionado con el hardware, que es llamado por la capa input_dev.
En la rutina de servicio de interrupción del dispositivo, determina cuál es el evento y luego llama a la función de procesamiento de eventos input_handler correspondiente
gpio_keys_isr
    // report event
    input_event (input, type, button-> código, !! estado);
    input_sync (entrada);
    
input_event (struct input_dev * dev, unsigned int type, unsigned int code, int value)
    struct input_handle * handle;

    list_for_each_entry (handle, & dev-> h_list, d_node)
        if (handle-> open)
            handle-> handler-> event (handle, type, code, value);


¿Cómo escribir un controlador que se ajuste al marco del subsistema de entrada?
1. Asignar una estructura input_dev
2. Configuración
3. Registro
4. Código relacionado con el hardware, como informes de eventos en la rutina del servicio de interrupciones
            


struct input_dev {

    void * privado;

    const char * nombre;
    const char * phys;
    const char * uniq;
    struct input_id id;

    unsigned long evbit [NBITS (EV_MAX)]; // Indica qué tipos de eventos se pueden generar
    unsigned long keybit [NBITS (KEY_MAX)]; // Indica qué claves se pueden generar
    unsigned long relbit [NBITS (REL_MAX)]; // Indica que se pueden generar Qué eventos de desplazamiento relativo, x, y, wheel
    unsigned long absbit [NBITS (ABS_MAX)]; // Indica qué eventos de desplazamiento absoluto se pueden generar, x, y
    unsigned long mscbit [NBITS (MSC_MAX)];
    unsigned long ledbit [NBITS (LED_MAX) )];
    sndbit largo sin firmar [NBITS (SND_MAX)];
    ffbit largo sin firmar [NBITS (FF_MAX)];
    swbit largo sin firmar [NBITS (SW_MAX)];

Prueba:
1. 
el hexdump / dev / EVENT1 (Open (/ dev / EVENT1), Read (),)
           segundos microsegundos código de valor de clase
0000000 0bb2 000C 0000 0001 0026 0001 0000 0e48
0000010 0bb2 000C 0000 0000 0000 0000 0000 0e54 0,00002
millones 0bb2 0000 5815 000e 0001 0026 0000 0000
0000030 0bb2 0000 581f 000e 0000 0000 0000 0000

2. Si no inicia QT:
cat / dev / tty1
presione: s2, s3, s4
para obtener ls

O:
exec 0 </ dev / tty1
y luego puede usar las teclas para ingresar


3. Si ha iniciado QT:
puede hacer clic para abrir el Bloc de notas
y luego presionar: s2, s3, s4

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_26690505/article/details/86494624
Recomendado
Clasificación