Anterior Siguiente Indice

2. Comenzando

2.1 Depuración

La mejor forma de depurar su código es configurar otra máquina Linux y conectar los dos ordenadores mediante un cable null-módem.

Use miniterm, disponible en el LDP Programmers Guide:
( ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/
en el directorio de ejemplos) para transmitir caracteres a su máquina Linux. Miniterm se puede compilar con mucha facilidad y transmitirá todas las entradas en bruto del teclado por el puerto serie.

Sólo las sentencias define (#define MODEMDEVICE "/dev/ttyS0") tienen que ser comprobadas. Ponga ttyS0 para COM1, ttyS1 para COM2, etc.. Es esencial para comprobar que todos los caracteres se transmiten en bruto (sin un procesamiento de salida) por la línea. Para comprobar su conexión, inicie miniterm en ambos ordemadores y teclee algo. Los caracteres introducidos en un ordenador deberían aparecer en el otro y viceversa. La entrada no tendrá eco en la pantalla del ordenador en el que escribamos.

Para hacer un cable null-modem tiene que cruzar las líneas TxD (transmit) y RxD (receive). Para una descripción del cable vea el Serie-COMO.

También es posible ejecutar estas comprobaciones con un sólo ordenador, si tiene un puerto serie no utilizado. Puede ejecutar dos miniterm en sendas consolas virtuales. Si libera un puerto serie desconectando el ratón, recuerde redirigir /dev/mouse, si existe. Si usa una tarjeta multipuerto serie, esté seguro de configurarla correctamente. Yo tenía la mía mal configurada, y todo funcionaba bien mientras hacía las comprobaciones en un sólo ordenador. Cuando lo conecté a otro, el puerto empezó a perder caracteres. La ejecución de dos programas en un ordenador nunca es completamente asíncrona.

2.2 Configuración del Puerto

Los dispositivos /dev/ttyS* tienen como misión conectar terminales a su linux, y están configurados para este uso al arrancar. Hay que tener esto presente cuando se programen comunicaciones con un dispositivo. Por ejemplo, los puertos están configurados para escribir en pantalla cada carácter enviado desde el dispositivo, que normalmente tiene que ser cambiado para la transmisión de datos.

Todos los parámetros se pueden configurar fácilmente con un programa. La configuración se guarda en una estructura struct termios, que está definida en <asm/termbits.h>:

#define NCCS 19
struct termios {
      tcflag_t c_iflag;         /* parametros de modo entrada */
      tcflag_t c_oflag;         /* parametros de modo salida */
      tcflag_t c_cflag;         /* parametros de modo control */
      tcflag_t c_lflag;         /* parametros de modo local */
      cc_t c_line;              /* disciplina de la linea */
      cc_t c_cc[NCCS];          /* caracteres de control */
};

Este archivo también incluye todas las definiciones de parámetros. Los parámetros de modo entrada de c_iflag manejan todos los procesos de entrada, lo cual significa que los caracteres enviados desde el dispositivo pueden ser procesados antes de ser leídos con read.

De forma similar c_oflag maneja los procesos de salida. c_cflag contiene la configuración del puerto, como la velocidad en baudios, bits por carácter, bits de parada, etc... Los parámetros de modo local se guardan en c_lflag. Determinan si el carácter tiene eco, señales enviadas al programa, etc...

Finalmente la tabla c_cc define el carácter de control para el fin de fichero, parada, etc... Los valores por defecto de los caracteres de control están definidos en <asm/termios.h>. Los parámetros están descritos en la página del manual termios(3).

La estructura termios contiene los elementos c_line. Estos elementos no se mencionan ni las páginas del manual para termios de Linux ni en las páginas de manual de Solaris 2.5. ¿Podría alguien arrojar alguna luz sobre esto? ¿No debería estar incluido en la estructura termio?

2.3 Conceptos de entrada para dispositivos serie

Hay tres diferentes conceptos de entrada que queremos presentar. El concepto apropiado se tiene que escoger para la aplicación a la que lo queremos destinar. Siempre que sea posible no haga un bucle para leer un sólo carácter a fin de obtener una cadena completa. Cuando he hecho esto, he perdido caracteres, mientras que un read para toda la cadena no mostró errores.

Proceso de Entrada Canónico

Es el modo de proceso normal para terminales, pero puede ser útil también para comunicaciones con otros dispositivos. Toda la entrada es procesada en unidades de líneas, lo que significa que un read sólo devolverá una línea completa de entrada. Una línea está, por defecto, finalizada con un NL(ASCII LF), y fin de fichero, o un carácter fin de línea. Un CR (el fin de línea por defecto de DOS/Windows) no terminará una línea con la configuración por defecto.

El proceso de entrada canónica puede, también, manejar los caracteres borrado, borrado de palabra, reimprimir carácter, traducir CR a NL, etc..

Proceso de Entrada No Canónico

El Proceso de Entrada No Canónico manejará un conjunto fijo de caracteres por lectura, y permite un carácter temporizador. Este modo se debería usar si su aplicación siempre lee un número fijo de caracteres, o si el dispositivo conectado envía ráfagas de caracteres.

Entrada Asíncrona

Los dos modos descritos anteriomente se pueden usar en modos síncrono y asíncrono. El modo síncrono viene por defecto, donde la sentencia read se bloquará hasta que la lectura esté completa. En modo asíncrono la sentencia read devolverá inmediatamente y enviará una señal al programa llamador cuando esté completa. Esta señal puede ser recibida por un manejador de señales.

Espera de Entradas Origen Múltiple

No es un modo diferente de entrada, pero puede ser útil si está manejando dispositivos múltiples. En mi aplicación manejaba entradas sobre un socket TCP/IP y entradas sobre una conexión serie de otro ordenador de forma casi simultánea. El programa ejemplo dado abajo esperará una entrada de dos orígenes distintos. Si la entrada de una fuente está disponible, entonces será procesada, y el programa esperará otra entrada nueva.

La aproximación presentada abajo parece más bien compleja, pero es importante tener en cuenta que Linux es un sistema operativo multiproceso. La llamada al sistema select no carga la CPU mientras espera una entrada, mientras que un bucle hasta que hay una una entrada disponible ralentizaría demasiado el resto de procesos que se ejecuten a la misma vez.


Anterior Siguiente Indice