Tengo una conexión que funciona con mi dispositivo en serie a través de PySerial, pero también quiero transferir archivos a través del protocolo xmodem como parte de mi programa.

¿Cuál sería la forma más neutral de plataforma para hacer esto? En el peor de los casos, podría close() mi objeto serial.Serial en Python y usar subprocess para invocar a /usr/bin/sb, pero eso parece poco elegante.

Actualmente estoy en Ubuntu 9.10 y estoy usando un adaptador USB-TTY.

¿Alguna idea?

2
lfaraone 2 dic. 2009 a las 19:50

3 respuestas

La mejor respuesta

Hay un módulo xmodem en PyPi. Toma dos funciones en el constructor para leer y escribir datos, impleméntelas para que funcionen con su puerto serie abierto. A continuación se muestra una muestra simple de su uso:

import serial
try:
    from cStringIO import StringIO
except:
    from StringIO import StringIO
from xmodem import XMODEM, CRC
from time import sleep

def readUntil(char = None):
    def serialPortReader():
        while True:
            tmp = port.read(1)
            if not tmp or (char and char == tmp):
                break
            yield tmp
    return ''.join(serialPortReader())

def getc(size, timeout=1):
    return port.read(size)

def putc(data, timeout=1):
    port.write(data)
    sleep(0.001) # give device time to send ACK


port = serial.Serial(port='COM5',parity=serial.PARITY_NONE,bytesize=serial.EIGHTBITS,stopbits=serial.STOPBITS_ONE,timeout=0,xonxoff=0,rtscts=0,dsrdtr=0,baudrate=115200)
port.write("command that loads data via xmodem\r\n")
sleep(0.02) # give device time to handle command
readUntil(CRC)
buffer = StringIO('data to send')
XMODEM(getc, putc).send(buffer, quiet = 1)
buffer.close()
readUntil()
4
Artem Zankovich 4 mar. 2011 a las 17:26

No estoy familiarizado con los detalles del protocolo xmodem, pero una persona respondió el xmodem-for-python la pregunta parece ser, e incluso ha proporcionado lo que parece una implementación cruda de xmodem en Python. Quizás podría usar eso, o ideas de otras respuestas allí.

0
Community 23 may. 2017 a las 12:07

Es muy simple usar la implementación del protocolo XMODEM que se encuentra en PyPi. Algunas cosas a tener en cuenta sobre el ejemplo anterior es que hay algunas cosas que no son necesarias. (¿Tal vez esto funcionó para el autor o con una versión anterior del módulo?)

La documentación que se encuentra aquí es extremadamente útil, así que no dejes que te asuste. Obviamente, necesitará un remitente y un receptor, y dado que no sé cuál será el script de Python, aquí hay dos ejemplos que he probado y que estoy trabajando a continuación. (básicamente copiado y pegado de los ejemplos en PyPi)

import serial
from xmodem import XMODEM

ser = serial.Serial(port='COM56')


def getc(size, timeout=8):
    gbytes = ser.read(size)
    print(f'Read Byte: {gbytes}')
    return gbytes or None


def putc(data, timeout=8):
    pbytes = ser.write(data)
    print(f'Put Byte: {pbytes}')
    return pbytes or None


if __name__ == '__main__':
    modem = XMODEM(getc, putc)

Para recibir del dispositivo en serie:

stream = open('output', 'wb')
modem.recv(stream, crc_mode=0)

Para enviar al dispositivo serie:

stream = open('input', 'rb')
modem.send(stream)

La clave aquí es asegurarse de que la velocidad en baudios esté establecida en ambos lados (por defecto aquí). NO agregue ningún retraso o suspensión ya que esto no se basa en el tiempo, sino en las transacciones. Las impresiones le permitirán ver la transacción en tiempo real a medida que los datos entran o salen del archivo / puerto serie.

2
thaGH05T 8 dic. 2018 a las 02:20