我可以在PySerial中使用xmodem协议吗?

2024-06-08 19:21:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我通过PySerial与我的串行设备建立了工作连接,但作为程序的一部分,我还希望通过xmodem协议传输文件。

哪种方法最适合平台中立?最糟糕的情况是,我可以在Python中使用close()我的serial.Serial对象并使用subprocess来调用/usr/bin/sb,但这似乎不雅。

我目前在Ubuntu9.10上,正在使用USB-TTY适配器。

有什么想法吗?


Tags: 文件对象方法程序协议closebinusr
3条回答

使用PyPi上的XMODEM协议实现非常简单。关于上面的例子,需要注意的是有些东西是不需要的。(这可能对作者有用,也可能对模块的以前版本有用?)

文档found here非常有用,所以不要让它吓到你。显然,您需要一个发送者和一个接收者,由于我不知道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)

这里的关键是确保波特率设置在两边(这里是默认值)。不要添加任何延迟或睡眠,因为这不是基于时间的,而是基于事务的。打印将允许您在数据流入或流出文件/串行端口时实时查看事务。

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协议的细节,但是有一个人回答了xmodem-for-python问题,他甚至在Python中提供了xmodem的粗略实现。也许你可以用这个,或者其他人的想法来回答。

相关问题 更多 >