¿Cómo manejan las computadoras los dispositivos de E / S?

En el nivel más bajo, el ‘dispositivo’ debe poder conducir un byte o una palabra más grande en el bus de datos de la CPU en el instante en que un ciclo de máquina apropiado lo solicite. Esto se llamaría memoria o IO read. El dispositivo puede usar otra señal para interactuar con la CPU: una entrada de interrupción. Esto generalmente pasa por una lógica externa que da un poco de orden y prioridad a los dispositivos que pueden competir por la atención. La entrada de interrupción le indica a la CPU que el dispositivo tiene algunos datos o que requiere algún tipo de atención. Quizás el dispositivo ha gastado su caché de datos para enviar y quiere que se envíen más, como en el UART que conforma un puerto serie. En tal caso, la CPU podría hacer un ciclo de escritura de memoria o IO, que transferiría un byte o una palabra más grande a un registro en el dispositivo. Los valores de los bytes transferidos de esta manera dependen del tipo de dispositivo y del tipo de operación que están realizando la CPU y el dispositivo. Lo más probable es que la operación del dispositivo comprenda una serie más grande y continua de tales transferencias. El código que realiza las transferencias es a menudo parte del sistema operativo, si hay uno, o al menos una extensión del sistema operativo llamada controlador.

Su visión de un ‘dispositivo’ probablemente esté en un nivel más macroscópico. Un mouse o un teclado, tal vez. Dichos dispositivos realizan algún tipo de transformación de las partes del “mundo real” del dispositivo, como las acciones del teclado y el movimiento del mouse a una señal digital que la CPU puede leer, escribir o reaccionar ante una interrupción. Muy a menudo, hay un nivel intermedio e intermedio de hardware que participa en la transformación. Por ejemplo, un teclado detecta continuamente cuando los interruptores de llave se abren y cierran, y luego transmite esta información a través del cable u otra interfaz a un puerto USB en una computadora. El puerto USB tiene la conexión real con los buses de la CPU y realiza la comunicación con la CPU en nombre del teclado, transmitiendo datos hacia y desde el dispositivo. Internamente, el dispositivo funciona de manera algo autónoma, y ​​solo tiene que obedecer los protocolos para enviar y recibir datos en la interfaz USB.

Naturalmente, hay muchos más detalles y los detalles son tan variados como la cantidad de diferentes tipos de dispositivos. Para simplificar las cosas, hay una serie de protocolos que están disponibles para que los fabricantes los usen para conectar sus tipos de dispositivos a las CPU. Esto reduce la cantidad de tipos de protocolos que un sistema debe admitir, ya que algunos de los hardware y software de soporte pueden volverse de naturaleza genérica y compartirse entre todos los otros tipos de dispositivos que usan el mismo tipo de interfaz. Estos protocolos tienen nombres como I2C (I-squared-C), SPI y otros. PCI y varias interfaces de unidad de disco son una especie de estándar de interfaz de mayor escala. Aún así, todos terminan como métodos para permitir la transferencia de datos en los buses de la CPU de una manera coordinada, con un software que comprende lo que hay que escribir o leer, y cómo y cuándo hacerlo.

El controlador del dispositivo tiene una interfaz representada en forma de registros. Aparecen como variables en la memoria, y si cambia el valor de los registros, cambia el comportamiento del dispositivo (la CPU enruta las señales eléctricas adecuadamente)

Eso es lo que ve el programador del controlador.

Hay tres técnicas para manejar IO. El primero es el sondeo.

En el código normal, verifica los registros de los cambios que desea de vez en cuando.

El segundo es interrupciones.

Cuando el dispositivo tiene algo que informar a la CPU, envía una señal a la CPU físicamente. Cuando la CPU nota esa señal, detiene la ejecución actual y pasa a una rutina de interrupción y la ejecuta. En este IR, la CPU maneja el cambio de estado del hardware. Una vez terminado, vuelve al código original.

El tercero es el acceso directo a la memoria.

Con esto, la CPU programa un controlador dma para dar acceso automático a un búfer de memoria. Esto se usa cuando necesita transferir una gran cantidad de datos hacia o desde un dispositivo.

Usando una combinación de estos tres enfoques, un desarrollador de controladores puede programar cualquier dispositivo.

Por ejemplo, tomemos la reproducción de sonido:

La tarjeta de sonido está asignada a la memoria que ve la CPU.

La CPU configura la tarjeta de sonido utilizando los Registros de control. Le da un puntero a un búfer de memoria, le dice el tamaño del búfer, el formato de audio (frecuencia, tamaño de muestra). Luego escribe un poco que dice iniciar la reproducción.

La tarjeta de sonido ahora tiene un acceso DMA que copia automáticamente el contenido del búfer al motor de reproducción.

Cada vez que la tarjeta de sonido llega a la mitad del búfer, dispara una solicitud de interrupción que le dice a la computadora, estoy en la segunda mitad del búfer, llena la primera mitad con tu próximo sonido. Una vez que la CPU copia los datos, abandona la IRQ y continúa con su trabajo. Una vez que la tarjeta de sonido llega al final del búfer de sonido, comienza al principio y dispara un nuevo IRQ que dice que estoy en la primera mitad, llene la segunda mitad.

Esto continúa mientras se reproduce el sonido. Cuando la CPU quiere detener la reproducción, cambia el bit que dice ejecutar a 0. Y la tarjeta de sonido detiene la reproducción y no dispara más IRQ para llenar buffers.