Могу ли я использовать протокол Xmodem с Pyserial?
Вопрос
У меня есть рабочее соединение с моим последовательным устройством через Pyserial, но я также хочу перенести файлы через протокол Xmodem в рамках моей программы.
Что было бы наиболее нейтральным платформой, чтобы сделать это? В худшем случае я мог close()
мой serial.Serial
объект в питоне и использовать subprocess
призывать /usr/bin/sb
, но это кажется неэлегантным.
В настоящее время я нахожусь на Ubuntu 9.10 и использую адаптер USB-TTY.
Любые идеи?
Решение
На PYPI есть модуль Xmodem. Требуется две функции в конструкторе для чтения и написания данных, реализуйте их для работы с вашим открытым последовательным портом. Ниже проста его использования:
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()
Другие советы
Супер просто использовать реализацию протокола Xmodem, найденную на PYPI. Несколько вещей, на которые следует отметить пример выше, это то, что есть некоторые вещи, которые не нужны. (Может быть, это сработало для автора или с предыдущей версией модуля?)
Документация найдено здесь чрезвычайно полезен, так что не позволяйте этому пугать вас. Очевидно, вам понадобится отправитель и приемник, и, поскольку я не знаю, какой из них будет сценарий Python, вот два примера, которые я протестировал и работаю ниже. (в основном копируется и вставлен из примеров на 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)
Получить с серийного устройства:
stream = open('output', 'wb')
modem.recv(stream, crc_mode=0)
Отправить на серийное устройство:
stream = open('input', 'rb')
modem.send(stream)
Ключ здесь состоит в том, чтобы убедиться, что скорость передачи передачи задач с обеих сторон (здесь не дефолт). Не добавляйте никакой задержки или сна, так как это не основано на времени, а на транзакции. Отпечатки позволят вам увидеть транзакцию в реальном времени, когда данные течет в файле/последовательном порту или выходят из файла.
Я не знаком с деталями протокола Xmodem, но один человек отвечает Xmodem-for-Python Вопрос, по -видимому, и даже предоставил то, что похоже на грубую реализацию Xmodem в Питон. Возможно, вы могли бы использовать это или идеи из других ответов там.