Diferencia entre revisiones de «Interrupción»
Sin resumen de edición |
|||
Línea 154: | Línea 154: | ||
* '''''Deshabilitar de forma selectiva distintos niveles de prioridad de interrupción para lo cual se emplean registros especiales denominados máscaras en el que cada uno de sus bits identifican a un nivel distinto y modificando su contenido podemos establecer que niveles están activos en ese momento. Se puede cambiar por el programador.''''' |
* '''''Deshabilitar de forma selectiva distintos niveles de prioridad de interrupción para lo cual se emplean registros especiales denominados máscaras en el que cada uno de sus bits identifican a un nivel distinto y modificando su contenido podemos establecer que niveles están activos en ese momento. Se puede cambiar por el programador.''''' |
||
=== Enlaces externos === |
|||
* [http://www.programarpicenc.com Microcontroladores PIC] '''Programación en lenguaje C de las interrupciones de los PICs 16F88 y 16F628A con el compilador mikroC.''' |
|||
[[Categoría:Interrupciones| ]] |
[[Categoría:Interrupciones| ]] |
Revisión del 02:35 18 jun 2010
Interrupción (también conocida como interrupción hardware o petición de interrupción) es una señal recibida por el procesador de un ordenador, indicando que debe "interrumpir" el curso de ejecución actual y pasar a ejecutar código específico para tratar esta situación.
Una interrupción supone la ejecución temporaria de un programa, para pasar a ejecutar una "subrutina de servicio de interrupción", que pertenece al BIOS (Basic Input Output System).
Las interrupciones surgen de las necesidades que tienen los dispositivos periféricos de enviar información al procesador principal de un sistema de computación. La primera técnica que se empleó fue que el propio procesador se encargara de sondear (polling) el dispositivo cada cierto tiempo para averiguar si tenía pendiente alguna comunicación para él. Este método presentaba el inconveniente de ser muy ineficiente, ya que el procesador constantemente consumía tiempo en realizar todas las instrucciones de sondeo.
El mecanismo de interrupciones fue la solución que permitió al procesador desentenderse de esta problemática, y delegar en el dispositivo la responsabilidad de comunicarse con el procesador cuando lo necesitaba. El procesador, en este caso, no sondea a ningún dispositivo, sino que queda a la espera de que estos le avisen (le "interrumpan") cuando tengan algo que comunicarle (ya sea un evento, una transferencia de información, una condición de error, etc.).
Funcionamiento del mecanismo de interrupciones
Cada dispositivo que desea comunicarse con el procesador por interrupciones debe tener asignada una línea única capaz de avisar a éste de que le requiere para una operación. Esta línea es la llamada IRQ ("Interrupt ReQuest", petición de interrupción).
Las IRQ son líneas que llegan al controlador de interrupciones, un componente hardware dedicado a la gestión de las interrupciones, y que puede estar integrado en el procesador principal o ser un circuito separado conectado al procesador principal. El controlador de interrupciones debe ser capaz de habilitar o inhibir líneas de interrupción (operación llamada comúnmente enmascarar por la utilización de una máscara), y establecer prioridades entre las distintas interrupciones habilitadas. Cuando varias líneas de petición de interrupción se activan a la vez, el controlador de interrupciones utilizará estas prioridades para escoger la interrupción sobre la que informará al procesador principal. Sin embargo hay interrupciones que no se pueden enmascarar o deshabilitar, las conocidas como interrupciones no enmascarables o NMI.
Un procesador principal (sin controlador de interrupciones integrado) suele tener una única línea de interrupción llamada habitualmente INT. Esta línea es activada por el controlador de interrupciones cuando tiene una interrupción que servir. Al activarse esta línea, el procesador consulta los registros del controlador de interrupciones para averiguar qué IRQ es la que ha de atender. A partir del número de IRQ busca en el vector de interrupciones qué rutina debe llamar para atender una petición del dispositivo asociado a dicha IRQ.
Las rutinas de interrupción generalmente toman un pequeño tiempo de ejecución y la mayoría no pueden ser interrumpidas cuando se están atendiendo, porque al entrar en ellas se almacena el estado de los registros en una pila y si se interrumpen muchas veces, la pila se puede desbordar.
Pasos para el procesamiento de una IRQ:
1) Terminar la ejecución de la instrucción máquina en curso.
2) Salva el valor de contador de programa, IP, en la pila, de manera que en la CPU, al terminar el proceso, pueda seguir ejecutando el programa a partir de la última instrucción.
3) La CPU salta a la dirección donde está almacenada la rutina de servicio de interrupción (ISR, Interrupt Service Routine) y ejecuta esa rutina que tiene como objetivo atender al dispositivo que generó la interrupción.
4) Una vez que la rutina de la interrupción termina, el procesador restaura el estado que había guardado en la pila en el paso 2 y retorna al programa que se estaba usando anteriormente.
Mecanismo de interrupciones en un PC
Un ordenador PC típico dispone en su placa base de un controlador de interrupciones 8259 de Intel o de un circuito integrado análogo. Este dispositivo electrónico dispone de hasta 16 líneas IRQ, numeradas desde el 00 hasta el 15. En las nuevas placas base este circuito está integrado junto con el resto del chipset y permite hasta 24 interrupciones.
Tipos de interrupciones
En este subapartado vamos a hacer una clasificación de las distintas clases de interrupciones que nos podemos encontrar atendiendo a la fuente que las produce. Por un lado distinguiremos si se producen por causas internas o externas al procesador y remarcaremos que este hecho está íntimamente ligado con que las interrupciones sean síncronas o asíncronas:
- Interrupciones hardware: Estas son asíncronas a la ejecución del procesador, es decir, se pueden producir en cualquier momento independientemente de lo que esté haciendo la CPU en ese momento. Las causas que lo producen son externas al procesador y a menudo suelen estar ligadas con distintos dispositivos de E/S.
- Interrupciones software o excepciones : Son aquellas que se producen de forma síncrona a la ejecución del procesador y por tanto podrían predecirse si se analiza con detenimiento la traza del programa que en ese momento estaba siendo ejecutado en la CPU. Normalmente las causas de estas interrupciones suelen ser realizaciones de operaciones no permitidas tales como la división por 0, el desbordamiento, el acceso a una posición de memoria no permitida, etc.
- Trampas: A menudo se tiende a confundir las interrupciones software y las trampas, ya que su naturaleza es bastante similar. Sin embargo las excepciones se producen al realizar una operación no permitida por lo que de algún modo podemos decir que no es controlada directamente por el programador si no que, por un fallo al programar, se producen. No obstante las trampas si que son provocadas por el programador, para provocar una trampa existen distintas instrucciones en el repertorio máquina que permiten al programador producir una interrupción al ejecutar dicha instrucción. Suelen tener nemotécnicos tales como INT. Suelen ser de vital importancia ya que a partir de las trampas se pueden pedir al SO que realice determinadas funciones, para ello, en DOS se realiza la instrucción INT 0x21 y en Unix se utiliza INT 0x80.
Interrupciones hardware
Son interrupciones que se producen como resultado de, normalmente, una operación de E/S. No son producidas por ninguna instrucción si no que son señales que producen los dispositivos para indicarle al procesador que necesitan ser 'atendidos'. Las interrupciones hardware son interesantes en cuanto a que permiten mejorar la productividad del procesador ya que este último puede ordenar una operación de E/S y en lugar de tener que esperar a que el dispositivo acabe realizando una espera activa, es decir, sin hacer ningún trabajo útil, se puede dedicar a atender a otro proceso o aplicación y cuando el dispositivo este de nuevo disponible será el encargado de notificarle al procesador mediante la línea de interrupción ya que está preparado para continuar/terminar la operación de E/S.
Interrupciones software o excepciones
Es un tipo de interrupción sincrónica típicamente causada por una condición de error, por ej. una división por 0 o un acceso inválido a memoria en un proceso de usuario. Normalmente genera un cambio de contexto a modo supervisor para que el sistema operativo atienda el error. De manera que podemos ver como las excepciones son un mecanismo de protección que permite garantizar la integridad de los datos tanto en el espacio de usuario como en el espacio kernel. El SO cuando detecta una excepción intenta solucionarla pero en caso de no poder simplemente notificará la condición de error a la aplicación y abortará la misma.
Trampas
En este apartado se consideran las llamadas al sistema operativo mediante una instrucción, normalmente de Entrada/Salida.
Una interrupción por software, se prevé en qué momento de la ejecución de un programa sucederá. En general actúa de la siguiente manera:
. Un programa que se venía ejecutando luego de su instrucción I5, llama al Sistema Operativo, por ejemplo para leer un archivo de disco.
. A tal efecto, luego de I5 existe en el programa, la instrucción de código de máquina CD21, simbolizada INT 21 en Assembler, que realiza el requerimiento del paso 1. Puesto que no puede seguir le ejecución de la instrucción I6 y siguientes del programa hasta que no se haya leído el disco y esté en memoria principal dicho archivo, virtualmente el programa se ha interrumpido, siendo, además, que luego de INT 21, las instrucciones que se ejecutarán no serán del programa, sino del Sistema Operativo.
. La ejecución de INT 21 permite hallar la subrutina del Sistema Operativo.
. Se ejecuta la subrutina del Sistema Operativo que prepara la lectura del disco.
. Luego de ejecutarse la subrutina del Sistema Operativo, y una vez que se haya leído el disco y verificado que la lectura es correcta, el Sistema Operativo ordenará reanudar la ejecución del programa autointerrumpido en espera.
. La ejecución del programa se reanuda.
Determinación de la dirección de la rutina de servicio de interrupción
En este apartado vamos a considerar las distintas alternativas que se nos presentan a la hora de decidir cómo determinar la dirección de comienzo de la rutina de servicio de interrupción que debe ejecutarse al recibir una interrupción determinada. En principio podemos definir dos alternativas:
- Direcciones fijas: Se hallan cableadas en el procesador y por tanto nunca pueden ser cambiadas. Esto implica que las RSI siempre estarán en una determinada posición de la memoria.
- Direcciones variables (por interrupciones vectorizadas): En este apartado hay que matizar una cosa. Entre paréntesis podemos observar que pone "direcciones por interrupciones vectorizadas" pues bien, en este punto hay una confusión muy común y es nosotros a menudo concebimos las direcciones por interrupciones vectorizadas como un caso concreto de direcciones variables que es aquella en la que existe una tabla con los vectores de interrupción. Simplemente resaltar que en algunos textos se utiliza esta denominación tanto para las direcciones variables en general como para el caso específico que comentamos con anterioridad. En este grupo incluimos aquellas que presentan una dirección variable y que, por tanto, no se halla cableada en el procesador. De esta manera el dispositivo debe darnos información acerca de la localización de la dirección de comienzo de la RSI asociada a dicho periférico. En el siguiente subapartado hablaremos de las distintas metodologías de diseño de las interrupciones con direcciones variables.
Direcciones variables
Vamos a explicar las alternativas que se implementan de manera habitual en la actualidad:
- Direccionamiento absoluto: En este caso es el dispositivo o la interfaz del dispositivo la encargada de conocer la dirección de la RSI y de enviarla al procesador para que este pueda localizar dicha subrutina y ejecutarla.
- Direccionamiento relativo: El dispositivo solo suministra parte de la dirección de comienzo y es el procesador el encargado de completarla (añadiendo bits o sumando una determinada cantidad, que siempre será fija). Esta alternativa tiene una ventaja sobre la anterior y es que permite especificar la dirección de comienzo con menos bits y por tanto simplifica el diseño. Ahora bien tiene una desventaja principal y es que limita el número de dispositivos que podemos conectar y además ciertos bits de la dirección quedan fijados de forma permanente por la CPU lo que reduce la capacidad de reubicabilidad de la RSI. Una alternativa que utilizan ciertos procesadores como el 8080 o 8085 es que en vez de enviar solamente la dirección de comienzo de la RSI se envía también el código de la operación de salto (call por ejemplo).
- Direccionamiento indirecto: También conocida como direccionamiento por interrupciones vectorizadas. Se mantiene una tabla de vectores de interrupción (direcciones de comienzo de las distintas RSI) y a cada interrupción se le asocia un número que será el índice por el cual se accederá a la tabla y se recuperará la información de la dirección de comienzo. Necesita señales de conformidad o 'handshaking' para sincronizar al procesador con la interfaz, ya que esta última tiene que indicarle al procesador cuando va a enviarle el índice que necesita para buscar el vector de interrupción (INT) y el procesador deberá enviar otra señal para indicar que se ha reconocido la interrupción (INTA#).
Por último introducimos otro apartado en el que indicamos las distintas formas de identificar la fuente de una determinada interrupción.
Determinación de la fuente que genera la interrupción
La primera alternativa que se consideró fue asignar una línea (un bit) para cada interrupción pero esto suponía un gran costo en cuanto a la relación nº de dispositivos y nº de bits usados y a menudo fijaba el límite de dispositivos que se podían conectar. Por tanto se pensó con posterioridad que en cada patilla de interrupción deberían poder conectarse más de un dispositivo pero entonces tendríamos que imponer una metodología que nos permitiese identificar de forma unívoca de qué dispositivo se trata. Para ello se han dado varias directrices que a continuación vamos a analizar de manera más detallada:
- "Polling": Se trata de que la CPU comprueba de manera sistemática todos los dispositivos de manera que "busca" cuál de ellos fue el que solicitó la interrupción. Esto tiene una ventaja y es que es barato a nivel de coste hardware ya que el "polling" se implementa en software, no obstante tiene otras desventajas que no podemos olvidar y es que suele ser lento porque tiene que comprobar en serie todos los dispositivos y establece una prioridad en los dispositivos (el orden de sondeo) y por tanto puede provocar inanición.
- Interrupciones vectorizadas: Este concepto fue ya tratado en el apartado anterior y como ventajas podemos destacar que suele ser rápido pero implica un alto coste en el hardware.
- Hardware paralelo: Se utiliza un registro de interrupción cuyos bits se controlan de forma independiente por las señales de petición de interrupción de cada periférico. Según la posición de cada bit en el registro, se establece la prioridad.
Está claro que necesitamos un mecanismo para priorizar las interrupciones y tratar primero las más "urgentes". En el siguiente apartado identificaremos los distintos métodos para establecer sistemas de prioridad y explicaremos de manera más extensa cada uno de ellos.
Sistemas de prioridad
Existen varias alternativas que consideramos a continuación:
- Interrupciones simultáneas: No tienen porque ocurrir de manera simultánea si no que se refiere a que en un momento dado puede haber varias interrupciones activas.
- Interrupciones anidadas: Mientras se está procesando una determinada rutina de servicio de interrupción sucede otra señal de interrupción.
- Inhibición de interrupciones: Se deshabilitan las interrupciones mientras se está tratando una.
Interrupciones simultáneas
En este método tenemos dos alternativas, una de ellas es que exista algún hardware que tenga como entradas las señales de interrupción y de como salida la interrupción más prioritaria que está activa en ese momento. Otra alternativa es tener un método de identificación de prioridades distribuida y no generalizada como en el caso anterior, en este caso tenemos que destacar dos técnicas distintas que se pueden implementar en la práctica:
- "Polling": Como ya vimos es la CPU la que chequea los dispositivos y el orden de sondeo determina la prioridad.
- "Daisy-chain": "Daisy-chain" significa "cadena de flores" y viene a significar que podemos conectar los distintos dispositivos en cadena, en orden decreciente de prioridad y por tanto la señal de reconocimiento de interrupción (INTA#) solo será pasada al siguiente dispositivo en caso de que el anterior (más prioritario) no halla solicitado los servicios del procesador. Sin embargo hay algo importante que explicar y es que las señales de interrupción que van al procesador están conectadas todas a un mismo cable, por tanto, deberemos utilizar alguna técnica especial para que no se produzca un cortocircuito. Para evitar precisamente que la pista se cortocircuite se utiliza la técnica del "open-collector" o "colector abierto" y consiste en conectar el colector de un transistor a la pista común (un transistor por cada dispositivo) y por tanto estarán tantos colectores conectados como dispositivos tengamos (se entiende que son dispositivos que mandan petición de interrupción al procesador).
- Híbrida: Mezcla las dos técnicas explicadas anteriormente.
Interrupciones anidadas
Existen dos métodos para tratar las interrupciones anidadas. El primero se basa en inhabilitar las interrupciones mientras se está ejecutando una determinada RSI. Esto puede realizarlo el hardware de manera automática en algunos procesadores pero en otros será el usuario el encargado de deshabilitarlas en caso de que desee que ninguna otra interrupción pueda interrumpir el transcurso normal de la rutina de servicio de interrupción. No es aconsejable deshabilitar las interrupciones durante mucho tiempo ya que esto degrada el rendimiento total del sistema. La otra alternativa es permitir que solo las interrupciones más prioritarias puedan suspender la ejecución de la RSI actual. Para esto tendremos que definir qué líneas son más prioritarias que otras. Otra consideración de esta segunda alternativa es que al anidar distintas llamadas a rutinas tendremos que contar con una pila suficientemente grande para que esta no se desborde.
Inhibición de interrupciones
En este apartado queremos destacar las distintas alternativas de inhibición de interrupciones. Como ya hemos visto estas se pueden hacer de manera automática por el hardware en algunos casos mientras que en otros será el usuario el encargado de realizarlo por software y esto depende de la arquitectura del procesador que consideremos. Las distintas opciones son:
- Deshabilitar todas las interrupciones para esto basta con inhibir el bit del registro de flags dedicado a las interrupciones
- Como hemos dicho se pueden deshabilitar al principio de la RSI y activarlas de nuevo al finalizar la misma, puede ser de manera automática o por el usuario
- Desactivar solo las interrupciones que tengan menor prioridad que la asociada a la RSI que se está ejecutando en ese momento
- Deshabilitar de forma selectiva distintos niveles de prioridad de interrupción para lo cual se emplean registros especiales denominados máscaras en el que cada uno de sus bits identifican a un nivel distinto y modificando su contenido podemos establecer que niveles están activos en ese momento. Se puede cambiar por el programador.