C�MO Programar el puerto serie en Linux
por Peter H. Baumann,
[email protected]
traducci�n de Pedro Pablo F�brega
[email protected]
v0.3, 14 Junio 1997
Este documento describe c�mo programar comunicaciones con dispositivos
sobre puerto serie en una m�quina Linux.
______________________________________________________________________
�ndice General:
1. Introducci�n
1.1. Copyright
1.2. Versiones futuras de este Documento
1.3. Revisi�n
2. Comenzando
2.1. Depuraci�n
2.2. Configuraci�n del Puerto
2.3. Conceptos de entrada para dispositivos serie
2.3.1. Proceso de Entrada Can�nico
2.3.2. Proceso de Entrada No Can�nico
2.3.3. Entrada As�ncrona
2.3.4. Espera de Entradas Origen M�ltiple
3. Programas Ejemplo
3.1. Proceso de Entrada Can�nico
3.2. Proceso de Entrada NO Can�nico
3.3. Entrada As�ncrona
3.4. Espera de Entradas de Origen M�ltiple.
4. Otras fuentes de Informaci�n
5. Contribuciones
5.1. Traducci�n
6. Anexo: El INSFLUG
______________________________________________________________________
1. Introducci�n
Este es el COMO Programar el puerto serie en Linux. Todo sobre c�mo
programar comunicaciones con otros dispositivos/ordenadores sobre una
l�nea serie, bajo Linux. Explicaremos diferentes t�cnicas: E/S
Can�nica (s�lo se transmiten/reciben l�neas completas), E/S as�ncrona,
y espera para una entrada de origen m�ltiple.
Este documento no describe c�mo configurar un puerto serie, ya que
esto ha sido descrito por Greg Hankins en el Serial-HOWTO (--
Disponible en castellano como Serie-COMO.--)
Tengo que hacer notar encarecidamente que no soy un experto en este
campo, pero he tenido problemas con un proyecto que necesitaba tales
comunicaciones. Los ejemplos de c�digo a�adidos aqu� se derivaron del
c�digo de miniterm disponible en la gu�a de programadores del Linux
Documentation Project:
(
ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/ y
espejos) en el directorio de ejemplos. Si alguien tiene alg�n
comentario, con gusto lo incorporar� a este documento (ver secci�n
``'').
Todos los ejemplos fueron comprobados usando un n�cleo Linux 2.0.29
sobre un i386.
1.1. Copyright
El C�MO Programar el puerto serie en Linux es propiedad inteletual (C)
1997 de Peter Baumann. Los documentos Linux HOWTO - Linux COMO pueden
ser reproducidos y distribuidos completos o en parte, en cualquier
medio f�sico o electr�nico, con la �nica condici�n de que mantengan
esta nota de propiedad intelectual en todas sus copias. La
redistribuci�n comercial est� permitida y fomentada; de todas formas
al autor le gustar�a que se le notificaran tales distribuciones.
Todas las traducciones, trabajos derivados o trabajos agregados que
incorporen cualquier documento Linux HOWTO-Linux COMO debe estar
cubierto por esta nota de propiedad intelectual. En resumen, no puede
crear un trabajo derivado de un HOWTO-COMO e imponer restricciones
adicionales a su distribuci�n. Se pueden conceder excepciones a estas
reglas bajo ciertas condiciones; por favor contacte con el coordinador
de los HOWTO en la direcci�n dada abajo.
Resumiendo, queremos promover la difusi�n de esta informaci�n a trav�s
de tantos canales com sea posible. No obstante queremos retener la
propiedad intelectual de los docuentos HOWTO-COMO, y nos gustar�a que
se nos notificara cualquier plan para redistribuir los HOWTO-COMO.
Si tiene preguntas, por favor contacte con Greg Hankins, el
coordinador de los HOWTO de Linux, en
[email protected] mediante
correo electr�nico.
1.2. Versiones futuras de este Documento
Las nuevas versiones de COMO Programar el puerto serie en Linux
estar�n disponibles en:
ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO y
sus espejos. Hay otros formatos, como versiones PostScript y DVI en
el directorio other-formats.
C�MO Programar el puerto serie en Linux tambi�n est� disponible en
http://sunsite.unc.edu/LDP/HOWTO/Serial-Programming-HOWTO.html y ser�
enviado a comp.os.linux.answers mensualmente.
1.3. Revisi�n
Por favor, m�ndeme cualesquiera correcci�n, pregunta, comentario,
sugerencia o material adicional. Me gustar�a mejorar este HOWTO-COMO.
D�game exactamente qu� es lo que no entiende, o qu� deber�a estar m�s
claro. Me puede encontrar en
[email protected] v�a email. Por
favor, incluya el n�mero de versi�n del C�MO Programar el puerto serie
en Linux cuando escriba. Esta es la versi�n 0.3.
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.
2.3.1. 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..
2.3.2. 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.
2.3.3. 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.
2.3.4. 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.
3. Programas Ejemplo
Todos los ejemplos provienen de miniterm.c. El buffer est� limitado a
255 caracteres, como la longitud m�xima de cadena para el proceso de
entrada can�nica. (<linux/limits.h> o <posix1_lim.h>).
Vea los comentarios que hay en el c�digo para una explicaci�n del uso
de los diferentes modos de entrada. Espero que el c�digo sea
comprensible. El ejemplo de entrada can�nica est� mejor comentado, el
resto de los ejemplos est�n comentados s�lo donde difieren del ejemplo
de entrada can�nica para remarcar las diferencias.
Las descripciones no son completas, por eso le invito a experimentar
con los ejemplos para obtener mejores soluciones para su aplicaci�n.
�No olvide dar los permisos apropiados a los puertos serie:
chmod a+rw /dev/ttyS1
3.1. Proceso de Entrada Can�nico
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
/* la tasa de baudios esta definida en <asm/termbits.h>, que esta
incluida <termios.h> */
#define BAUDRATE B38400
/* cambie esta definicion por el puerto correcto */
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* fuentes cumple POSIX */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
/*
Abre el dispositivo modem para lectura y escritura y no como controlador
tty porque no queremos que nos mate si el ruido de la linea envia
un CTRL-C.
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) { perror(MODEMDEVICE); exit(-1); }
tcgetattr(fd,&oldtio); /* almacenamos la configuracion actual del puerto */
bzero(newtio, sizeof(newtio)); /* limpiamos struct para recibir los
nuevos parametros del puerto */
/*
BAUDRATE: Fija la tasa bps. Podria tambien usar cfsetispeed y cfsetospeed.
CRTSCTS : control de flujo de salida por hardware (usado solo si el cable
tiene todas las lineas necesarias Vea sect. 7 de Serial-HOWTO)
CS8 : 8n1 (8bit,no paridad,1 bit de parada)
CLOCAL : conexion local, sin control de modem
CREAD : activa recepcion de caracteres
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
/*
IGNPAR : ignora los bytes con error de paridad
ICRNL : mapea CR a NL (en otro caso una entrada CR del otro ordenador
no terminaria la entrada) en otro caso hace un dispositivo en bruto
(sin otro proceso de entrada)
*/
newtio.c_iflag = IGNPAR | ICRNL;
/*
Salida en bruto.
*/
newtio.c_oflag = 0;
/*
ICANON : activa entrada canonica
desactiva todas las funcionalidades del eco, y no envia segnales al
programa
llamador
*/
newtio.c_lflag = ICANON;
/*
inicializa todos los caracteres de control
los valores por defecto se pueden encontrar en /usr/include/termios.h,
y vienen dadas en los comentarios, pero no los necesitamos aqui
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* @ */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* temporizador entre caracter, no usado */
newtio.c_cc[VMIN] = 1; /* bloqu.lectura hasta llegada de caracter. 1 */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */
/*
ahora limpiamos la linea del modem y activamos la configuracion del
puerto
*/
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/*
configuracion del terminal realizada, ahora manejamos las entradas.
En este ejemplo, al introducir una 'z' al inicio de linea terminara el
programa.
*/
while (STOP==FALSE) { /* bucle hasta condicion de terminar */
/*
bloque de ejecucion de programa hasta que llega un caracter de fin de
linea, incluso si llegan mas de 255 caracteres.
Si el numero de caracteres leidos es menor que el numero de caracteres
disponibles, las siguientes lecturas devolveran los caracteres restantes.
'res' tomara el valor del numero actual de caracteres leidos.
*/
res = read(fd,buf,255);
buf[res]=0; /* envio de fin de cadena, a fin de poder usar printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
/* restaura la anterior configuracion del puerto */
tcsetattr(fd,TCSANOW,&oldtio);
}
3.2. Proceso de Entrada NO Can�nico
En el modo de proceso de entrada no can�nico, la entrada no est�
ensamblada en l�neas y el procesamiento de la entrada (erase, kill,
delete, etc.) no ocurre. Dos par�metros controlan el comportamiento de
este modo: c_cc[VTIME] fija el temporizador de car�cter, y fija el
n�mero m�nimo de caracteres a recibir antes de satisfacer la lectura.
Si MIN > 0 y TIME = 0, MIN fija el n�mero de caracteres a recibir
antes de que la lectura est� realizada. Como TIME es cero, el
temporizador no se usa.
Si MIN = 0 y TIME > 0, TIME indica un tiempo de espera. La lectura se
realizar� si es le�do un s�lo car�cter, o si se excede TIME (t =TIME
*0.1 s). Si TIME se excede, no se devuelve ning�n car�cter.
Si MIN > 0 y TIME > 0, TIME indica un temporizador entre caracteres.
La lectura se realizar� si se reciben MIN caracteres o el tiempo entre
dos caracteres excede TIME. El temporizador se reinicia cada vez que
se recibe un car�cter y s�lo se hace activo una vez que se ha recibido
el primer car�cter.
Si MIN = 0 y TIME = 0, la lectura se realizar� inmediatamente.
Devolver� el n�mero de caracteres disponibles en el momento, o el
n�mero de caracteres solicitados. De acuerdo con Antonino (ver
contribuciones), podr�a poner un fcntl(fd, F_SETFL, FNDELAY); antes de
leer para obtener el mismo resultado.
Modificando newtio.c_cc[VTIME] y newtio.c_cc[VMIN] se pueden comprobar
todos los modos descritos arriba.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* fuentes cumple POSIX */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) { perror(MODEMDEVICE); exit(-1); }
tcgetattr(fd,&oldtio); /* salva configuracion actual del puerto */
bzero(newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
/* pone el modo entrada (no-canonico, sin eco,...) */
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; /* temporizador entre caracter, no usado */
newtio.c_cc[VMIN] = 5; /* bloquea lectura hasta recibir 5 chars */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
while (STOP==FALSE) { /* bucle para entrada */
res = read(fd,buf,255); /* devuelve tras introducir 5 */
buf[res]=0; /* asi podemos printf... */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
tcsetattr(fd,TCSANOW,&oldtio);
}
3.3. Entrada As�ncrona
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* fuentes cumple POSIX */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
void signal_handler_IO (int status); /* definicion del manejador de segnal */
int wait_flag=TRUE; /* TRUE mientras no segnal recibida */
main()
{
int fd,c, res;
struct termios oldtio,newtio;
struct sigaction saio; /* definicion de accion de segnal */
char buf[255];
/* abre el dispositivo en modo no bloqueo (read volvera inmediatamente) */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) { perror(MODEMDEVICE); exit(-1); }
/* instala el manejador de segnal antes de hacer asincrono el dispositivo */
saio.sa_handler = signal_handler_IO;
saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
/* permite al proceso recibir SIGIO */
fcntl(fd, F_SETOWN, getpid());
/* Hace el descriptor de archivo asincrono (la pagina del manual dice solo
O_APPEND y O_NONBLOCK, funcionara con F_SETFL...) */
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd,&oldtio); /* salvamos conf. actual del puerto */
/*
fija la nueva configuracion del puerto para procesos de entrada canonica
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/* bucle de espera para entrada. Normalmente se haria algo util aqui */
while (STOP==FALSE) {
printf(".\n");usleep(100000);
/*
tras recibir SIGIO, wait_flag = FALSE, la entrada esta disponible y puede ser leida
*/
if (wait_flag==FALSE) {
res = read(fd,buf,255);
buf[res]=0;
printf(":%s:%d\n", buf, res);
if (res==1) STOP=TRUE; /* para el bucle si solo entra un CR */
wait_flag = TRUE; /* espera una nueva entrada */
}
}
/* restaura la configuracion original del puerto */
tcsetattr(fd,TCSANOW,&oldtio);
}
/***************************************************************************
* manipulacion de segnales. pone wait_flag a FALSE, para indicar al bucle *
* anterior que los caracteres han sido recibidos *
***************************************************************************/
void signal_handler_IO (int status)
{
printf("recibida segnal SIGIO.\n");
wait_flag = FALSE;
}
3.4. Espera de Entradas de Origen M�ltiple.
Esta secci�n est� al m�nimo. S�lo intenta ser un indicaci�n, y por
tanto el ejemplo de c�digo es peque�o. Esto no s�lo funcionar� con
puertos serie, sino que tambi�n lo har� con cualquier conjunto de
descriptores de archivo.
La llamada select y las macros asociadas usan un fd_set. Esto es una
tabla de bits, que tiene una entrada de bit para cada n�mero de
descriptor de archivo v�lido. select aceptar� un fd_set con los bits
fijados para los descriptores de archivos relevantes y devuelve un
fd_set, en el cual los bits para el descriptor del archivo est�n
fijados donde ocurre una entrada, salida o excepci�n. Todas la
manipulaciones de fd_set se llevan a cabo mediante las macros
proporcionadas. Ver tambi�n la p�gina del manual select(2).
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
main()
{
int fd1, fd2; /* origenes de entrada 1 y 2 */
fd_set readfs; /* descriptor de archivo */
int maxfd; /* mixmum file desciptor used */
int loop=1; /* bucle mientras TRUE */
/*
open_input_source abre un dispositivo, fija el puerto correctamente
y devuelve un descriptor de archivo
*/
fd1 = open_input_source("/dev/ttyS1"); /* COM2 */
if (fd1<0) exit(0);
fd2 = open_input_source("/dev/ttyS2"); /* COM3 */
if (fd2<0) exit(0);
maxfd = MAX (fd1, fd2)+1; /* entrada maxima de bits (fd) a probar */
/* bucle para entrada */
while (loop) {
FD_SET(fd1, &readfs); /* comprobacion origen 1 */
FD_SET(fd2, &readfs); /* comprobacion origen 2 */
/* bloqueo hasta que la entrada esta disponible */
select(maxfd, &readfs, NULL, NULL, NULL);
if (FD_ISSET(fd1)) /* entrada de origen 1 esta disponible */
handle_input_from_source1();
if (FD_ISSET(fd2)) /* entrada de origen 2 esta disponible */
handle_input_from_source2();
}
}
El ejemplo dado bloquea indefinidamente hasta que una entrada de una
de las fuentes est� disponible. Si necesita un temporizador para la
entrada, s�lo sustituya la llamada select por:
int res;
struct timeval Timeout;
/* fija el valor del temporizador en el bucle de entrada */
Timeout.tv_usec = 0; /* milisegundos */
Timeout.tv_sec = 1; /* segundos */
res = select(maxfd, &readfs, NULL, NULL, &Timeout);
if (res==0)
/* numero de descriptores de archivo con input = 0, temporizador sobrepasado */
Este ejemplo concluye el tiempo de espera tras un segundo. Si este
tiempo transcurre, select devolver� 0, pero tenga cuidado porque
Timeout se decrementa por el tiempo actualmente esperado para la
entrada por select. Si el valor de retardo es cero, select volver�
inmediatamente.
4. Otras fuentes de Informaci�n
� El Linux Serie-COMO describe c�mo configurar un puerto serie y
contiene informaci�n sobre hardware.
� Serial Programming Guide for POSIX Compliant Operating Systems, por
Michael Sweet.
� La p�gina del manual termios(3) describe todos los par�metros de la
estructura termios.
5. Contribuciones
Como se mencion� en la introducci�n, no soy un experto en este campo,
pero he tenido mis propios problemas, y encontr� la soluci�n con la
ayuda de otras personas. Gracias por la ayuda de Mr. Strudthoff de
European Transonic Windtunnel, Cologne, Michael Carter,
[email protected], y Peter Waltenberg,
[email protected]
Antonino Ianella,
[email protected] escribi� el Serial-Port-Programming
Mini HOWTO, a la misma vez que yo preparaba este documento. Greg
Hankins me pidi� que incorporara el Mini-Howto de Antonino en este
documento.
La estructura de este documento y el formateo SGML provienen del
Serial-HOWTO de Greg Hankins.
5.1. Traducci�n
Este documento ha sido traducido por
Pedro Pablo F�brega Mart�nez,
[email protected]
Si encontr�is mejoras, a�adidos o fallos, de cualquier tipo,
indic�dmelo para mejorar el documento.
Insultos > /dev/null
6. Anexo: El INSFLUG
El INSFLUG forma parte del grupo internacional Linux Documentation
Project, encarg�ndose de las traducciones al castellano de los Howtos
(Comos), as� como la producci�n de documentos originales en aquellos
casos en los que no existe an�logo en ingl�s.
En el INSFLUG se orienta preferentemente a la traducci�n de documentos
breves, como los COMOs y PUFs (Preguntas de Uso Frecuente, las FAQs.
:) ), etc.
Dir�jase a la sede del INSFLUG para m�s informaci�n al respecto.
En la sede del INSFLUG encontrar� siempre las �ltimas versiones de las
traducciones: www.insflug.org. Aseg�rese de comprobar cu�l es la
�ltima versi�n disponible en el Insflug antes de bajar un documento de
un servidor r�plica.
Se proporciona tambi�n una lista de los servidores r�plica (mirror)
del Insflug m�s cercanos a Vd., e informaci�n relativa a otros
recursos en castellano.
Francisco Jos� Montilla,
[email protected].