GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo controlar puertos periféricos:Acceso y escritura en puerto paralelo con C en Linux. Parte I

Uno de los casos de uso más llamativos y emergentes para controlar puertos periféricos en un PC es la domótica, esta tecnología ofrece un campo infinito de posibilidades en nuestros hogares. La domótica es una disciplina técnica con un lado social. Nuestro enfoque es, utilizando algunas frases clave, mejorar la calidad de vida, expandir la comunicación y automatizar procesos. Todo esto parece bastante simple, pero la complejidad inherente a este nuevo mundo de la domótica es apasionante, veamos por qué.

La domótica es una actividad compleja por varias razones. En primer lugar, el funcionamiento en dispositivos domésticos (sensores, electrodomésticos inteligentes, actuadores...) te da una idea de los complicados fenómenos físicos, como la mecánica cuántica o el efecto fotoeléctrico. Además, uno de estos dispositivos puede realizar varias tareas y no necesariamente solo una simple. En segundo lugar, hablar de Domótica es hablar de sistemas formados por muchos componentes diferentes que no siempre interactúan con facilidad (imagina un sistema de seguridad para el hogar que incluya cámaras de vídeo, detectores de presencia, equipos de comunicación, alarmas con sistema de aviso a distancia, etc. . ...). Finalmente, y lo más importante, es complejo porque enfrenta la automatización de sistemas técnicos con sistemas sociales.

Definición de términos

Puerto paralelo:

Un puerto paralelo es una interfaz entre una computadora y un dispositivo periférico, cuya principal característica es que los bits de datos viajan juntos, enviando un paquete byte a la vez. Se implementa un cable o ruta física para cada bit de datos formando un bus de 8 líneas. A través del puerto paralelo también podemos controlar periféricos como luces, motores y otros dispositivos.

Interfaces web:

Una interfaz web permite a los usuarios controlar e interactuar con sus dispositivos a través de un navegador web. Esto se puede usar para un control remoto, administración de bibliotecas, comentarios visuales y muchas otras cosas.

Domótica:

Es la automatización de todos los sistemas capaces de automatizar una vivienda, proporcionando servicios de gestión energética, seguridad, bienestar y comunicación, pudiendo integrarse en redes de comunicación interior y exterior cableadas o inalámbricas.

Cómo trabajar con puertos paralelos en C

Para nuestro propósito principal, la domótica básica, usaremos el puerto paralelo para demostrar cómo podemos escribir (o leer) algunos bytes para controlar dispositivos simples. El puerto paralelo de un PC Tipo ECP tiene un conector de salida tipo DB25 hembra cuyo diagrama y señales se pueden ver en la siguiente figura:

Figura 1:Diagrama de puerto paralelo. Pinout del conector hembra. Cortesía de Wikipedia

Salida de puerto paralelo

El puerto paralelo de un PC, según el estándar Centronics, está compuesto por un bus de comunicación bidireccional de 8 bits de datos, más un conjunto de líneas para el protocolo. Las líneas de comunicación tienen un retenedor que retiene el último valor que se les escribió hasta que se escriben nuevos datos, las características eléctricas son:

  •      Voltaje de alto nivel:3,3 a 5 V.
  •      Voltaje de nivel bajo:0 V.
  •      Corriente de salida máxima:2,6 mA.
  •      Corriente de entrada máxima:24 mA.

El voltaje y la corriente pueden alimentar un conjunto de dispositivos de control como LED, relés e interruptores de estado sólido. Estos buffers son necesarios para apagar o encender elementos con un mayor consumo de energía.

Direccionamiento

El direccionamiento de un puerto paralelo estándar es importante debido a la variedad de recursos que utiliza de la computadora y para fines de identificación. El puerto paralelo estándar usa tres direcciones contiguas, generalmente en uno de estos rangos:


La primera dirección en el rango es la dirección base del puerto, también llamada Registro de datos o simplemente la dirección del puerto. La segunda dirección es el registro de estado del puerto y la tercera es el registro de control.

Los EPP y ECP reservan direcciones adicionales para cada puerto. Un EPP agrega cinco registros en la dirección base + 3 a través de la dirección base + 7, y un ECP agrega tres registros en la dirección base + 400h a través de la dirección base + 402h. Para una dirección base de 378h, los registros EPP están en 37Bh a 37Fh, y los registros ECP están en 778h a 77Fh.

Canales DMA

Los ECP pueden utilizar el acceso directo a la memoria (DMA) para las transferencias de datos al puerto paralelo. Durante las transferencias DMA, la CPU tiene libertad para hacer otras cosas, por lo que las transferencias DMA pueden dar como resultado un rendimiento general más rápido. Para usar DMA, el puerto debe tener un canal DMA asignado, en el rango de 0 a 3.

Acceder a puertos físicos en Linux

Debido a que el hardware del puerto en una PC está controlado directamente por el kernel de Linux, debemos acceder a ciertos encabezados relacionados con el bus del puerto paralelo. El compilador GCC puede acceder a estas cabeceras, siempre teniendo en cuenta que el usuario debe tener privilegios de root para evitar errores de acceso. Estos encabezados son:

  • stdio.h:El "encabezado de entrada-salida estándar" (E/S de encabezado estándar) es el archivo de encabezado que contiene las definiciones de macros, constantes, declaraciones de funciones en la biblioteca estándar del lenguaje de programación C para realizar operaciones, estándar entrada y salida, así como la definición de los tipos necesarios para tales operaciones. Por razones de compatibilidad, el lenguaje de programación C ++ (derivado de C) también tiene su propia implementación de estas funciones, que se declaran con el encabezado del archivo cstdio. La función que tengo que usar es fprintf que permite imprimir en una ventana de terminal si hay algún error.
  • stdlib.h: es el archivo de encabezado de la biblioteca estándar del lenguaje de programación de uso general C. Contiene los prototipos de funciones de C para la gestión dinámica de la memoria, el control de procesos y otros. Es compatible con C ++ donde se conoce como cstdlib. La función que usaré es salir cuando tengamos un error
  • unistd.h: archivo de encabezado que proporciona acceso a la API del sistema operativo POSIX. En los sistemas similares a Unix, la interfaz definida por unistd.h generalmente se compone en gran parte de funciones de contenedor de llamadas del sistema, como bifurcación, canalización y primitivas de E/S (lectura, escritura, cierre, etc.).
  • sys/io.h:esta familia de funciones se utiliza para realizar entradas y salidas de puerto de bajo nivel. Las funciones out* hacen la salida del puerto, las funciones in* hacen la entrada del puerto; las funciones de sufijo b son de ancho de byte y las funciones de sufijo w de ancho de palabra; las funciones del sufijo _p hacen una pausa hasta que se completa la E/S. De esta función familiar usaré outb.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

En Linux, es fácil acceder y controlar el puerto paralelo, sin embargo, se debe tener muy en cuenta el acceso a la raíz. Las anteriores son todas las bibliotecas requeridas para nuestro tutorial de hoy.

Definiendo la dirección de memoria para el puerto paralelo

Una vez incluidas las bibliotecas, debemos definir la dirección de memoria asignada al puerto paralelo, como se mencionó anteriormente, la dirección predeterminada para el primer puerto paralelo es 0x378.

#define base 0x378           /* parallel port base address */

Si tiene algún problema al probar esta dirección, debe probar con 0x278.

Usando el Bus de Datos como Puerto de Salida

Para este tutorial de la primera parte, voy a usar el bus de datos como puerto de salida. En el próximo capítulo veremos cómo usarlo como puerto de entrada de datos o incluso como puerto mixto. En la siguiente imagen podemos ver el control de un conjunto de 8 LED conectados, a través de resistencias limitadoras de corriente, al puerto paralelo, que responden al valor asignado a la dirección 0x378. El valor de las resistencias puede variar de 100 Ohms a 300 Ohms, es importante esta parte porque podemos dañar el puerto si no limitamos la corriente.

Esquema


Nota:el color de los LED no es importante.

Circuito Real



Precaución:tenga cuidado al manipular el conector del puerto paralelo, tenga asegúrese de no desconectar el circuito antes de apagar la PC. Esto puede provocar daños en el puerto o incluso en la placa base. No podemos asumir ningún daño que pueda causar a sus dispositivos de hardware.

Implementación de software

Para mis propósitos, les mostraré cómo poner algunos valores en el puerto, y cómo se debe hacer la temporización de esos valores, esta es una rutina muy simple para mostrarles cómo funciona.

Ahora explicaré todos los comandos y palabras utilizadas en el software de control:

  • Paso 1:Condición si el usuario tiene permiso de raíz para acceder al puerto. El argumento para este comando condicional es ioperm, que establece los bits de permiso de acceso al puerto para la base de direcciones del puerto.
if (ioperm(base,1,1))
  • Paso 2:Si el usuario no tiene suficientes privilegios para acceder al puerto paralelo, se mostrará un error de acceso y la ejecución del programa finalizará.
fprintf(stderr, "Access denied to %x\n", base), exit(1);
  • Paso 3:si se concede el acceso, un bucle for proporcionará una secuencia de encendido y apagado de los LED mediante valores predefinidos para mostrar en el puerto. La función de temporización que utilicé es sleep(), que hace que el subproceso de llamada se duerma hasta que hayan transcurrido unos segundos en el argumento.
        w=0;
        for (x=0; x=7; x++)  
            {        
            y=pow(2,w);
            outb(y, base);
            sleep(1);
            w=w+1;
               }


    Cuando el procesamiento del código pasó la línea de acceso permitido,  'fprintf (stderr, "Acceso denegado a% x \ n", base), exit (1); ', los pines de datos del puerto paralelo están disponibles a su disposición e imaginación. En mi caso solo tomo una secuencia simple de la primera llevada a la última con un intervalo de un segundo, usando potencias de base 2. (ver el enlace del video). Sin embargo, las posibilidades son infinitas, de hecho, sin utilizar multiplexación se pueden controlar hasta 8 salidas independientes, con multiplexación de salidas se pueden crecer hasta 255 posibilidades. Dependiendo de la aplicación, ya sea en términos de domótica, podemos manejar el puerto sin multiplexar, colocando los búfer adecuados para manejar cargas de corriente más altas, que se tratarán más adelante en otro tutorial.


    Referencias:

    Martin H, Saez F. Domótica, Un Enfoque Sociotécnico. Junio ​​2006. Fundación Rogelio Segovia para el Desarrollo de las Telecomunicaciones, Ciudad Universitaria, s/n 28040-Madrid, ISBN:84-7402-335-1.

    Axelson J. Puerto Paralelo Completo. Programación, interfaz y uso del puerto de impresora paralelo de la PC. Amazon INC. ISBN:0-9650819-1-5

    Kerrisk M. La interfaz de programación de Linux. Proyecto de páginas man de Linux. ISBN 978-1-59327-220-3


    Linux
    1. Cómo encontrar archivos con permisos SUID y SGID en Linux

    2. Flatpak en Linux:qué es y cómo instalar aplicaciones con él

    3. Cómo comprimir archivos y directorios en Linux (con ejemplos)

    4. Cómo buscar puertos abiertos en Linux con netstat, lsof y nmap

    5. ¿Cómo puedo verificar qué puertos están ocupados y qué puertos están libres en mi máquina Linux?

    Cómo hacer un escaneo de puertos en Linux

    ¿Qué es Crontab y cómo automatizar tareas en Linux con Crontab?

    Cómo ver el uso del disco con Duf en Linux y Unix

    Cómo encontrar y cerrar puertos abiertos en Linux

    Cómo usar Netcat para escanear puertos abiertos en Linux

    Cómo y por qué usar Linux para instalar Telnet

      3BCh 3BDh 3BEh
      378h 379h 37Ah
      278h 279h 27Ah