سؤال

لدي اتصال عمل مع جهازي المسلسل عبر Pyserial، لكني أرغب أيضا في نقل الملفات عبر بروتوكول XMODEM كجزء من برنامجي.

التي ستكون الطريقة الأكثر محايدة منصة للقيام بذلك؟ أسوأ الحالات، أستطيع close() لي serial.Serial كائن في بيثون واستخدام subprocess دعوة /usr/bin/sb, ، ولكن هذا يبدو مذهلا.

أنا حاليا على Ubuntu 9.10 و أنا باستخدام محول USB TTY.

أيه أفكار؟

هل كانت مفيدة؟

المحلول

هناك وحدة XMODEM على Pypi. يستغرق الأمر وظيفتين في منشئ بيانات القراءة والكتابة، وتنفيذها للعمل مع منفذك التسلسلي الذي تم فتحه. أدناه هي عينة بسيطة من استخدامها:

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 في بيثون. ربما يمكنك استخدام ذلك، أو الأفكار من الإجابات الأخرى هناك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top