So-net無料ブログ作成
検索選択

Sレコードをバイナリに変換するプログラム [ColdFire V2]このエントリーを含むはてなブックマーク#

1990557

いよいよ、Sレコードからバイナリ・ファイル COLDFIRE.BIN を作成します。 あと、一歩だよ。

どこで誰がフォーマット変換するか

要するに、Sレコードを読み込んで、バイナリ・ファイルを作成してやれば良いのですが、この作業を誰にやらせるのかが、問題になります。 メモリが少ない環境で作成する場合には、Sレコードを一行ずつ呼んで、途中結果を逐一ファイルに書き出すことになると思います。 付録基板でプログラムを作成する場合にも、一行ずつ処理して、逐次FLASHに書き込むことになりますが、Sレコードの送受信でハンドシェイクが働くかどうかが心配です。

どうも、付録基板にやらせると、ハードルがいくつもありそうなので、まずは、PCでフォーマット変換する方法を考えました。 最近のPCで処理する場合には、Sレコードを全て読み込んで、主記憶上にメモリ・イメージを展開して、それを一気にファイルに書き出せば簡単です。 128kバイトのメモリなんて、十分小さいことでしょう。

じゃ~ん。フォーマット変換プログラム

というわけで、急ごしらえではありますが、フォーマット変換プログラムを作成しました。

size = 128*1024
offset = 128*1024
mem=[255 for x in xrange(0, size)]


def parse(line):
    if line[0] != 'S':
        return -1, []
    try:
        nibbles = [int(ch, 16) for ch in line[1:]]
    except ValueError:
        return -1, []
    type = nibbles[0]
    bytes = [(nibbles[i*2+1] * 16 + nibbles[i*2+2])
             for i in xrange(0, len(nibbles) / 2)
            ]
    if bytes[0] != len(bytes) - 1:
        return -1, []
    csum = sum(bytes) & 255
    if csum != 255:
        return -1, []
    return type, bytes[1:-1]

def type0(payload):
    print "".join([chr(ch) for ch in payload[2:]])

def write(address, data):
    address -= offset
    for x in data:
#        print "WRITE %02X to %08X" % (x, address)
        if address < 0:
            return False
        if address >= size:
            return False
        mem[address] = x
        address = address + 1
    return True

def type1(payload):
    address = payload[0] * 256 + payload[1]
    return write(address, payload[2:])
    
def type2(payload):
    address = (payload[0] * 256 + payload[1]) * 256 + payload[2]
    return write(address, payload[3:])

def type3(payload):
    address = ((payload[0] * 256 + payload[1]) * 256 + payload[2]) * 256 + payload[3]
    return write(address, payload[4:])

def type5(payload):
    return True

def type7(payload):
    address = ((payload[0] * 256 + payload[1]) * 256 + payload[2]) * 256 + payload[3]
    print "Entry Point=%08X" % address
    return True

def type8(payload):
    address = (payload[0] * 256 + payload[1]) * 256 + payload[2]
    print "Entry Point=%06X" % address
    return True

def type9(payload):
    address = payload[0] * 256 + payload[1]
    print "Entry Point=%04X" % address
    return True

def loadLine(line):
    if not line:
        return True
    (type, payload) = parse(line)
    if type == 0:
        return type0(payload)
    elif type == 1:
        return type1(payload)
    elif type == 2:
        return type2(payload)
    elif type == 3:
        return type3(payload)
    elif type == 5:
        return type5(payload)
    elif type == 7:
        return type7(payload)
    elif type == 8:
        return type8(payload)
    elif type == 9:
        return type9(payload)
    else:
        print "INVALID: %s\n" % line
        return False

def loadFile(fileName):
    mem=[255 for x in xrange(0, size)]
    f = open(fileName, 'r')
    for line in f.readlines():
        loadLine(line.strip('\n'))
    f.close()

def saveFile(fileName):
    f = open(fileName, 'wb')
    for ch in mem:
        f.write(chr(ch))
    f.close()
    

え~と、プログラミング言語は、どの環境でも実行できると思われる "Python" です。 クラスにすれば良かった。 条件分岐は連想を使えば良かった。 と、色々と突っ込みどころ満載ですので、どなたか適宜ブラッシュ・アップしてください。

このプログラムを smem.py という名前のファイルにして、 Python のコンソールから、手動で呼び出して使用します。

>>> import smem
>>> smem.loadFile("C:/Projects/CW/CFCQ03/bin/MCF52233_INTERNAL_FLASH.elf.S19")

Entry Point=00020000
>>> smem.saveFile("Z:/noritan/COLDFIRE.BIN")
>>>

読み出しているSレコードは、前回の記事で作成したファイルです。 読み出すファイルと書き込むファイルは、各自の環境に合わせてください。

付録基板にバイナリ・ファイルを送り込む

Sレコードには、100バイトほどのプログラムしか書かれていませんが、出来上がったバイナリ・ファイルは、もれなく128kバイトの大きさがあります。 これを tftp でターゲットの付録基板に送り込みます。 もちろん、前々回の記事で紹介したベクタ・テーブルが書き込まれている付録基板を使用してください。

Z:\noritan>tftp -i 192.168.1.105 put COLDFIRE.BIN
Transfer successful: 131072 bytes in 6 seconds, 21845 bytes/s

あっという間に転送完了です。 これで、ユーザ・ドライバが使用できるようになりました。

使ってみよう

今回作成したユーザ・ドライバは、引数の値に従って、三つのメッセージを返すという仕様でした。

OK
PrStr(UserDriver(0,0))
HELLO WORLD!!

OK
PrStr(UserDriver(0,1))
Nice to meet you.

OK
PrStr(UserDriver(0,2))
Good bye.

OK

いい感じです。 ユーザ・ドライバを入れ替えたくなったら、再度、バイナリ・ファイル COLDFIRE.BIN を送り込むだけで済みます。

今後の課題

たかが100バイトのプログラムに128kバイトのバイナリ・ファイルを作らせるなんて、もったいなさ過ぎます。 PCのプログラムが必要な所も、引っかかります。

そこで、次なる課題は、 SilentC のプログラムだけでSレコードを読み込ませて、 FLASH に書き込むことです。 さて、間に合うかな?

参考文献

Interface (インターフェース) 2008年 09月号 [雑誌]

Interface (インターフェース) 2008年 09月号 [雑誌]

  • 作者:
  • 出版社/メーカー: CQ出版
  • 発売日: 2008/07/25
  • メディア: 雑誌

なぜか、これも。

Interface (インターフェース) 2008年 12月号 [雑誌]

Interface (インターフェース) 2008年 12月号 [雑誌]

  • 作者:
  • 出版社/メーカー: CQ出版
  • 発売日: 2008/10/25
  • メディア: 雑誌


nice!(0)  コメント(4)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 4

masato

Linker の設定を "Generate Binary Image" として出来たものの先頭 8 byte を削除して誤魔化してみました。

ところで Editor の Font 設定で "MS ゴシック' + 日本語でデフォルト円コーディングを ShiftJIS としていてもファイルを開くと UTF16 になってしまい make がエラーになったりするんですが、そんなことはありませんか。
by masato (2008-10-25 17:59) 

noritan

え~と、私が使っているのは、Courierなので良く分かりません。

CodeWarrior for MCU の時には、iniファイルかhwlファイルのフォント名を"MS ゴシック"ではなく"MS Gothic"にして対処したと記憶していますが、 CodeWarrior for ColdFire には、該当するファイルがありませんね。

きっと、円高のせいだな。(意味不明)

by noritan (2008-10-25 21:07) 

masato

なるほど。
自分で書くときにはプログラムに日本語を入れないようにするのですが、エレキジャックの QG8 用ソースをそのまま ColdFire に使い回して日本語表示して気付きました。
ソースコードを開いたときに UTF16 になってコンパイルに通らない上に、ProcessorExpert を再実行するとソースコードが消されたりして悩んでました。
by masato (2008-10-25 23:33) 

noritan

ProcessorExpert で、書いたプログラムが消されてしまう事故は、 CodeWarrior for Microcontrollers で経験しました。 Service Request に、さんざん文句を付けて、バグ取りをしてもらったので、今は落ち付いているんじゃないかな。

CodeWarrior for CodFire は、私がバグ出しをしていないので、まだまだバグが残っていると思います。 :-P

by noritan (2008-10-27 16:00) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。