かみやんの技術者ブログ

主にプログラムの話です

H8マイコン 自動プログラムローダと.net frameworkでジョイパッド入

1つ前のエントリで書いたAibiUIの続き。

TeraTermのファイル送信コマンドってどんなプロトコルだろう?
というところで終わっていたが、まず、TeraTermのソースをsourceforgeから取得してみたところ、ソースをざっと読んだところ、あまり大した事をしていなさそう。
次に、Toppersのサイトでモニタプログラムのソースを取得して、眺めてみたが、こちらはアセンブラで書いてあって、H8マイコンアセンブリ言語は覚える気がないので、ざっとみただけ。

はっきりとプロトコルが分からなかったが、まずは、読み込んだファイルをそのままシリアルポートへ出力してみるコードを書いてみた。

        //ファイル送信開始
        private void StartSendFile()
        {
            try
            {
                isMicroComputerRunning = false;
                StopSendFile();
                string fname = option.GetProgramFile();
                FileInfo fi = new FileInfo(fname);
                sendFileTotal = fi.Length;
                sendFileNow = 0;
                fileInput = new FileStream(fname, FileMode.Open);
                AppendText("Start sending file:" + fname +"\n");
                sendFileTimer.Interval = 500;
                sendFileTimer.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                StopSendFile();
            }
        }

        //ファイル送信停止
        private void StopSendFile()
        {
            if (fileInput != null)
            {//転送中のとき
                fileInput.Close();
                fileInput = null;
                sendFileTotal = 0;
                sendFileNow = 0;
                sendFileTimer.Stop();
            }
        }

        //ファイル送信:タイマーイベント
        private void sendFileTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                int size = serialPort.WriteBufferSize - serialPort.BytesToWrite;
                byte[] buf = new byte[size];
                int n = fileInput.Read(buf, 0, size);
                if (n == 0)
                {//EOFのとき
                    StopSendFile();
                    isMicroComputerRunning = true;
                    return;
                }
                serialPort.Write(buf, 0, n);
                sendFileNow += n;
                AppendText("Sending... "+ sendFileNow + "/" + sendFileTotal+"\n");
            }
            catch (Exception ex)
            {
                StopSendFile();
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

インターバルタイマーで500msごとに、シリアルポートの書き込みバッファの空サイズ分づつ送信するようにした。
実行してみたところ、あっさりToppers+自分のアプリが転送されて、実行された。
ということで、どうもテキストファイルを無手順で送ればよかったようだ。
先頭にデータサイズを送るとか、パケットに分けてチェックサムを付加するとか、データの終了を表す終端子をつけるとか全くなかった。(テキストファイルのEOF(0xff)は送っているかも)

モニタプログラム起動時のメッセージを見つけたら、自動的に自分のアプリを転送するようにしようと思っていたが、まずは、手動で「Send File」ボタンを押したら自分のアプリを転送するように実装した。TeraTermに比べて毎回自分のアプリのファイルをファイル選択ダイアログから選ばなくてよくなったので快適。