¿Qué sucede cuando se vuelve a llamar a una interrupción antes de que se complete la ejecución del ISR?
¿Qué sucede cuando se vuelve a llamar a una interrupción antes de que se complete la ejecución del ISR?
En la mayoría de los casos normales, esto puede no suceder o no hay daño. Cada arquitectura en la que puedo pensar deshabilita las interrupciones de tal manera que la interrupción que se acaba de tomar no puede volver a ocurrir hasta que el software la vuelva a habilitar, generalmente. Algunos procesadores tienen una interrupción no enmascarable, que se puede manejar de manera diferente. Ignora esos por ahora.
En los procesadores simples que tienen una sola interrupción, las interrupciones generalmente se desactivan globalmente cuando se toma una interrupción. Eso permite que el código inmediatamente al comienzo de la interrupción sepa que no se puede interrumpir. Eso es útil ya que a menudo es necesario hacer varias cosas en la rutina de interrupción que debe parecer atómica. Muchos procesadores tienen un medio para volver a habilitar las interrupciones combinadas con el retorno de la rutina de interrupción de tal manera que se garantice que no es necesario escribir la rutina de interrupción para admitir la reentrada. Por ejemplo, el PIC 16 tiene un bit de habilitación de interrupción global (GIE en INTCON). Esto se borra automáticamente cuando se toma la única interrupción, y la instrucción especial RETFIE se puede usar para regresar de la interrupción y configurar GIE al mismo tiempo.
Las cosas se complican un poco más en los procesadores que tienen múltiples prioridades de interrupción. El propósito de las prioridades es específicamente permitir interrupciones de alta prioridad, ya sea en una rutina de interrupción de prioridad más baja o no. Generalmente hay un campo en algún registro que es el nivel de prioridad actual. Cuando se toma una interrupción, el nivel de prioridad existente se guarda junto con otro estado (como la dirección de retorno), luego se golpea la prioridad para que solo puedan ocurrir interrupciones de mayor prioridad. Cualquier rutina de interrupción no puede volver a ingresarse a menos que el código haya hecho deliberadamente el nivel de prioridad, pero todas las rutinas de interrupción, excepto las de prioridad más alta, deben escribirse considerando que pueden interrumpirse. Por lo general, esto no es un problema en las operaciones de preformado que deben parecer atómicas, ya que las otras interrupciones de mayor prioridad generalmente se ocuparán de un hardware y estado diferentes. Sin embargo, significa que no se puede confiar en el tiempo de instrucción secuencial en interrupciones de baja prioridad. Estas son todas las cosas que deben tenerse en cuenta durante el diseño del software a nivel del sistema.
Ahora vuelva a las interrupciones no enmascarables (a menudo llamadas NMI). Estas son, por definición, interrupciones que el software no puede desactivar ("enmascarar"). Esto significa que, en algunas arquitecturas, la rutina de interrupción de NMI podría llamarse repetidamente. Esto es algo que debe tener en cuenta como diseñador del sistema. Por lo general, conecta la entrada del NMI a una señal que sabe que no puede disparar en un intervalo muy corto. Como el controlador de interrupciones NMI es la prioridad más alta en el sistema, también sabe que no se interrumpirá y, por lo tanto, puede saber que siempre se ejecutará dentro de un tiempo máximo.
También ten en cuenta lo que realmente es una interrupción. Usted puede pensar en estar "en" una interrupción en algún código, pero a menudo el código de interrupción no es nada especial para el procesador. Para usar nuevamente el ejemplo de PIC 16, la interrupción no es una condición duradera sino un evento único. Cuando se produce la condición de interrupción y se establece el GIE, el procesador ejecuta efectivamente una llamada a la ubicación 4 y borra el GIE. Eso es. El procesador se realiza con la interrupción. Si ve el código en esa ubicación como un controlador de interrupciones o si cree que está "en" una interrupción es estrictamente su propia abstracción. El código de primer plano ordinario también puede borrar GIE, por lo que ejecutarse con GIE apagado no hace que algo interrumpa el código. Si ejecuta RETFIE algunas instrucciones después de ingresar a la rutina en 4, la ejecución volverá a donde estaba cuando se produjo la interrupción y se vuelve a habilitar GIE. Para usted puede estar "dejando" la rutina de interrupción, pero el procesador no hace nada diferente antes o después de esa instrucción y no tiene ningún estado que le indique que está "en" el código de interrupción.
Esto depende de la arquitectura, pero por lo general los controladores de interrupción individuales no son reingresantes: continuará ejecutando el controlador actual hasta que finalice.
¿Qué pasa con la otra interrupción? Dependiendo de la arquitectura exacta, puede perderse o desencadenarse nuevamente.
Algunas arquitecturas tienen interrupciones de prioridad, donde un controlador de interrupciones puede interrumpir otra. Uno de ellos puede ser una interrupción no enmascarable (NMI).
Olin lo llamó. Lo único que agregaría es la necesidad de tener en cuenta que el contexto del procesador se almacena en la pila antes de ingresar el ISR. Entonces:
Demasiadas interrupciones no manejadas acabarán con tu pila, y
Colocar el contexto en la pila de esta manera inherentemente obliga a manejar las interrupciones de alta prioridad antes de las interrupciones de baja prioridad, y esto es lo que desea. Si está escribiendo un ISR, desea desenmascarar las interrupciones tan pronto como pueda para que las interrupciones de mayor prioridad puedan ser atendidas al interrumpir el ISR de menor prioridad ...
Lea otras preguntas en las etiquetas interrupts