Могу ли я использовать протокол xmodem с PySerial?
У меня есть рабочее соединение с моим последовательным устройством через PySerial, но я также хочу передавать файлы по протоколу xmodem как часть моей программы.
Какой способ сделать это наиболее нейтральным с точки зрения платформы? В худшем случае я мог close()
мой serial.Serial
объект в Python и использовать subprocess
призвать /usr/bin/sb
, но это кажется не элегантным.
В настоящее время я использую Ubuntu 9.10 и использую адаптер USB-TTY.
Есть идеи?
3 ответа
На 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 в Python. Возможно, вы могли бы использовать это, или идеи из других ответов там.