Linux interrumpe el flujo de procesamiento

  

Primero, la arquitectura de hardware del sistema de interrupción:

arm cortex-A9, el controlador de interrupción en A15 es GIC400 (la versión inferior tiene GIC390, PL190, etc.), el diagrama lógico del hardware es < Br>

EXTINT0-EXTINT2: Establezca EINT0 — EINT7, EINT8 — EINT15, EINT16 — EINT23 modo de disparo (disparador de nivel alto, disparador de nivel bajo, disparador de borde descendente, disparador de borde ascendente).

EINTPEND: Este es el registro de interrupciones pendientes. Escriba 1 al borrar, y luego escriba 1 borrar. Cuando se produce una interrupción externa (EINT4-EINT23), se establecerá el bit correspondiente. ¿Por qué no hay EINT0-EINT3 porque están controlados por los últimos 4 bits del registro SRCPND?

EINTMASK: Esto es simple, se usa para enmascarar las interrupciones. Es decir, cuando el bit es 1, la interrupción no es válida.

Hay 8 registros para interrupciones internas:

SUBSRCPND: Cuando se produce una interrupción, el bit correspondiente se establece en 1, lo que indica que se ha producido una interrupción.

INTSUBMSK: El anterior es un grupo de registros de máscara de interrupción.

SRCPND: Cuando se produce una interrupción, el bit correspondiente se establece en 1, lo que indica que se ha producido una o un tipo de interrupción.

INTMSK: se utiliza para enmascarar la interrupción identificada por el registro SRCPND. Sin embargo, solo las interrupciones de IRQ se pueden enmascarar y las interrupciones de FIQ no se pueden enmascarar.

INTMOD: cuando un bit en INTMOD se establece en 1, su interrupción correspondiente se establece en FIQ y la CPU ingresará en el modo de interrupción rápida.

PRIORITY: se utiliza para establecer la prioridad de las interrupciones de IRQ.

INTPND: Después de que el árbitro de prioridad de interrupción selecciona la interrupción de prioridad más alta, se establece el bit correspondiente en el registro INTPND, y luego la CPU ingresa en el modo de interrupción para procesarlo. Sólo un bit de este registro se establece al mismo tiempo.

INTOFFSET: se utiliza para indicar qué bit en el registro INTPND se establece, es decir, se registra el valor del bit x en el que el bit [x] de INTPND es 1. Se borra automáticamente cuando se borran INTPND y SRCPND.

La descripción del registro anterior se tomó de la publicación del foro, el autor fuente es desconocido.

En segundo lugar, la arquitectura abstracta del software del sistema de interrupción

1) La siguiente figura es el diagrama de relaciones de la estructura de datos relacionada con el sistema de interrupción del kernel de Linux, en la "arquitectura de kernel de Linux profundo", el sistema de interrupción se divide en tres Nivel:

Rutina de servicio de interrupción de alto nivel: el controlador de interrupción controlado por dispositivo, correspondiente al irqacton en la figura.

Control de flujo de interrupción: control de flujo de interrupción (el libro original se traduce como control de corriente de interrupción, no creo que sea posible, aunque esta parte está relacionada con el estado de la fuente de señal, como una interrupción activada por el borde o una interrupción activada por nivel, pero La responsabilidad principal sigue siendo: cuándo llamar al control de la máscara de operación de hardware, ack, etc.).

Encapsulación de hardware de nivel de chip: la capa de dispositivo de hardware, máscara, reconocimiento y otros registros de hardware del sistema de interrupción, correspondientes al irq_chip en la figura.

2) irq_desc: es una matriz global, cada fuente de interrupción corresponde a un descriptor.

3) handle_irq: es la entrada del controlador para cada tipo diferente de fuente de interrupción. La ruta de la llamada es: asm_do_IRQ- > handle_irq- > generic_handle_irq- > generic_handle_irq_desc- > handle_irq. Los diferentes tipos de fuentes de interrupción utilizan diferentes métodos de procesamiento. Cuando se inicializa el subsistema de interrupción, la función irq_set_handler se utiliza para establecer o asignar directamente un valor al puntero de la función.

irq_chip: Reemplaza la versión anterior de hw_interrupt_type. La función establecida en la estructura es la máscara, desenmascaramiento, respuesta ack, mask_ack, etc. correspondiente a la operación del hardware de la fuente de interrupción. Se establece mediante la función irq_set_chip cuando se inicializa el subsistema de interrupción. .

handle_level_irq maneja el tipo de fuente de interrupción activada por la señal de nivel. Esta función llamará a irq_mask del chip, irq_ack para enmascarar y aceptar (indique al controlador de interrupciones, alguien respondió a la interrupción y puede continuar generando la siguiente nueva interrupción. La fuente de la señal de interrupción, de lo contrario, la interrupción se procesará repetidamente;

handle_egde_irq maneja el tipo de fuente de interrupción activada por la señal de borde, solo se puede aceptar, no se requiere máscara, el siguiente nuevo tipo de interrupción puede estar pendiente Registro SRCPEND.

Para las CPU de varios núcleos, si el otro núcleo está procesando la interrupción, puede ser identificado por la función irqd_irq_inprogress que detecta si el irq_desc -> irq_data- > state_use_accessors state es IRQD_IRQ_INPROGRESS.

handle_irq (= handle_level_irq o handle_egde_irq o ...) llamará al controlador de interrupción del dispositivo real action-> handler a través de handle_irq_event- > handle_irq_event_percpu (versión 2.6 para handle_IRQ_event).

4) irqaction: corresponde a la descripción específica de la interrupción del dispositivo, el manejador es la función específica del servicio de interrupción ISR, dev_id se utiliza para distinguir los diferentes dispositivos en la interrupción compartida, el siguiente puntero apunta a la misma fuente de interrupción (interrupción compartida) a continuación La acción del dispositivo, cuando se produce la interrupción, se llamará al dispositivo de interrupción compartido, de modo que el dispositivo de cada dispositivo debe tener la capacidad de determinar si el dispositivo emite la interrupción. Un párrafo sobre interrupciones compartidas "Controladores de dispositivos Linux": "Cuando dos o más controladores comparten líneas de interrupción y las interrupciones de hardware interrumpen el procesador en esta línea, el núcleo llama a cada una registrada para esta interrupción. El controlador, pasando su dev_id a cada uno. Por lo tanto, un controlador compartido debe poder reconocer su propia interrupción y debe salir rápidamente cuando su propio dispositivo no se interrumpe. " Creo que esta declaración es incorrecta, primero La señal de interrupción es solo una señal eléctrica en io. Es imposible pasar la información dev_id a la CPU. El kernel no sabe qué dispositivo está enviando la señal de interrupción. Si hay un dev_id conocido, no hay necesidad de llamar a todos Compartiendo el ISR interrumpido.

Por lo tanto, el isr de cada dispositivo es para determinar si la interrupción es emitida por sí misma. Se requiere soporte de hardware. Por ejemplo, simplemente al verificar el registro del indicador de un dispositivo, no es el dispositivo, e inmediatamente sale de la interrupción.

Además, cuando se trata de interrupciones compartidas, no puede deshabilitar o habilitar irq en un dispositivo. Esto afectará a otros dispositivos que comparten interrupciones.

Tercero, flujo de procesamiento de software interrumpido

Copyright © Conocimiento de Windows All Rights Reserved