Durante más de medio año y sobre todo desde LatinoAmerica estoy recibiendo cantidad de solicitudes de ayuda para manejar el puerto paralelo del Ordenador y poder así activar relés que ponen en marcha cualquier tipo de artilugio eléctrico o electrónico. He sido reticente a escribir nada al respecto, pues consideraba que existen mil y una soluciones actuales tanto en HardWare como en SoftWare que permiten controlar motores, luces o cualquier tipo de mecatronica pero de forma profesional con tecnología y medios actuales. Pensar el soluciones del tiempo de MS-DOS, me parece como menos equivocado siempre y cuando la finalidad no sea como ejercicio docente o como una forma de aprender y experimentar. Una vez entendida la declaración me complace compartir la siguiente explicación para contextualizar que encender un ‘led’ utilizando el puerto paralelo no es ningún logro, aunque sin despreciar la experiencia pueda ser divertido, teniendo en cuenta que la interacción con el sistema operativo es la que marcan los cánones a pesar de que de vez en cuando podamos hacerle un giño. A demás no debemos olvidar que a día de hoy no todos los ordenadores incorporan la antigua especificación para el puerto paralelo.
Una de las características de la arquitectura x86 es el direccionamiento de dispositivos periféricos a través de un bus de entradas/salidas. Si nos remontamos en el tiempo, para la mayoría de los que utilizaron “Macro Assembler” o “C” en los tiempos de sistemas operativos como CP/M o MS/DOS, recordaran como nos hacíamos con el control de los dispositivos desviando los vectores de interrupción a nuestras rutinas y por supuesto comunicándonos directamente con los dispositivos a través de sus puertos mapeados en tal bus de E/S. Estamos hablando de dispositivos como el Teclado, Puerto Serie, Paralelo, Memoria, Timer, etc … ciertamente todos los dispositivos que componían la estructura básica de nuestro sistema. Por supuesto estábamos más que familiarizados con la utilización de las instrucción ‘in’ y ‘out’, ellas nos permitían enviar o recibir un byte utilizando un puerto (Mapa E/S) que conectaba directamente y permitía el intercambio de información con un periférico en concreto.
En esos tiempos los sistemas operativos estaban orientados a la ejecución mono-Usuario, Mono tarea, sin entorno grafico y con la única posibilidad de interaccionar a través de un ‘prompt’ por parte del usuario.
Con la llegada y evolución de los sistemas gráficos, multitarea, multiusuario para plataformas Intel, tuvieron que adaptarse a una arquitectura adecuada para tal cometido. Dicha arquitectura dicta las normas en las deben efectuarse las llamadas a procedimientos, manejar las interrupciones y como no las excepciones, por citar algunas.
Dicho esquema, familiar para cualquier estudiante de informática como mecanismo de protección reconoce en forma de aros, en concreto cuatro aros concéntricos que representan cuatro niveles de privilegio del 0 al 3, la principal razón para usar ese esquema se vasa en mejorar la fiabilidad del propio sistema operativo.
El primer aro en el centro es utilizado por módulos de código que contienen partes vitales y criticas del sistema, por lo tanto disponen del nivel de privilegios más alto. El resto de módulos con menor nivel de privilegio solo pueden acceder al nivel superior a través de un estricto controlador llamado “puerta” o “gate”, intentar acceder a un segmento privilegiado de un nivel superior directamente o si utilizar la protección “gate” sin los suficientes permisos causara una excepción de protección general.
En nuestro entorno Intel/Windows, tuvimos la posibilidad de utilizar las instrucciones de ‘in’ ‘out’ tanto desde lenguajes como Asm, C y Basic y los sistemas operativos DOS, 95 y 98. Sin embargo con la tecnología NT, el uso de estas instrucciones por programas con privilegios de usuarios generaba la consecuente excepción en el sistema.
Cabe dejar claro que es del todo irreconciliable la mentalidad de acceder al puerto paralelo enviando un byte a la dirección de su puerto en un entorno como el nuestro. Difícilmente podemos justificar una programación orientada a controlar los dispositivos… ese tiempo ya paso y precisamente una de las tareas más eficientes que nuestro sistema operativo es capaz de llevar a cabo es ese control. No debemos perder la perspectiva que si necesitamos programar partes especificas que justifican ese nivel de privilegios, debemos utilizar las herramientas que nos facilita el fabricante del SO, tales como SDK, DDK..etc. Es evidente que necesitamos una serie de conocimientos avanzados, para encajar nuestra pieza en todo este puzle, pero sin duda solo siguiendo esos patrones seremos capaces de construir soluciones profesionales aptas para superar las pruebas a nivel de los mercados a los que van dirigidos.
Advertencia y Aclaración.
Está claro que os facilito este articulo por vuestra insistencia, aunque debo advertiros que el mal uso del soldador con el conector de 25 al intentar realizar experimentos o utilizar inadecuadamente el puerto paralelo conectando aparatos o dispositivos inadecuados o incompatibles, puede causar averías en el equipo o en el peor de los casos daños personales, debo rechazar categóricamente cualquier responsabilidad por el uso de la información contenida, cualquier aplicación o uso derivada de la información de este artículo y su alcance es estrictamente responsabilidad del lector aunque estaré encantado de recibir vuestros comentarios.
En el caso que nos ocupa, para poder enviar o recibir un byte de puerto, necesitaremos estar dentro del anillo de ‘driver’ que nos proporcione los derechos de privilegio suficiente para realizar dicha operación. La mayoría de nosotros carecemos de los conocimientos suficientes para desarrollar un adaptador que nos permita fabricarnos nuestro propio ‘driver’ aunque podemos encontrar multitud de ejemplos en la red, existe una conocida librería llamada ‘inpout32.dll’ que viene a implementar ese ‘kernel model driver’. Podemos descargarnos esa librería desde un montón de ubicaciones, solo es necesario buscar ‘inpout32.dll DownLoad’ en la red y una vez dispongamos de ella copiarla en “\windows\system32”.
Luego solo nos restara crear un nuevo proyecto en Visual Studio e incluir nuestras referencias como sigue:
‘Declaraciones para leer/ecribir un puerto E/S utilizando inpout32.dll
Public Declare Function leer Lib «inpout32.dll» Alias «Inp32» _
(ByVal puerto As Short) As Short
Public Declare Sub escribir Lib «inpout32.dll» Alias «Out32» _
(ByVal puerto As Short, ByVal Valor As Short)
Finalmente en el evento clic del botón por ejemplo:
‘ Para la prueba de los led’s
‘ Conectar los led’s a traves de una resistencia.
‘ La resistencia debe soldarse a la masa en las
‘ patillas del conector de (25pins) correspondientes
‘ a los pines 19,20,21,22,23,24,25 (son todos masa).
‘ El otro extremo de la resistencia lo soldaremos al
‘ negativo del led, y el positivo del mismo a las
‘ patillas 2,3,4,5,6,7,8,9 que corresponden a la salida
‘ del registro de datos del puerto serie.
Private Sub Button1_Click(…) Handles Button1.Click
Static OnOff As Boolean = False
‘el puerto &h378 corresponde a la direccion
‘del registro ‘data’ del LPT1:
If OnOff Then
‘Apagar todos los led’s
escribir(&H378, &H0)
Else
‘Encender todos los led’s
escribir(&H378, &HFF)
End If
OnOff = Not OnOff
End Sub
Luego para leer el estado de las líneas del registro de datos:
Private Sub Button2_Click(…) Handles Button2.Click
MessageBox.Show(leer(&H378))
End Sub
Saludos,
Pep Lluis,