El driver que se pretende desarrollar en esta práctica
permite el manejo de un circuito capaz de seleccionar entre 4 canales posibles,
convertir la señal del canal elegido de analógica a digital
y leer dicho valor.
Cada canal dispone de un buffer, de al menos 64 posiciones, donde se
irán almacenando las lecturas hasta que sean leídas por la
aplicación del usuario. La aplicación de usuario podrá
seleccionar qué canal se encuentra activo en cada momento, leyendo
los datos de todos los que lo estén.
La lectura de los datos se realizará por intervalos de tiempo,
determinados dentro del driver. En cada intervalo se leerán todos
los canales activos. La lectura del primer canal se produce al comienzo
del intervalo y la lectura del resto de canales, si los hay, se van encadenando
según vayan finalizando la de los canales inferiores (utilizar la
señal INTR del conversor para determinar dicho instante, ver
la práctica 2).
El driver es un programa que dejará residente la interrupción de usuario 61H. Se crearán una serie de acciones para esta interrupción. La acción a realizar estará indicada por el valor de AH. En algunos casos se añadirán otros registros como AL,BX,CX o DI para controlar el funcionamiento de las acciones a realizar.
Las acciones básicas que debe ejecutar el driver son las siguientes:
Método de comunicación:
El driver se comunica con el programa de aplicación utilizando
la interrupción 61h.
Los parámetros de entrada están en los registros CX,
AL y AH.
AH siempre señala la función que va a ejecutarse.
CX siempre es el número del canal de ADC utilizado
(de 0 a 3).
AL sirve como complemento de AH.
Los resultados se dejarán en los registros AH, AL y CX.
- En AH estará el estado de la ejecución.
Con una excepción, el significado de AH es:
AH = 0 la función ha terminado con éxito.- En AL se encuentran los datos del canal correspondiente.
AH = 1 error en los parámetros de la llamada.
AH = 2 parámetros de llamada fuera del rango permitido (ejemplo – pedir datos de canal 10).
AH = 3 dispositivo ocupado o error en el orden de la secuencia de comandos.
AH = 80h datos todavía no disponibles.
AH = 0FDh – canal no activo.
AH = 0FEh -- dispositivo no disponible.
AH = 0FFh – datos caducados (desbordamiento del buffer interno)
Descripción detallada de la interfaz del driver
Funciones:
De servicio:
AH=0FFh – desinstalar el driver, con terminación del programa (int 21h/ 4c00h).
AH=0FEh – comprobar la presencia del driver.
Retorno: AX=055AAh – el driver esta instalado.
AH=4 – pedir parámetros del driver:
CX = número del canal
Salida:
AH – status
AL – bit0=1 canal ocupado, activo
bit1=1 datos
caducados (se ha sobreescrito el buffer)
CX – intervalo de muestreo, en ms.
De manejo del reloj (intervalo de muestreo):
AH=0 – Cambiar el intervalo de muestro, de petición de
datos.
AL=0 – valor fijo y reservado.
CX -- Periodo de petición de
datos en ms.
De manejo del dispositivo:
AH=2 – Activar el canal
AL=0 – sin borrado del buffer,
AL=1 – limpiando el buffer.
CX -- número de canal 0…3
AH=3 -- Desactivar el canal CX.
AL=0 – sin cambio del buffer,
AL=1 – limpiando el buffer del canal.
CX -- número de canal.
AH=1 – pedir datos del canal CX.
CX -- número canal.
Salida:
AH – estado
AL – datos
(si AH=0).
Funciones opcionales:
AH=10h – pedir el buffer DS:SI de DI datos, CX --
número canal
DS:SI – el buffer destino de datos. Cada dato
ocupa 1 byte.
DI – número de datos pedidos.
CX – número de canal
Retorno:
AH – status
CX – número de datos leídos.
AH=0, AL=1, BL – canal, CX mseg. – cambiar el periodo de pedido
de datos para cada canal por separado.
Estructura del driver
El driver tendrá tres partes comunicandose entre sí:
A. Parte de manejo de la int 61h.Además, el driver tendrá una parte de instalación/desinstalación.
B. Parte de manejo del tiempo.
C. Parte de manejo de la interrupción del dispositivo (LPT1).
A. Int 61h:
Activación: Por llamadas de la aplicación.
Función: Proporcionar interfaz de la aplicación y el
driver.
La parte de int 61h controla las otras dos partes. Lee los datos de los buffers del driver y se los proporciona al usuario (la aplicación). También desinstala el driver, liberando TODOS los recursos ocupados.
B. Manejo del tiempo:
Activación: Periódica, del mismo reloj del sistema.
Función: Inicializa la petición de datos del primer canal
que se va a leer.
La parte del manejo del tiempo controla el reloj del sistema con objeto de pedir datos del ADC con un periodo constante. Esta parte pide solo el primer dato del primer canal. Los datos de los demás canales se piden en orden consecutivo a través de la parte que maneja las interrupciones de LPT. Si el dispositivo no funciona y la parte que maneja el tiempo recibe interrupciones consecutivas del reloj sin recibir ningún dato, se supone que el dispositivo no esta instalado.
El control del tiempo se realizará a través de la interrupción 70H. Esta es una interrupción hardware asociada a un generador de pulsos programable situado en el RTC (Real Time Clock: Reloj de Tiempo Real). Programando ciertos registros del RTC se puede variar el periodo de los pulsos, con lo que se obtienen diferentes temporizaciones. Para más detalle consultar el libro de Antonio García Guerra, "Los microprocesadores xx86 y la arquitectura del PC", editorial Sistemas y Servicios de Comunicación, S.L. 1995, disponible en nuestra biblioteca.
C. Manejo de la interrupción del puerto paralelo:
Activación: Por interrupciones del ADC.
Función: Guardar el dato recibido en el buffer.
Activar la petición del siguiente canal si precisa.
Si el buffer cíclico se desborda, sobreescribir los datos más
antiguos y señalar la situación a la aplicación
con la siguiente petición de datos.
Más datos en notas del
puerto paralelo.
Métodos de comunicación entre las partes del driver:
A -> B Cambiando los parámetros del driver
(memoria). También activando el periodo del reloj.
A -> C Cambiando los parámetros del driver
(los canales que se precisan leer y los punteros de los buffers de datos).
C -> A Buffers cíclicos de datos con los correspondientes
punteros.
B -> C Con los registros del dispositivo B arranca C, también
al inicializar C se pone un flag que sirve para señalar si el dispositivo
está presente.
C -> B No hay transferencia de datos, salvo un flag que señala
que se ha producido la recepción de datos.