ingeniería en informática sistemas operativosso-unlam.com.ar/informes/informepuerto serie - parte...

32
Universidad Nacional de la Matanza Sistemas Operativos 1 Ingeniería en Informática Sistemas Operativos Trabajo Práctico 2 “Optimización del Puerto Serie” Nicanor Casas Equipo Graciela De Luca Waldo Valiente Docente Federico Díaz Martín Cortina Sergio Martín Esteban Carnuccio GRUPO: Día cursada: Miércoles y Viernes Noche Alumnos Apellido Nombre DNI Rodriguez Lucas 34.265.017 Canella Leandro 29.410.564 Céspedes Gustavo 30.862.441 Acreditación: Instancia Fecha Calificación PRE-ENTREGA ENTREGA FINAL

Upload: buicong

Post on 13-Feb-2019

213 views

Category:

Documents


0 download

TRANSCRIPT

Universidad Nacional de la Matanza Sistemas Operativos

1

Ingeniería en Informática

Sistemas Operativos

Trabajo Práctico 2

“Optimización del Puerto Serie”

Nicanor Casas Equipo Graciela De Luca Waldo Valiente Docente Federico Díaz Martín Cortina Sergio Martín Esteban Carnuccio

GRUPO: Día cursada: Miércoles y Viernes Noche

Alumnos Apellido Nombre DNI

Rodriguez Lucas 34.265.017 Canella Leandro 29.410.564 Céspedes Gustavo 30.862.441

Acreditación:

Instancia Fecha Calificación

PRE-ENTREGA ENTREGA FINAL

Universidad Nacional de la Matanza Sistemas Operativos

2

Observaciones:

Universidad Nacional de la Matanza Sistemas Operativos

3

Índice

1. OBJETIVO DEL TP .................................................................................................................. 4

ALCANCE ............................................................................................................................................. 4 FUERA DE ALCANCE ............................................................................................................................... 4

2. RESUMEN DEL DOCUMENTO Y EXPLICACIÓN DE SU ESTRUCTURA ........................................ 5

3. TEÓRICA ............................................................................................................................... 6

INTRODUCCIÓN TEÓRICA AL TEMA A TRATAR .............................................................................................. 6 EL CONECTOR SERIAL ............................................................................................................................. 6 CONTROL DE FLUJO ............................................................................................................................... 8 UART ................................................................................................................................................ 9 FIFO CONTROL REGISTER (FCR) ........................................................................................................... 11 TIPO DE COMUNICACIÓN DE LA UART .................................................................................................... 11 ANÁLISIS DEL CASO .............................................................................................................................. 12 ANÁLISIS DEL FTRACE Y SU FORMATO ................................................................................................... 15

4. PRÁCTICA ........................................................................................................................... 17

DRIVER DEL PUERTO COM – FUNCIONES DE INICIALIZACIÓN, TRANSMISIÓN Y RECEPCIÓN – MANEJOS DE

INTERRUPCIONES - POLLING .................................................................................................................. 17 COM.H ............................................................................................................................................ 17 COM.C ............................................................................................................................................ 20 LOG.H ............................................................................................................................................. 22 COMANDO PARA TESTEO DE LA CONEXIÓN SERIE ....................................................................................... 24 SOLUCIÓN A PROBLEMAS DE ESTABILIDAD ............................................................................................... 24 CONFIGURACIÓN DEL SODIUM PARA PODER UTILIZAR EL PUERTO SERIE DENTRO DEL MISMO ORDENADOR, USANDO LA VM Y LA MÁQUINA REAL. .................................................................................................... 25

5. CONCLUSIONES .................................................................................................................. 31

6. MEJORAS QUE SE DEBERÍAN APLICAR A FUTURO PARA UN MEJOR FUNCIONAMIENTO DEL PUERTO SERIE. ........................................................................................................................... 31

7. BIBLIOGRAFÍA/REFERENCIAS .............................................................................................. 32

Universidad Nacional de la Matanza Sistemas Operativos

4

Desarrollo

1. Objetivo del TP

El objetivo principal de este trabajo de investigación es subsanar algunas restricciones existentes en el desarrollo actual del driver de puerto serie, como la falta de parametrización de la velocidad de transmisión, bits de parada y tipo de sincronización, y problemas de estabilidad en la inicialización, transmisión y recepción de datos.

Alcance:

Resolver problemas de estabilidad de la interfaz Optimizar el funcionamiento del driver del puerto serie desarrollado en Sodium Implementar comunicación Full-Duplex en forma serial Efectuar el LOG de Sodium en forma remota.

Fuera de alcance:

Implementar un protocolo de depuración remota.

Universidad Nacional de la Matanza Sistemas Operativos

5

2. Resumen del documento y explicación de su estructura El presente documento permite el adecuado seguimiento de los cambios que han sido realizados durante el trabajo práctico, al sistema operativo SODIUM. Cuenta principalmente con un componente teórico, que facilita la familiarización con el entorno, ayudando a comprender más acerca del objetivo final del Trabajo Práctico (Implementación y utilización del puerto serie para el logueo de eventos). Luego de analizar cuidadosamente los requerimientos del TP se especificaron todas aquellas alternativas posibles de implantación, considerando sus ventajas y desventajas. Una vez elegida la estrategia más adecuada, se definieron todos aquellos cambios llevados a cabo en la estructura de archivos de SODIUM, ya sea MAKEFILE y agregados de nuevas bibliotecas, ficheros de código, funciones y variables.

Universidad Nacional de la Matanza Sistemas Operativos

6

3. Teórica

Introducción teórica al tema a tratar

El puerto SERIE (RS-232) o COM (puerto de comunicación) es un adaptador asíncrono utilizado para poder intercomunicar dos terminales (DTE/DCE) entre sí. El puerto envía y recibe información a través de un cable, y dentro de las terminales la misma es tratada a través del driver de comunicación SERIE. Los DTE son equipos terminales de datos, y están representados por cualquier equipo informático ya sea receptor o emisor de datos. Es decir, es aquel dispositivo que dentro del circuito de comunicación hace de fuente o destino de la información. En cambio, los DCE son equipos que procesan los datos y los envía sin modificarlos.

Los puertos serie dependen de un chip especial como controlador, el Universal Asynchronous Receiver/Transmitter (UART), para funcionar correctamente. La UART es un circuito integrado diseñado para implementar la comunicación serie y es el encargado de manejar la transmisión de datos a través del puerto serie, cuyas funciones principales son manejar las interrupciones como también la conversión de datos de serie a paralelo y viceversa (lo veremos con más profundidad más adelante).

El conector serial

El conector externo para un puerto serie puede ser de 9 o de 25 pines. Originalmente el uso de un puerto serie era para conectar un modem a la computadora. Comúnmente se usa un conector DB9 hembra para conectarlo en el conector serial DB9 macho que poseen las computadoras.

Universidad Nacional de la Matanza Sistemas Operativos

7

Pin # 9-pin Pin # 25-pin Siglas Nombre Completo Dirección

3 2 TxD Transmit Data -->

2 3 RxD Receive Data <--

7 4 RTS Request To Send -->

8 5 CTS Clear To Send <--

6 6 DSR Data Set Ready <--

4 20 DTR Data Terminal Ready -->

1 8 DCD Data Carrier Detect <--

9 22 RI Ring Indicator <--

5 7 SG Signal Ground

TxD (Transmit Data, transmisión de datos): Señales de datos que se transmiten del DTE al DCE. En principio, los datos no se pueden transmitir si alguno de los pins RTS, CTS, DSR ó DTR está desactivado.

RxD (Receive Data, recepción de datos): Señales de datos transmitidos desde el DCE al DTE.

DTR (Data Terminal Ready, terminal de datos preparado): Señal del DTE que indica que está conectado, generalmente en "0" indica que el DTE está listo para transmitir o recibir.

DSR (Data Set Ready, dispositivo preparado): Señal del DCE que indica que el dispositivo está en modo de transmisión de datos.

RTS (Request To Send, petición de envío): Señal del DTE al DCE, notifica al DCE que el DTE dispone de datos para enviar. Se emplea en líneas semiduplex para controlar la dirección de transmisión [1]. Una transición de 1 a 0 avisa al DCE que tome las medidas necesarias para prepararse para la transmisión.

CTS (Clear To Send, preparado para transmitir): Señal del DCE al DTE indicando que puede transmitirle datos.

DCD (Carrier Detect, detección de portadora): Señal del DCE que ha detectado la señal portadora enviado por un modem remoto o que la línea telefónica está abierta.

RI (Ring Indicator, timbre o indicador de llamada entrante): Señal del DCE indicando que está recibiendo una llamada por un canal conmutado.

SG (GND) (System Ground ó Signal Ground, masa de señal): Masa común para todas las líneas.

La información se envía al puerto caracter a caracter, convirtiéndola en una señal a través de un cable serie, que en nuestro caso utilizamos un cable NULL MODEM(o cable cruzado).

Representación gráfica de un tipo de cable NULL MODEM y como están conectados los pines.

Universidad Nacional de la Matanza Sistemas Operativos

8

MODEM NULO Se usa para conectar dos DTEs, proporciona una manera económica de conectar dos computadoras o bien una computadora con un dispositivo. La teoría de funcionamiento es sencilla, la meta consiste en hacer que la computadora piense que está “hablando” con un MODEM, en lugar de con otra computadora. Todo dato transmitido de una computadora debe ser recibido por la otra, de tal forma que TxD está conectado con RxD en ambas computadoras, la señal de tierra también debe estar unida entre ambas. El pin Data Terminal Ready (DTR) está interconectado con el pin Data Set Ready (DSR) y con Carrier Detect (CD) en ambos extremos. De tal forma que cuando el pin Data Terminal Ready (DTR) se active, entonces Data Set Ready (DSR) y Carrier Detect (CD) se activarán inmediatamente. En este punto, la computadora “piensa” que el “MODEM” al cual está conectada está listo y ha detectado la portadora de la línea telefónica. Los pines que quedan son Request to Send (RTS) y Clear To Send (CTS). Como ambas computadoras se comunican a la misma velocidad, el control de flujo no es necesario de tal forma que estos dos pines están también interconectados. Cuando la computadora desea enviar datos, envía la señal Request To Send (RTS) y esta misma señal es atrapada en el pin Clear To Send (CTS) de tal forma que siempre obtiene la respuesta del “MODEM” que está listo para recibir datos. Esto puede ser muy peligroso porque puede ser que el dispositivo no esté listo para recibir datos y los mismos sean enviados y nunca sean recibidos. Por eso existe el control de flujo. Control de Flujo

Un aspecto importante de la comunicación serial es el concepto de control de flujo. Esta es la capacidad de sincronización entre transmisor y receptor con la finalidad de que el receptor no se sature. Existe el control de flujo por software y control de flujo por Hardware. Imagine un MODEM que se comunica a 56Kbps con la red, y la conexión serial entre la computadora y el modem es de a 115Kbps, el cual es más del doble de rápido que lo que el MODEM puede transmitir hacia la red. Esto significa que el modem está recibiendo más información de la computadora que la que puede transmitir por la línea telefónica. Aun si el modem tuviera un buffer grande para almacenar datos, este rápidamente se llenaría (overflow) y sería incapaz de funcionar correctamente con toda la información recibida de la computadora. Esta es una aplicación clásica donde se requiere control de flujo. En conclusión los síntomas de no tener control de flujo son fragmentos de datos que faltan de los archivos enviados. Cuando sucede overflow, a menudo cientos o incluso miles de bytes se pierden, y todo en trozos contiguos.

Universidad Nacional de la Matanza Sistemas Operativos

9

Tipos de control de flujo

1) Control de Flujo por Software

Algunas veces llamado Xon/Xoff, usa dos caracteres (Xon y Xoff). El caracter Xon comúnmente es el ASCII17 y el carácter ASCII 19 es el Xoff. Cuando la computadora llena el buffer del MODEM, este envía el carácter Xoff indicándole a la computadora que deje de enviar datos. Una vez que el MODEM tiene espacio para más datos envía el carácter Xon y la computadora reanuda el envío de datos. Este tipo de control de flujo tiene la ventaja de que no requiere más cables, ya que los caracteres Xon y Xoff son enviados por las líneas TD/RD. La desventaja de este control de flujo es que tenemos que enviar más datos haciendo la transmisión más lenta.

2) Control de Flujo por Hardware

Si es posible, lo mejor es utilizar el control de flujo por "hardware" que utiliza dos cables dedicados "de control del módem" para enviar las señales de "stop" y "start". El control de flujo de hardware en el puerto serie funciona así: Se utilizan dos pines, el RTS (Request to send - Solicitud de envío) y CTS (Clear to send - Libre para enviar). Cuando el equipo está preparado para recibir datos confirma RTS, poniendo una señal positiva en el pin RTS (que significa "Solicitud para enviarme"). Cuando el equipo no es capaz de recibir más bytes, se niega RTS poniendo una tensión negativa en el pin diciendo: "Dejar de enviarme". El pin RTS se conecta mediante el cable serie al otro pin en el modem, impresora, terminal, etc. La única función de este pin es recibir esta señal. Para el caso de un módem, este "otro" pin será pin RTS del módem. Pero para una impresora, otro PC o un dispositivo no-módem, por lo general es un pin CTS así se requiere un "cruce" o "módem nulo" por cable. Este cable conecta el pin de CTS en un extremo con el pin de RTS en el otro extremo (dos cables desde cada extremo del cable tienen una pin de CTS). Para un módem, se utiliza un cable recto. Para la dirección opuesta de flujo se utiliza un esquema similar. Para un módem, el pin CTS se utiliza para enviar la señal de control de flujo para el pin CTS en el PC. Para un no-módem, el pin de RTS envía la señal. Por lo tanto los módems y los no módems tienen los papeles de sus RTS y CTS pins intercambiados. Algunos no-módems como terminales tontas pueden utilizar otros pines para el control de flujo, como el pin DTR en lugar de RTS.

UART

Para entender las diferencias entre las distintas UART primero vamos a examinar lo que sucede cuando una UART ha enviado o recibido un byte. La UART por sí misma no puede hacer nada con los datos que pasan a través de ella, que sólo recibe y envía. Para las primeras UARTS (8250 y 16450), la CPU recibe una interrupción del dispositivo serie cada vez que un byte se ha enviado o se ha recibido. La CPU mueve el byte recibido fuera del buffer de la UART y lo coloca en algún lugar de la memoria o da a la UART otro byte a enviar. Las primeras UARTs 8250 y 16450 sólo tenían un buffer de 1 byte. Eso significa, que cada vez que 1 byte era enviado o recibido, la CPU se interrumpía. En bajas tasas de transferencia, esto está bien. Pero,

Universidad Nacional de la Matanza Sistemas Operativos

10

a altas velocidades de transferencia, la CPU se pone tan ocupada con la UART que no tiene tiempo para atender adecuadamente a otras tareas. En algunos casos, la CPU no puede atender las interrupciones a tiempo y se sobre escribe el byte, porque están llegando muy rápido. Esto se llama "overflow”. A partir de la UART 16550A (o 16550) el FIFO tiene un tamaño de 16 bytes. Esto significa que puede recibir hasta 14 bytes (o enviar 16 bytes) antes que tenga que interrumpir a la CPU. No sólo puede esperar por más bytes, sino que la CPU puede entonces transferir todo (14 a 16) bytes de una vez. Esta es una ventaja significativa sobre las UARTs anteriores, que sólo tenían un buffer de un byte. La CPU recibe menos interrupciones, y es queda libre para hacer otras cosas. Los datos rara vez se pierden. Tenga en cuenta que el umbral de interrupción de esta UART ("trigger level") puede fijarse en 1, 4, 8, y 14 bytes. Tenga en cuenta que si una interrupción se produce poco antes que el buffer este lleno (en el caso de un "trigger level" de 14 bytes para un buffer de 16 bytes) esto deja espacio para un par de bytes que se reciban antes de que la rutina de servicio de interrupción sea capaz de buscar en realidad todos estos bytes. El "trigger level" se puede ajustar a diferentes valores permitidos, por software del kernel. Un "trigger level" de 1 será casi como una de las primeras UART (salvo que aún tiene espacio para 15 bytes más después de que se emite la interrupción). En el caso que no se complete el "trigger level" hay un tiempo de espera para que una vez superado, se envíe una interrupción de todos modos para completar el envío o recepción. La frecuencia con que se emiten las interrupciones puede ser controlada por el ajuste del valor del RTL (receive trigger level). Cuando la cantidad de datos recibidos llega a la RTL, la UART emitirá una interrupción. La UART 16550A con su FIFO de 16 bytes soporta 4 niveles RTL: 1, 4, 8 y 14 esto significa que se emitirá una interrupción cuando el FIFO de la UART reciba 1, 4, 8, o 14 bytes de datos. Tenga en cuenta que el nivel más alto es 14 en lugar de 16 para evitar “overflow”. Otro problema que hay que considerar es el siguiente: Si la cantidad de datos recibidos no tiene alcanzado el valor de RTL, Por ejemplo, si se configura el nivel de activación a 14 (por defecto), pero el dispositivo sólo envía 4 bytes (sustancialmente menor que 14). La UART utiliza un tiempo de espera para resolver este problema. La longitud del tiempo de espera es diferente para diferentes diseños de UART, pero como regla general, la mayoría de las UART esperan el tiempo necesario para transmitir 4 bytes. Por ejemplo, para una configuración de serie de 300 bps, 8 bits de datos, paridad impar, y 2 bits de parada, 1 bit necesita 3,3 ms para ser transferidos. Dado que la transmisión de cada byte requiere la transmisión de un bit de inicio, 8 bits de datos, 1 bit de paridad y 2 bits de parada, se transmitirá un total de 12 bits, y, en consecuencia: 4 bytes time = 4 bytes x 12 bits / byte x 3.3 ms / bits ≈ 160 ms Un largo período de latencia de este tipo no es apropiado para algunas aplicaciones de control de tiempo crítico. En la comunicación en serie, hay un equilibrio entre el rendimiento y la latencia, y sólo se puede elegir uno, que es una suerte ya que la mayoría de las aplicaciones sólo necesitan uno de los dos. Para aplicaciones tales como la descarga de firmware u otras descargas de archivos sólo se necesita un buen rendimiento. Para tales aplicaciones, sólo tiene que configurar la UART con el valor más alto de RTL (por ejemplo, 14 bytes para el 16550A). Pero para otras aplicaciones, es necesario desactivar el FIFO o establecer el valor RTL a 1 para obtener una mejor latencia. Esto significa que usted necesita responder lo más pronto posible cuando reciba los datos desde la línea serie.

Universidad Nacional de la Matanza Sistemas Operativos

11

En el control de flujo por software, por ejemplo, si recibe un caracter XOFF, debe dejar de transmitir datos de forma inmediata. La discusión anterior se centra en la recepción de datos, pero también hay que controlar la forma en que los datos se transmiten. La diferencia está en la cantidad de bytes que se transmiten para cada interrupción. Tenga en cuenta que la transmisión de más bytes se traducirá en un mayor rendimiento pero para casos de dispositivos viejos con un buffer pequeño la solución es transmitir un byte para cada interrupción, lo que aumenta el desfase entre dos bytes y le da un tiempo mayor de procesamiento al dispositivo. Toda estos parámetros que debemos manejar para la comunicación serie los tenemos en el FIFO control register (FCR). FIFO Control Register (FCR)

BIT Nom Definición Valor Descripción

0 EN FIFO Enable 0 Desactivar FIFO

1 Habilitar FIFO

1 RECV RST

Receiver Reset 0 Sin efecto

1 Restablecer FIFO receptor

2 XMIT RST

Transmitter Reset 0 Sin efecto

1 Restablecer FIFO transmisor

3 DMA DMA mode control 0 Funcionar como UART 16450

1 Modo FIFO

4 0 - - -

5 0 - - -

6 RT0 Receiver trigger level 0 0 1 byte en FIFO

7 RT1 0 1 4 byte en FIFO

1 0 8 byte en FIFO

1 1 14 byte en FIFO

Tipo de comunicación de la UART

La comunicación de la UART es full duplex siempre que la conexión hardware lo permita, teniendo distintas líneas de transmisión y recepción. Para esto si queres una conexión Full duplex o Half duplex debemos saber que estándar de comunicaciones en bus de la capa física del modelo OSI usaremos. Si queremos una comunicación full duplex usaremos el RS 232 y si queremos una comunicación half duplex (semi duplex) usaremos la RS 485. La UART depende de la conexión física solamente para el tipo de comunicación (FD o HD) [2].

Universidad Nacional de la Matanza Sistemas Operativos

12

Análisis del caso

Debido a que no existía el driver para puerto Serie en SODIUM y hubo que crearlo de cero, se debe definir la información básica y necesaria para la construcción del mismo. Teniendo en cuenta que para la comunicación serie vamos a utilizar interrupciones o polling. El manejo de señales a través de interrupciones indica que se deben utilizar los registros de la UART (que se definen más adelante) para atender las distintas IRQ’s(interrupciones) propias del manejo de la comunicación serie. El modo de interrupciones es asincrónico y lleva un control que se define en el driver del puerto Serie. El polling consiste en “escuchar” (chequear) la línea de comunicación constantemente hasta detectar que se recibieron datos. Se utiliza como método de sincronización Nuestro driver presenta un conjunto de funciones que permiten inicializar los puertos COM, setear la configuración de la comunicación (velocidad de transmisión, formato de envío de datos, etc…), transmisión, recepción y tratamiento de errores. Se contempla el uso de interrupciones y polling.

Registros de direcciones de los puertos de E/S:

Utiliza una serie de registros para definir los puertos COM y una línea de interrupciones IRQ para llamar la atención del procesador.

Estas direcciones son estándar en la mayoría de las arquitecturas y están definidas en base hexadecimal:

Puerto Registro (IRQ)

COM1 3F8 4

COM2 2F8 3

COM3 3E8 4

COM4 2E8 3

Los siguientes registros son los utilizados por la UART para la comunicación:

Registros E/S Descripción

3F8/2F8 Registro de datos Emisión/Recepción (DRI/O)

3F9/2F9 Registro de habilitación de interrupciones (IER)

3FA/2FA Registro de identificación de interrupciones (IIR)

3FB/2FB Registro de control de la línea (LCR)

3FC/2FC Registro de control del MODEM (MCR)

3FD/2FD Registro de estado de la línea (LSR)

3FE/2FE Registro de estado del MODEM (MSR)

A continuación, una breve descripción de cada uno:

Registro de datos Emisión/Recepción: son dos registros separados. Uno para emisión y el otro para recepción. Si se escribe sobre esos registros se está seleccionando el de emisión. Si se lee, el de recepción

Registro de habilitación de interrupciones(IER): provee cuatros fuentes de interrupción(solo utiliza 4 bits de los 8):

Universidad Nacional de la Matanza Sistemas Operativos

13

Bit Descripción(Description)

0 Información recibida disponible(Received data available)

1 Registro de transmisión en espera vacío(Transmitter holding register empty)

2 Cambio de estado en la línea de recepción(Receiver line status register change)

3 Cambio en el estado del registro del Modem(Modem status register change)

4 Modo suspendido(Sleep mode (16750 only))

5 Modo baja energía(Low power mode (16750 only))

6 Reservado(reserved)

7 Reservado(reserved)

Registro de identificación de interrupciones(IIR): es un registro de solo

lectura que especifica si hay una interrupción pendiente y de qué tipo es la misma:

o Solo usa 4 bits de los 8. o El 1er bit indica si existe o no una interrupción (0 y 1

respectivamente). o 2do, 3er y 4to bit:

000 -> cambio de estado 001 -> NO transmisión 010 -> hay información 011 -> cambio de estado en la línea

Bit Valor(Value) Descripción(Description) Reseteado por(Reset by)

0

0 Interrupción pendiente(Interrupt pending) –

1 No hay interrupción pendiente(No interrupt pending) –

1,2,3

Bit 3 Bit 2 Bit 1

0 0 0 Cambio de estado del Modem(Modem status

change) Leer MSR(MSR read)

0 0 1 Registro de transmisión en espera vacío(Transmitter holding register empty)

Leer IIR o THR(IIR read

or THR write)

0 1 0 Información recibida disponible(Received data

available) Leer RBR(RBR read)

0 1 1 Cambio de estado en la línea(Line status change) Leer LSR(LSR read)

1 1 0 Caracter de timeout(Character timeout (16550)) Leer RBR(RBR read)

Registro de control de línea (LCR): permite especificar los parámetros de

transmisión. Incluye: o Seteo del tamaño de la información a enviar (2 bits). o Bit de parada. o Bit de paridad. o Control de paridad (2 bits).

Universidad Nacional de la Matanza Sistemas Operativos

14

Bit Valor(Value) Descripción(Description)

0,1

Bit 1 Bit 0 Longitud de la palabra(Data word length)

0 0 5 bits

0 1 6 bits

1 0 7 bits

1 1 8 bits

2

0 Bit de parada(1 stop bit)

1 1.5 stop bits (5 bits word) 2 stop bits (6, 7 or 8 bits word)

3,4,5

Bit 5 Bit 4 Bit 3

x x 0 Sin paridad(No parity)

0 0 1 Paridad impar(Odd parity)

0 1 1 Paridad par(Even parity)

1 0 1 Paridad alta(High parity)

1 1 1 Paridad baja(Low parity)

Registro de control de MODEM (MCR): contiene 5 bits que permiten controlar directamente varios de los pines de salida(conectores físicos del cable serie) y manejar el handshake:

Bit Description

0 Terminal de datos disponible(Data terminal ready)

1 Solicitud para enviar(Request to send)

2 Salida Auxiliar 1 (Auxiliary output 1)

3 Salida Auxiliar 1 (Auxiliary output 2)

4 Modeo bucle (Loopback mode)

5 Control de ajuste automático (Autoflow control (16750 only))

6 Reservado (Reserved)

7 Reservado (Reserved)

Registro de estado de línea (LSR): es un registro de solo lectura, que al

leerlo nos devuelve el estado actual de la comunicación.

Bit Description

0 Dato disponible (Data available)

1 Error de desborde (Overrun error)

2 Error de paridad (Parity error)

3 Error de trama (Framing error)

4 Señal de parada recibida (Break signal received)

5 Listo para cargar nuevo bit a enviar (Transmitter holding register Empty)

6 Puerto listo para aceptar nuevo caracter (Transmitter shift register empty)

7 Unused

Universidad Nacional de la Matanza Sistemas Operativos

15

Registro de estado del MODEM (MSR): nos reporta el estado del

handshake y otras señales del MODEM.

Bit Description

0 Cambia si está disponible para enviar(change in Clear to send)

1 Cambia si los datos están listos (change in Data set Ready)

2 trailing edge Ring indicator

3 Cambia si detecta acarreo (change in Carrier detect)

4 Disponible para enviar (Clear to send)

5 Datos listos (Data set ready)

6 Indicador de llamada (Ring indicador)

7 Acarreo detectado (Carrier detect)

Transmisión: En nuestro caso usaremos una transmisión de 9600bps con formato 8N1 (8

bits de datos | sin paridad | 1 bit de parada). El cable utilizado es un NULL MODEM con un extremo de cable RS-232 y el

otro extremo un USB adaptado, el cual nos permite conectarnos con cualquier dispositivo que usemos como terminal (laptop, tablet, PC sin conexión Serie, etc.).

Análisis del FTRACE y su formato

Como se comentó en lo objetivos del trabajo, uno de los puntos es el de evaluar y modificar los logueos actuales del SODIUM. Como base de investigación utilizamos el comando FTRACE de LINUX y adaptando la función vFnLog (…) del SODIUM junto con un formato de logueo customizado por nosotros, para así lograr una implementación de log a través del puerto Serie de los eventos del Kernel. El mismo tendrá un formato adaptado por este grupo, utilizando las funciones existentes en SODIUM para mostrar la información de los eventos logueados. El FTRACE es un tracer interno que se utiliza para debuggear el kernel del Linux permitiendo tracear eventos para detectar problemas de performance, de latencia, etc. Posee varias formas de ser llamada y utilizada, pero para este caso nos interesa el formato de salida del log, ya que es el que vamos a tomar como base para implementar el LOG de SODUIM a través del puerto Serie. A continuación se muestra un ejemplo de salida del Ftrace, usando “function”, el cual indica al “tracer” que tracee todas las funciones del Kernel:

bash-1977 [000] .... 17284.993652: sys_close <-system_call_fastpath

bash-1977 [000] .... 17284.993653: __close_fd <-sys_close

bash-1977 [000] .... 17284.993653: _raw_spin_lock <-__close_fd

sshd-1974 [003] .... 17284.993653: __srcu_read_unlock <-fsnotify

bash-1977 [000] .... 17284.993654: add_preempt_count <-_raw_spin_lock

bash-1977 [000] ...1 17284.993655: _raw_spin_unlock <-__close_fd

bash-1977 [000] ...1 17284.993656: sub_preempt_count <-_raw_spin_unlock

bash-1977 [000] .... 17284.993657: filp_close <-__close_fd

bash-1977 [000] .... 17284.993657: dnotify_flush <-filp_close

sshd-1974 [003] .... 17284.993658: sys_select <-system_call_fastpath

Universidad Nacional de la Matanza Sistemas Operativos

16

En esta salida podemos observar:

- El 1er campo es la tarea que ejecutó la función. - El 2do campo indica la latencia del CPU para esa tarea. - El 3er campo indica distintas banderas para IRQ´s. - El 4to campo se indica el tiempo en el cual fue ejecutada la función, en el formato

<segundos>.<microsegundos> - Por último se muestra el nombre de la función a la cual se le aplicó el trace en ese

instante. En base a la información obtenida del FTRACE y su formato para la función “function” (ya que loguearemos en el puerto serie todos los eventos del kernel), utilizaremos el siguiente formato de LOG con adaptaciones propias que más adelante se demostraran en la parte práctica: Fecha actual -> DD/MM/AAAA Hora actual -> HH:MM:SS Tipo de LOG -> aquí se muestra el tipo de LOG que representa el evento. Por ejemplo: 1024 -> “Inicialización de reloj realizada”. Estos mensajes no son de texto, sino que están representados por potencias de 2, que representan la clasificación de LOG’s que implementamos y que más adelante se explicará. Evento -> Se muestra el evento logueado LOG: 19/11/2013 | 21:23:33 | 1024 | Se cargó la distribución del teclado

Fecha Hora T. Log Evento

Universidad Nacional de la Matanza Sistemas Operativos

17

4. Práctica

Driver del puerto COM – Funciones de inicialización, transmisión y recepción – Manejos de Interrupciones - Polling

Como se comentó en la introducción teórica, se necesitó crear el driver del puerto COM para poder manejar la comunicación serie. El mismo se encuentra en el Kernel del SODIUM y está compuesto por los archivos com.h (dentro de la carpeta kernel/include/) y com.c (dentro de la carpeta /kernel). A continuación se explicará el funcionamiento del driver junto con el código fuente que los demuestra: COM.H

Definimos los puertos COM con sus registros correspondientes, ya sea que usemos el puerto COM1 o COM2:

#define PORT_COM1 0x3f8

#define PORT_COM2 0x2f8

El offset que se define a continuación su sumará al registro base definido anteriormente, para sumarlo y obtener los registros de interrupciones que vamos a utilizar:

#define PORT_COM_DATA 0

#define PORT_COM_IER 1

#define PORT_COM_IIR 2

#define PORT_COM_LCR 3

#define PORT_COM_MCR 4

#define PORT_COM_LSR 5

#define PORT_COM_MSR 6

#define PORT_COM_LCR_FRAMING_SET_8O1 11

#define PORT_COM_LCR_FRAMING_SET_7O1 10

#define PORT_COM_LCR_FRAMING_SET_8E1 27

#define PORT_COM_LCR_FRAMING_SET_7E1 26

#define PORT_COM_LCR_FRAMING_SET_8N1 3

#define PORT_COM_LCR_FRAMING_SET_7N1 2

#define PORT_COM_LCR_FRAMING_SET_8O2 15

#define PORT_COM_LCR_FRAMING_SET_7O2 14

#define PORT_COM_LCR_FRAMING_SET_8E2 31

#define PORT_COM_LCR_FRAMING_SET_7E2 30

Mascaras para comparar registro LCR

#define MASK_PORT_COM_LCR_PARITY_MODE 207

#define MASK_PORT_COM_LCR_PARITY_ENABLED 247

#define MASK_PORT_COM_LCR_STOP_BIT 251

#define MASK_PORT_COM_LCR_WORD_LENGTH 252

Seteos registro LCR

#define PORT_COM_LCR_FRAMING_SET_8O1 11

#define PORT_COM_LCR_FRAMING_SET_7O1 10

#define PORT_COM_LCR_FRAMING_SET_8E1 27

#define PORT_COM_LCR_FRAMING_SET_7E1 26

Universidad Nacional de la Matanza Sistemas Operativos

18

#define PORT_COM_LCR_FRAMING_SET_8N1 3

#define PORT_COM_LCR_FRAMING_SET_7N1 2

#define PORT_COM_LCR_FRAMING_SET_8O2 15

#define PORT_COM_LCR_FRAMING_SET_7O2 14

#define PORT_COM_LCR_FRAMING_SET_8E2 31

#define PORT_COM_LCR_FRAMING_SET_7E2 30

#define PORT_COM_LCR_BRDLatch 128

Valores para máscaras de bits pertenecientes a cada registro definido de interrupciones (MSR, IIR, IER, etc…):

#define COM_STOP_BITS1 0

#define COM_STOP_BITS2 1<<2

#define COM_WORD_LENGTH5 0

#define COM_WORD_LENGTH6 1

#define COM_WORD_LENGTH7 2

#define COM_WORD_LENGTH8 3

#define COM_PARITY_OFF 0

#define COM_PARITY_ON 1<<3

#define COM_PARITY_ODD 0

#define COM_PARITY_EVEN 16

#define COM_PARITY_1 32

#define COM_PARITY_0 48

Definimos las opciones para que el puerto funcione con interrupciones o polling.

#define COM_INTERRUPT_MODE 0

#define COM_POLLING_MODE 1

También definimos la velocidad, en baudios, que vamos a utilizar para la comunicación:

#define COM_BAUDS 9600

Universidad Nacional de la Matanza Sistemas Operativos

19

Se definen las funciones que utilizaremos en com.c y que se explicarán más adelante:

// Inicializacion

u8 bFnInicializarCom(int port, int flags);

// Estado

int bFnTerminalConectado(int port);

int iFnEstadoPuerto(int port);

void vFnSetEstadoPuerto(int port, unsigned char status);

void SetUsoParidad(int port, int parityStatus);

void SetModoParidad(int port, int parityMode);

void SetBitsParada(int port, int bits);

int SetBaudios(int port, int bauds);

void SetLargoPalabra(int port, int wordLength);

// Transferencia

void vFnComRecibirBuffer(int iPuerto, unsigned char *buffer, int

iMaxTamanio, int * piTamanio);

void vFnComRecibirBufferPolling(int iPuerto, unsigned char *buffer, int

iMaxTamanio, int * piTamanio);

void vFnComRecibirBufferIRQ(int iPuerto, unsigned char *buffer, int

iMaxTamanio, int * piTamanio);

void vFnComEnviarBuffer(int iPuerto, unsigned char *buffer, int iTamanio);

void vFnComEnviarBufferPolling(int iPuerto, unsigned char *buffer, int

iTamanio);

void vFnComEnviarBufferIRQ(int iPuerto, unsigned char *buffer, int

iTamanio);

void vFnLeerByteCom(int port);

void vFnEscribirByteCom(int port, unsigned char byte);

// Handler de interrupciones

void ISRCOMC(int port);

Universidad Nacional de la Matanza Sistemas Operativos

20

COM.C

En este archivo definimos el funcionamiento del driver:

Función bFnInicializarCom(int iPuerto, int iFlags): inicializa lo índices de los buffers de recepción y emisión, setea la velocidad de transmisión del puerto y otros parámetros de la misma como: modo de paridad, bits de parada, etc.

o Para setear los baudios de transmisión, se debe colocar el 8 bit del registros LSR en 0 y luego habilitar el LATCH DIVISOR.

o Luego, colocar la parte baja del valor del divisor en el puerto COM y la parte alta en el registro IIR del mismo.

o Se habilita las interrupciones por el COM1 en el 1er PIC. o Se agregó un manejador de interrupciones en la IDT en base a como estaba

hecho el controlador del floppy

Función vFnComRecibirBufferPolling(int iPuerto, unsigned char *buffer, int iMaxTamanio, int * piTamanio): setea el estado del puerto para poder recibir en modo polling y también manipula los buffers de información durante la recepción de datos.

o En modo polling, la función queda a la espera de recibir un dato por lo que se controla el estado del registro LSR chequeando que esté activo el bit de recepción.

Función vFnComRecibirBufferIRQ(int iPuerto, unsigned char *buffer, int iMaxTamanio, int * piTamanio): setea el estado del puerto para poder recibir en modo interrupciones y también manipula los buffers de información durante la recepción de datos.

o En modo interrupciones, la función queda en espera activa de recibir un dato. La recepción también es manejada en este caso por el manejador (handler) de interrupciones que se explica más abajo.

Función vFnComEnviarBufferPolling(int iPuerto, unsigned char *buffer, int iTamanio): setea el estado del puerto para poder transmitir en modo polliing y también manipula los buffers de información durante el envío de datos.

o Cheque el registro LSR para controlar el estado de la línea y setear el mismo para poder enviar datos.

Función vFnComEnviarBufferIRQ(int iPuerto, unsigned char *buffer, int

iTamanio): setea el estado del puerto para poder transmitir en modo interrupciones y también manipula los buffers de información durante el envío de datos.

o Nuevamente en este caso, se realiza una espera activa mientras se envían datos. La transmisión también es manejada en este caso por el manejador (handler) de interrupciones que se explica más abajo.

Función vFnLeerByteCom(int iPuerto): lee un byte del puerto y lo guarda en el buffer de lectura.

Función vFnEscribirByteCom(int iPuerto, unsigned char byte): Escribe un byte en el puerto para su posterior tratamiento.

Universidad Nacional de la Matanza Sistemas Operativos

21

Función SetBaudios(int iPuerto, int iBaudios): Setea la velocidad del puerto a

una velocidad dada en baudios, se corrige el valor de velocidad a uno válido y operable.

Función vFnSetEstadoPuerto(int iPuerto, unsigned char cEstado): Seteamos el registro correspondiente al puerto con el valor del estado(status) recibido como parámetro.

Función iFnEstadoPuerto(int iPuerto): Obtiene el estado del puerto leyendo el registro y luego devuelve el valor obtenido .

Función ISRCOMC(int port): se realiza el manejo de las interrupciones, leyendo el registro IIR(Registro de identificación de interrupciones) determinando el tipo de atención que se debe realizar:

o Estados del registro IIR:

Si es = 2 -> el puerto está listo para transmitir Si es = 4 -> el puerto está listo para recibir Si es = 6 -> indica que hubo un error en la línea

Universidad Nacional de la Matanza Sistemas Operativos

22

Customización del LOG:

Se modificó la función vFnLog(…) para que la misma pueda loguear siguiendo un formato y además hacerlo tanto sobre el puerto E9 (creado por Bochs para simular el puerto serie; todo lo que se imprime en dicho puerto, se verá reflejado en la consola del debugger) como en el puerto serie propiamente dicho. El funcionamiento del log será realizado por una macro que verificará inicialmente que esté activado el modo de LOGUEAR. A su vez cada punto de logueo tiene asociada una categoría de log (por ejemplo LOG_CATEGORIA_ERROR, LOG_CATEGORIA_TECLADO, etc.) que están definidas en el archivo log.h y se loguearán aquellos puntos que tengan la categoría y el modo de logueo activados. LOG.H

Definición de activación del logueo:

//es el principal define, si es 0 no loguea

#define LOGUEAR 1

Definición de categorías:

//categorías

#define LOG_CATEGORIA_MEMORIA 1<<1

#define LOG_CATEGORIA_HEAP 1<<2

#define LOG_CATEGORIA_PAGINACION 1<<3

#define LOG_CATEGORIA_PAGEFAIL 1<<4

#define LOG_CATEGORIA_PCI 1<<5

#define LOG_CATEGORIA_USB 1<<6

#define LOG_CATEGORIA_SYSCALL 1<<7

#define LOG_CATEGORIA_ES 1<<8

#define LOG_CATEGORIA_PCI 1<<9

#define LOG_CATEGORIA_FDD 1<<10

#define LOG_CATEGORIA_LECTURA 1<<11

#define LOG_CATEGORIA_ESCRITURA 1<<12

#define LOG_CATEGORIA_APM 1<<13

#define LOG_CATEGORIA_INICIALIZACION 1<<14

#define LOG_CATEGORIA_ERROR 1<<15

#define LOG_CATEGORIA_CONTROL 1<<16

#define LOG_CATEGORIA_PLANIFICADOR 1<<17

#define LOG_CATEGORIA_SYSTEM 1<<18

#define LOG_CATEGORIA_EVENTO 1<<19

#define LOG_CATEGORIA_TECLADO 1<<20

#define LOG_CATEGORIA_FAT12 1<<21

Ejemplo de la macro de log en el driver del teclado (teclado.c):

#if LOGUEAR && (LOG_CATEGORIA_TECLADO |

LOG_CATEGORIA_INICIALIZACION)

vFnLog(LOG_CATEGORIA_TECLADO | LOG_CATEGORIA_INICIALIZACION,

"Se cargo la distribucion de teclado \"%s\"",

(pstuPosMemoriaKeymap)->sNombre);

#endif

La macro verifica que LOGUEAR sea 1 y además que las categorías estén activas. Utilizamos la metodología de definir cada categoría como una potencia de 2 en el header (#define LOG_CATEGORIA_TECLADO 1<<20), para que un log pueda tener más de una categoría al

Universidad Nacional de la Matanza Sistemas Operativos

23

realizar la operación lógica "|". De esa manera enviamos en un número de 32 bits a lo sumo, la proveniencia del mensaje de logueo. Y además pudiendo lograr que sólo se envíen logs de determinadas categorías (las que estén activas). Los parámetros que recibe la función: void vFnLog(int iPropiedades, const char *cnstCadena, ...)

son:

la/s categoría/s del LOG el mensaje que se está logueando los parámetros del mensaje

Esta función se encuentra en /kernel/interfaz/consola.c

En esta función se setea una variable del tipo char * llamada formato, la cual va a contener el formato fijo definido por nosotros:

formato = "LOG - fecha | propiedades | mensaje\n”

Usando las funciones para leer el reloj del Sodium, obtenemos fecha y hora para usar en el LOG:

pcFnObtenerFechaYHoraActual();

Enviamos la cadena actual de logueo al puerto simulado e9 y al puerto serie, previamente habiendo completado la cadena con el mensaje del evento:

iFnImprimirCadenaE9(0, strAux1);

//puerto serie

vFnComEnviarBuffer(PORT_COM1 + PORT_COM_DATA, strAux1,

iLongitudCadena);

Posteriormente, y a modo de ejemplo, en ambos puertos(e9 y serie) llega el siguiente

LOG con los valores que obtuvo la función para el evento generado en este caso por el teclado:

LOG: 19/11/2013 | 21:23:33 | 1024 | Se cargó la distribución del teclado

Fecha Hora T. Log Evento

Universidad Nacional de la Matanza Sistemas Operativos

24

Comando para testeo de la conexión serie

Implementamos el comando pr_serie, el cual ejecuta un test de la conexión permitiendo enviar y recibir datos a través del puerto COM haciendo uso de las funcionalidades programadas. El mismo se ejecuta en modo polling o con interrupciones, según el seteo que se haya realizado en la configuración. Actualmente está seteado para funcionar con interrupciones.

Solución a problemas de estabilidad

Para solucionar los problemas de estabilidad tuvimos que eliminar la habilitación de interrupciones al iniciar el Sodium en el archivo /kernel/main.c ya que esto estaba haciendo que de forma aleatoria el Sistema Operativo arranque algunas veces sí y otras fallaba en este punto, esto solo ocurría al correr el Sistema Operativo Sodium en una maquina real. Las líneas que tuvimos que eliminar son las siguientes:

vFnImprimir ("\nHabilitando Interrupciones ... ");

asm("sti");

Universidad Nacional de la Matanza Sistemas Operativos

25

Configuración del SODIUM para poder utilizar el puerto serie dentro del mismo ordenador, usando la VM y la máquina real.

Para poder utilizar el puerto Serie dentro del mismo ordenador, debemos como 1er paso configurar el archivo generar_lanzador.sh dentro de la carpeta /SODIUM/herramientas:

com1: enabled=1, mode=socket-server, dev="0.0.0.0:12345"

Esta configuración habilita el puerto COM1 usando el socket como server y permitiendo conectar a todas aquellas IP’s que se conecten al puerto “0.0.0.0:12345(puerto)” (el puerto lo setea uno mismo con el valor deseado, en nuestro caso usamos el que se muestra de ejemplo). Luego debemos obtener la IP del nuestra VM. Para eso ejecutamos el comando ifconfig y nos copiamos la ip que luego vamos a usar para configurar la terminal en la máquina real. Una vez realizado lo anterior, dentro de la maquina real debemos tener instalado algún programa que simule terminales. En este caso usaremos como ejemplo el PuTTY, y se describirán los pasos para configurar el mismo:

A. Abrir el PuTTY. Se obtiene la siguiente pantalla principal:

Universidad Nacional de la Matanza Sistemas Operativos

26

B. Copiar la IP obtenida en la VM, setear el puerto “12345” y tildar la opción “Raw”

Universidad Nacional de la Matanza Sistemas Operativos

27

C. Ir al menú “Terminal”, tildar las opciones como se muestra en la captura y dejar en blanco “Answer back…” para que se puedan visualizar los caracteres “basura” cuando se está recibiendo:

Universidad Nacional de la Matanza Sistemas Operativos

28

D. Volver al menú principal “Session”, guardar la configuración( “Save”) con el nombre deseado y presionar “Open” para abrir la terminal:

E. Por último, ejecutamos el SODIUM en la VM. Se pueden ver los resultados de la conexión con el puerto serie:

o Podemos observar que durante la inicialización del SODIUM, se enviaron a través del puerto serie eventos de LOG hacía la terminal del PuTTY.

Universidad Nacional de la Matanza Sistemas Operativos

29

Distintas formas de configurar el puerto serie 1) Ejecutamos el script “configurar.sh” que se encuentra dentro de la carpeta fuente con el

resto del codigo. Nos aparecerá el siguiente menú:

2) Elegimos la opción 5 que es “Configuración de puerto serie”. En donde podemos elegir el

puerto (Com1 o Com2), el modo de operación del puerto (Polling o Interrupciones), y la velocidad de transmisión medida en baudios que deseamos. En este ejemplo elegimos la opción de usar el puerto com 1 con Pooling.

Universidad Nacional de la Matanza Sistemas Operativos

30

3) Luego elegimos la velocidad de transmisión que deseamos para nuestra conexión,

eligiendo la opción 6 “settear velocidad” del menú anterior, una vez dentro elegimos la opción que deseamos, en este ejemplo elegimos 4800 baudios.

Una vez elegida la velocidad presionamos la “x” para volver al menú anterior. Donde salimos presionando nuevamente “x” y volviendo al menú principal donde guardamos los cambios y salimos de la configuración de sodium. Una vez guardados los cambios compilamos el código del Sodium y podremos usar la configuración que seteamos en el menú para nuestro puerto serie.

Universidad Nacional de la Matanza Sistemas Operativos

31

5. Conclusiones

Las primeras dificultades encontradas en este trabajo práctico fueron la de comprender como estaba estructurado el SODIUM y la realización de programas dentro del kernel del mismo. Esto se debe además a que cada trabajo o grupo está enfocado en una funcionalidad particular del sistema. En segundo lugar fue necesario investigar y aprender sobre el funcionamiento de la conexión serie y la estructura de la UART junto con los registros que esta maneja, para luego poder construir el driver. Luego hubo que implementar un formato de LOG acorde a lo investigado sobre el FTRACE y a las herramientas que nos brindó SODIUM para obtener y chequear los eventos del sistema. Además debimos tomar decisiones sobre algunas partes específicas del manejo de la UART en base a la información que obtuvimos de fabricantes de componentes electrónicos, los cuales agregamos en la bibliografía. Entendemos la complejidad que representa un sistema operativo e incorporar nuevas funcionalidades, si además pensamos que cada equipo se debe enfocar en algo en particular y no va a tener la posibilidad de comprender todo el funcionamiento en sí. Esto no quita que no se tenga un enfoque general sobre el sistema SODIUM y sus funcionalidades, que hacen al conjunto y aportaron a la realización en nuestro caso de la comunicación serie. En resumen, hemos aprendido muchas cosas durante la realización de este trabajo práctico, aunque nos faltan por aprender muchas otras y hemos podido analizar muchos de los aspectos principales del SODIUM y comprender su funcionamiento. Creemos que esta experiencia fue positiva, y sobre todo, entendimos la complejidad de los sistemas operativos y pudimos poner en práctica muchos de los conocimientos teóricos que poseíamos sobre los mismos.

6. Mejoras que se deberían aplicar a futuro para un mejor funcionamiento del puerto serie.

Nosotros consideramos que se debería aplicar algún tipo de control de flujo para la comunicación serie debido a que no se está utilizando ninguno y esto puede producir perdida de información. Además sería interesante la utilización del FIFO Control Register (FCR) que nos da la opción de enviar determinada cantidad de bytes a través del puerto serie y que estas cantidades puedan ser seteadas desde el SODIUM.

Universidad Nacional de la Matanza Sistemas Operativos

32

7. BIBLIOGRAFÍA/REFERENCIAS

http://docente.ucol.mx/al960347/public_html/serie.htm http://wiki.osdev.org/Serial_Ports http://es.wikipedia.org/wiki/Universal_Asynchronous_Receiver-Transmitter http://en.wikipedia.org/wiki/Serial_port#Parity http://digital.ni.com/public.nsf/allkb/2AD81B9060162E708625678C006DFC62 http://gilzu.com/?p=6 http://digital.ni.com/public.nsf/allkb/3BDC7FF03541F772862564990057F919 http://flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/CH22.PDF http://www.scribd.com/doc/57894869/DTE-y-DCE [1] - http://perso.wanadoo.es/pictob/comserie.htm#la_norma_rs232 [2] - http://www.mosaic-industries.com/Manuals/UAM/ [2] - http://www.keil.com/forum/12050/