なんとかなるさね

マイコンをネタにブログを始めてみました


RL78マイコン基板(RL78/G13)|KurumiWriter V1.00(ソース公開版)のフラッシュ書き込み時間の改善 

これまでの2つのエントリ(811, 819)でKurumiWriterとrl78flashでRL78マイコンの内蔵フラッシュメモリへの
書き込み時間を比較しましたが、両者に違いがあり過ぎるのがちょっと残念でしたので、KurumiWriterを改造
して書き込み時間をどの程度短縮出来るか試してみました。幸い、両者はMITライセンスでソースコードが公開
されていますので、両者を見比べつつ勘を頼りにKurumiWriterで以下の改造を行ってみました。

* 半2重で設計された通信プロトコルで受信スレッドを使う発想に違和感があったのでスレッド処理をやめた
* rl78flashがやっている非同期I/O読み出しを使わずに出来る受信タイムアウトの設定パラメータを拝借した

その結果、以下のように改善されました。(とは言え、ややタイムアウト時間が長かったので微調整が必要になり
そうですし、FT232RLの内蔵EEPROMを書き換える為のRun after COM openにチェックがあるとタイムアウト
するか意図的に調べている箇所を実行して不自然に暫く固まったりしますので、もうちょっとな感はあります。)

FT232RLのWindowsドライバのデフォルト設定

* KurumiWriter V1.00改造前 (Run after COM openのチェック無し、cotton_sketch.bin)

115,200bps → 22sec
500,000bps → 20sec
1,000,000bps → 未サポート

* KurumiWriter V1.00改造後 (Run after COM openのチェック無し、cotton_sketch.bin)

115,200bps → 8sec
500,000bps → 5sec
1,000,000bps → 未サポート

* rl78flash (rl78flash-0.5.2-mon80-20160914 -m 2 -b 通信ボーレート -a COM14 cotton_sketch.mot)

115,200bps → 16sec
500,000bps → 11sec
1,000,000bps → 11sec

以前のエントリでRL78/G10への書き込み時間が短くなることに気付いてから私が常用している設定

* KurumiWriter V1.00改造前 (Run after COM openのチェック無し、cotton_sketch.bin)

115,200bps → 40sec
500,000bps → 36sec (+/-2sec程度のバラツキあり)
1,000,000bps → 未サポート

* KurumiWriter V1.00改造後 (Run after COM openのチェック無し、cotton_sketch.bin)

115,200bps → 7sec
500,000bps → 3sec
1,000,000bps → 未サポート

* rl78flash (rl78flash-0.5.2-mon80-20160914 -m 2 -b 通信ボーレート -a COM14 cotton_sketch.mot)

115,200bps → 10sec
500,000bps → 4sec
1,000,000bps → 4sec

なお、改造したソースファイルとKurumiWriter_Win.exeを以下の7zファイルに固めておきました。

ファイル: KurumiWriter_Win_V100_Modify.7z
内容:

KurumiWriter_Win_V100_MON80_20160923.exe
KurumiWriter.vcxproj
SequenceProcessor.cpp
SequenceProcessor.h
SerialPortProcessor.cpp
SerialPortProcessor.h

ちなみに、ソースファイルの改造箇所の一例は以下の通りです。

ファイル: SequenceProcessor.cpp
改造内容(抜粋): 赤字の箇所を改造

//-----------------------------------------------------------------------------
// @outline     プログラミング処理を行います。
// @explanation プログラミング処理を行います。
// @param       none
// @return      正常に終了できた場合には SW_SUCCESSを、正常に終了できない場合には SW_SUCCESS 以外を返します。
//-----------------------------------------------------------------------------
DWORD WINAPI CSequenceProcessor::programming()
{
    DWORD           dwRet           = SW_SUCCESS;   // 戻り値
    DCB             dcb;                            // DCB構造体
#ifdef MON80
    COMMTIMEOUTS    timeouts;                       // TIMEOUTS構造体
#endif

    途中省略

    // シリアルポートの設定
    memset(&dcb, 0, sizeof(DCB));               // DCB構造体の初期化
    dcb.DCBlength       = sizeof(DCB) ;         // DCB構造体のサイズ
    dcb.fBinary         = TRUE;                 // Windowsはバイナリモードのみサポート
    dcb.BaudRate        = CBR_115200;           // ボーレート       :115200bps
    dcb.Parity          = NOPARITY;             // パリティビット   :なし
    dcb.ByteSize        = 8;                    // データ長         :8ビット
    dcb.StopBits        = TWOSTOPBITS;          // ストップビット   :2ビット
    dcb.fDtrControl     = DTR_CONTROL_DISABLE;  // DTR制御線を無効化

#ifdef MON80
    // シリアルポートのタイムアウトパラメータ(https://github.com/msalau/rl78flash/blob/master/src/serial_win32.c)
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=0;
    timeouts.WriteTotalTimeoutMultiplier=0;
#endif


#if PROC_TIME_FLG
    // 処理開始時間をセット
    dwStartTime = timeGetTime();
#endif

    // シリアルポートをオープン
    if (SW_SUCCESS == dwRet) {
#ifndef MON80
        dwRet = m_ComPort.Open(m_ContextInfo.PortNumber, &dcb);
        if (SW_SUCCESS == dwRet) {
            // 受信スレッドの起動待ち
            while (FALSE == m_ComPort.IsReading()) {
                Sleep(0);
            }
        }
#else
        dwRet = m_ComPort.Open(m_ContextInfo.PortNumber, &dcb, &timeouts);
#endif

    }

    // プログラミング・モードへ遷移
    if (SW_SUCCESS == dwRet) {
        DTRACE(_T("## Programming Mode\r\n"));
        m_Progress.Step  = SW_STEP_MODE_CHANGE;
        m_Progress.Share = 5UL;

        fInvertDtr = FALSE;
        dwRet = programingMode(m_ContextInfo.BaudRate, V33, fInvertDtr);
        if (SW_ERROR_MODE_CHANGE_TIMEOUT == dwRet) {
            fInvertDtr = TRUE;
            dwRet = programingMode(m_ContextInfo.BaudRate, V33, fInvertDtr);
        }

        m_Progress.CurrentProgress  += 5UL;
        UpdateProgress(m_Progress.Step, m_Progress.CurrentProgress);
    }

    途中省略
    return dwRet;
}


追記 : メモ

Windows Communication API - MSDN

COMMTIMEOUTS structure
https://msdn.microsoft.com/library/aa363190.aspx

SetCommTimouts
https://msdn.microsoft.com/library/cc429719.aspx

追記 : メモ

KURUMI Writer for Win V1.00 Source - Rulz
http://japan.renesasrulz.com/gr_user_forum_japanese/m/mediagallery/119.aspx

追記 : メモ

Tool to program RL78 MCUs via serial bootloader - GitHub

master
https://github.com/msalau/rl78flash/

releases
https://github.com/msalau/rl78flash/releases/

v0.5.2
https://github.com/msalau/rl78flash/tree/v0.5.2/

関連記事

2016/09/23   blog-entry-820   category: RL78 /* 16bit,8bit CISC */

go page top