Pergunta

Eu tenho uma conexão de trabalho com meu dispositivo serial via Pyseial, mas também quero transferir arquivos através do protocolo XMODEM como parte do meu programa.

Qual seria a maneira mais neutra de plataforma de fazer isso? Na pior das hipóteses, eu poderia close() minha serial.Serial objeto em python e uso subprocess para chamar /usr/bin/sb, mas isso parece deselegante.

Atualmente, estou no Ubuntu 9.10 e estou usando um adaptador USB-TTY.

Alguma ideia?

Foi útil?

Solução

Há módulo Xmodem no Pypi. São necessárias duas funções no construtor para ler e escrever dados, implemente -os para trabalhar com sua porta serial aberta. Abaixo está a amostra simples de seu 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()

Outras dicas

É super simples usar a implementação do protocolo XMODEM encontrada no PYPI. Algumas coisas a serem observadas sobre o exemplo acima é que existem algumas coisas que não são necessárias. (Talvez isso tenha funcionado para o autor ou com uma versão anterior do módulo?)

A documentação encontrado aqui é extremamente útil, então não deixe que isso o assuste. Você precisará de um remetente e um receptor, obviamente, e como não sei qual será o script Python, aqui estão dois exemplos que testei e estão funcionando abaixo. (basicamente copiado e colado a partir dos exemplos no 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 receber do dispositivo serial:

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

Para enviar para o dispositivo serial:

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

A chave aqui é garantir que a taxa de transmissão seja definida de ambos os lados (inadimplente aqui). Não adicione nenhum atraso ou sono, pois não é baseado no tempo, mas baseado em transações. As impressões permitirão que você veja a transação em tempo real à medida que os dados fluem dentro ou fora da porta de arquivo/serial.

Não estou familiarizado com os detalhes do protocolo Xmodem, mas uma pessoa respondendo ao xmodem-for python A pergunta parece ser e até forneceu o que parece ser uma implementação grosseira do Xmodem dentro Pitão. Talvez você possa usar isso, ou idéias de outras respostas lá.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top