我可以将 xmodem 协议与 PySerial 一起使用吗?

Posted

技术标签:

【中文标题】我可以将 xmodem 协议与 PySerial 一起使用吗?【英文标题】:Can I use the xmodem protocol with PySerial? 【发布时间】:2009-12-02 16:50:07 【问题描述】:

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

哪种方式最不依赖于平台?最坏的情况,我可以在 Python 中使用close() 我的serial.Serial 对象并使用subprocess 调用/usr/bin/sb,但这似乎不优雅。

我目前使用的是 Ubuntu 9.10,并且正在使用 USB-TTY 适配器。

有什么想法吗?

【问题讨论】:

您需要发送或接收还是两者都需要? 我只想转发。 【参考方案1】:

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()

【讨论】:

【参考方案2】:

使用 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)

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

【讨论】:

看起来它期待一个文件被发送 stream = open('input', 'rb') modem.send(stream) 对吗?如果您只想发送一个简单的字符串,例如“Hello World”,该怎么办?【参考方案3】:

我不熟悉 xmodem 协议的细节,但回答 xmodem-for-python 问题的人似乎是,甚至提供了看起来像 xmodem 的粗略实现in Python .也许您可以使用它,或者那里其他答案的想法。

【讨论】:

嗯,那里的提问者想从传感器设备接收;您提到的答案是 SENDING 的粗略实现。

以上是关于我可以将 xmodem 协议与 PySerial 一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

xmodem 协议恢复交换机

XModem协议

用Xmodem传送文件为啥总是出现系统无响应

XModem与YModem

Android 固件升级之 Xmodem

Ymodem协议详解