1

ユーザーアプリを作成している組み込みシステムがあります。ユーザー アプリは、ファームウェア イメージを取得し、プログラミングのために組み込みシステムに送信するのに適したチャンクに分割する必要があります。私は S レコード ファイルから始めて、ファイル転送に Xmodem を使用しています (つまり、主要な「ファイル」転送はそれぞれ EOF で終了する必要があります)。 (シングル スレッド) 組み込みシステムの受信バッファーのサイズ以下の完全な s レコードのセット ファイル。私のユーザーアプリはPythonで書かれており、ファームウェアイメージを適切なサイズのファイルに分割するCプログラムがありますが、おそらくカスタムストリームハンドラーを使用することで、これについてもっと「pythonic」な方法があるかもしれないと思いました。

何かご意見は?

編集:議論に追加するために、入力ファイルをバッファに入れることができます。range を使用して、ファイル サイズまたは完全な S レコード行 ('S' で区切られた ASCII テキスト) のバッファーに入るハード リミットを設定するにはどうすればよいですか?

4

2 に答える 2

0

すでに C プログラムをお持ちの場合は、幸運です。Python は、ほとんど同じ機能を持つ C 上のスクリプト言語のようなものです。よく知られているすべての CI/O 機能については、ストリームを操作するためのコア ツールを参照してください。次に、メソッドをクラスにまとめたり、 The Python Slice Notationなどを使用して、プログラムをより Pythonic にすることができます。

于 2013-06-11T14:45:40.107 に答える
0

これは興味深い質問であり、S レコード形式はそれほど複雑ではないと思ったので、限られたテストで動作するように見える S レコード エンコーダーを作成しました。

import struct

def s_record_encode(fileobj, recordtype, address, buflen):
    """S-Record encode bytes from file.

    fileobj      file-like object to read data (if any)
    recordtype   'S0' to 'S9'
    address      integer address
    buflen       maximum output buffer size
    """
    # S-type to (address_len, has_data)
    record_address_bytes = {
        'S0':(2, True), 'S1':(2, True), 'S2':(3, True), 'S3':(4, True),
        'S5':(2, False), 'S7':(4, False), 'S8':(3, False), 'S9':(2, False)
    }

    # params for this record type
    address_len, has_data = record_address_bytes[recordtype]

    # big-endian address as string, trimmed to length
    address = struct.pack('>L', address)[-address_len:]

    # read data up to 255 bytes minus address and checksum len
    if has_data:
        data = fileobj.read(0xff - len(address) - 1)
        if not data:
            return '', 0
    else:
        data = ''

    # byte count is address + data + checksum
    count = len(address) + len(data) + 1
    count = struct.pack('B', count)

    # checksum count + address + data
    checksummed_record = count + address + data
    checksum = struct.pack('B', sum(ord(d) for d in checksummed_record) & 0xff ^ 0xff)

    # glue record type to hex encoded buffer
    record = recordtype + (checksummed_record + checksum).encode('hex').upper()

    # return buffer and how much data we read from the file
    return record, len(data)



def s_record_test():
    from cStringIO import StringIO

    # from an example, this should encode to given string
    fake_file = StringIO("\x0A\x0A\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
    encode_to = "S1137AF00A0A0D0000000000000000000000000061"
    fake_file.seek(0)
    record, buflen = s_record_encode(fake_file, 'S1', 0x7af0, 80)
    print 'record', record
    print 'encode_to', encode_to
    assert record == encode_to

    fake_file = StringIO()
    for i in xrange(1000):
        fake_file.write(struct.pack('>L', i))
    fake_file.seek(0)

    address = 0

    while True:
        buf, datalen = s_record_encode(fake_file, 'S2', address, 100)
        if not buf:
            break
        print address, datalen, buf
        address += datalen
于 2013-06-12T14:44:14.727 に答える