Pregunta

Necesito probar una aplicación de puerto serie en Linux; sin embargo, mi máquina de prueba solo tiene un puerto serie.

¿Existe alguna manera de agregar un puerto serie virtual a Linux y probar mi aplicación emulando un dispositivo a través de un shell o script?

Nota:No puedo reasignar el puerto, está codificado en ttys2 y necesito probar la aplicación tal como está escrita.

¿Fue útil?

Solución

Puede utilizar un pty ("pseudoteletipo", donde un puerto serie es un "teletipo real") para esto.Desde un extremo, abierto /dev/ptyp5, y luego adjunte su programa a /dev/ttyp5; ttyp5 actuará como un puerto serie, pero enviará/recibirá todo lo que haga a través de /dev/ptyp5.

Si realmente lo necesita para hablar con un archivo llamado /dev/ttys2, luego simplemente mueve tu viejo /dev/ttys2 fuera del camino y haga un enlace simbólico desde ptyp5 a ttys2.

Por supuesto que puedes usar algún número que no sea ptyp5.Quizás elija uno con un número alto para evitar duplicados, ya que todos sus terminales de inicio de sesión también usarán ptys.

Wikipedia tiene más información sobre ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

Otros consejos

Complementando la respuesta de @slonik.

Puede probar socat para crear un puerto serie virtual realizando el siguiente procedimiento (probado en Ubuntu 12.04):

Abra una terminal (llamémosla Terminal 0) y ejecútela:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

El código anterior devuelve:

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]

Abra otra terminal y escriba (Terminal 1):

cat < /dev/pts/2

El nombre del puerto de este comando se puede cambiar según la PC.Depende de la salida anterior.

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs 

debe utilizar el número disponible en el área resaltada.

Abra otra terminal y escriba (Terminal 2):

echo "Test" > /dev/pts/3

Ahora regrese a la Terminal 1 y verá la cadena "Prueba".

Utilice socat para esto:

Por ejemplo:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

También hay tty0tty http://sourceforge.net/projects/tty0tty/ que es un emulador de módem nulo real para Linux.

Es un módulo del kernel simple: un pequeño archivo fuente.No sé por qué solo recibió el visto bueno en Sourceforge, pero a mí me funciona bien.Lo mejor de esto es que también emula los pines del hardware (RTC/CTS DSR/DTR).¡Incluso implementa los comandos TIOCMGET/TIOCMSET y TIOCMIWAIT iotcl!

En un kernel reciente, es posible que obtenga errores de compilación.Esto es fácil de arreglar.Simplemente inserte algunas líneas en la parte superior de la fuente del módulo/tty0tty.c (después de incluye):

#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif

Cuando se carga el módulo, crea 4 pares de puertos serie.Los dispositivos son /dev/tnt0 a /dev/tnt7 donde tnt0 está conectado a tnt1, tnt2 está conectado a tnt3, etc.Es posible que deba corregir los permisos de los archivos para poder utilizar los dispositivos.

editar:

Supongo que fui un poco rápido con mi entusiasmo.Si bien el conductor parece prometedor, parece inestable.No lo sé con seguridad, pero creo que se estrelló una máquina en la oficina en la que estaba trabajando desde casa.No puedo comprobarlo hasta que vuelva a la oficina el lunes.

Lo segundo es que TIOCMIWAIT no funciona.El código parece haber sido copiado de algún código de ejemplo "tiny tty".El manejo de TIOCMIWAIT parece estar en su lugar, pero nunca se activa porque falta la llamada correspondiente a wake_up_interruptible().

editar:

El accidente en la oficina realmente fue culpa del conductor.Faltaba una inicialización y el código TIOCMIWAIT, que no había sido probado en absoluto, provocó un fallo de la máquina.

Pasé ayer y hoy reescribiendo el controlador.Hubo muchos problemas, pero ahora me funciona bien.Todavía falta código para el control de flujo de hardware administrado por el controlador, pero no lo necesito porque administraré los pines yo mismo usando TIOCMGET/TIOCMSET/TIOCMIWAIT desde el código del modo de usuario.

Si alguien está interesado en mi versión del código, envíeme un mensaje y se lo enviaré.

Quizás quieras mirar Tibbo VSPDL para crear un puerto serie virtual de Linux usando un controlador Kernel; parece bastante nuevo y está disponible para descargar ahora mismo (versión beta).No estoy seguro de la licencia en este momento, o si quieren que esté disponible comercialmente solo en el futuro.

Existen otras alternativas comerciales, como http://www.ttyredirector.com/.

En código abierto, reserial (GPL) también puede hacer lo que quiera, utilizando Unix PTY.Transmite los datos en serie en "forma cruda" a un socket de red;Se debe realizar una configuración similar a STTY de los parámetros del terminal al crear el puerto; no parece que se admita cambiarlos más adelante como se describe en RFC 2217.Debería poder ejecutar dos instancias remserial para crear un módem nulo virtual como com0com, excepto que necesitará configurar la velocidad del puerto, etc. de antemano.

Socat (también GPL) es como una variante extendida de Remserial con muchas más opciones, incluido un método "PTY" para redirigir el PTY a otra cosa, que puede ser otra instancia de Socat.Para Unit tets, socat probablemente sea mejor que remserial porque puede cat archivos directamente en el PTY.Ver el Ejemplo de PTY en la página de manual.A parche existe en "contrib" para proporcionar soporte RFC2217 para negociar la configuración de la línea serie.

Usando los enlaces publicados en las respuestas anteriores, codifiqué un pequeño ejemplo en C++ usando un puerto serie virtual.Envié el código a GitHub: https://github.com/cymait/virtual-serial-port-example .

El código se explica por sí mismo.Primero, crea el proceso maestro ejecutando ./main master y se imprimirá en el archivo estándar que está utilizando el dispositivo.Después de eso, invocas ./main Slave Device, donde dispositivo es el dispositivo impreso en el primer comando.

Y eso es.Tienes un vínculo bidireccional entre los dos procesos.

Usando este ejemplo puedes probar la aplicación enviando todo tipo de datos y ver si funciona correctamente.

Además, siempre puedes vincular simbólicamente el dispositivo, por lo que no necesitas volver a compilar la aplicación que estás probando.

¿Podrías utilizar un adaptador USB->RS232?Tengo algunos y solo usan el controlador FTDI.Luego, debería poder cambiar el nombre de /dev/ttyUSB0 (o ​​lo que sea que se cree) como /dev/ttyS2 .

Puedo pensar en tres opciones:

Implementar RFC 2217

RFC 2217 cubre un puerto de comunicación según el estándar TCP/IP que permite a un cliente en un sistema emular un puerto serie para los programas locales, mientras envía y recibe de forma transparente datos y señales de control a un servidor en otro sistema que realmente tiene el puerto serie.Aquí está un descripción general de alto nivel.

Lo que haría es encontrar o implementar un controlador de puerto com de cliente que implementaría el lado cliente del sistema en su PC, pareciendo ser un puerto serie real pero en realidad transfiriendo todo a un servidor.Es posible que pueda obtener este controlador de forma gratuita de Digi, Lantronix, etc. como soporte para sus servidores de puerto serie independientes reales.

Luego, implementaría el lado del servidor de la conexión localmente en otro programa, permitiendo al cliente conectarse y emitir los datos y los comandos de control según sea necesario.

Probablemente no sea trivial, pero el RFC está disponible y es posible que pueda encontrar un proyecto de código abierto que implemente uno o ambos lados de la conexión.

Modificar el controlador del puerto serie de Linux

Como alternativa, la fuente del controlador del puerto serie para Linux está disponible.Tome eso, destripe las piezas de control del hardware y haga que ese controlador ejecute dos puertos /dev/ttySx, como un simple loopback.Luego conecte su programa real al ttyS2 y su simulador al otro ttySx.

Utilice dos cables USB<-->Serial en un loopback

¿Pero lo más fácil de hacer ahora mismo?Gaste $40 en dos dispositivos USB con puerto serie, conéctelos (módem nulo) y tenga dos puertos serie reales: uno para el programa que está probando y otro para su simulador.

-Adán

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top