RL78 のフレームワークを久々に改善

C++ は組み込みでは積極利用者が少ない事を実感する日々

最近、特に感じるが、何故か、C++ を組み込みマイコンで積極利用している人が少ないように感じる。

やはり、ハードルがあるのだろうと思う(自分は慣れの問題で感じなくなっている)

どう考えても、C で実装するより、間違いが少なく、構造的に作れて、再利用性が大きく、最適化性能が高い。

C++11 以降、痛い部分が改善されて、より良く自然に書けるようにもなった。

勉強しない人には、何かと敷居が高いのかもしれない・・・

ただ、C++ は、C である程度実装出来る人にとっては、「手っ取り早く、楽で魅力的」とは映らない面もある。
C++ のパワーを理解していないものと思う。

自分は、10年以上前に、C++ を「勉強しなくては」と心の底から思った出来事がある。

非常に複雑で、ボリュームが大きいプロジェクト内で、急遽、モニター用のプログラムを作る案件が生じたー

この案件に対して、C++師匠は、STL を駆使して、あっとゆーまに実装を終え、ちゃんと動くアプリを作った。
※自分がこの仕様を観た時は、これは、そこそこ大変だなーと思っていた・・

また、この師匠は、数ギガヘルツで動くようなCPUのアプリを、何でアセンブラに毛が生えたようなC言語でプログラムしないといけないの?
もっと相応しい作り方があるのでは?

と問うて来たー、この一件で、自分の C++ 敬遠傾向は、一蹴されたと思う。

それ以来、C++ を履修しなおし、現在に至る。

  • C++ の勉強会などに参加して、C++ に精通した人から、色々なレクチャーを受けた。
  • C++ は、正しい道を進まないで我流で進むと、とんでもない迷路にはまる事がある事例をいくつも聞かされた。
  • C++ の最適化で、人間が考えもしない独特の手法で、巧妙に行う事例をいくつも観た。
  • C++ になって大きなプログラムでも、メモリーリークは殆どしないようになった。
  • コンパイルが正常終了すると、大抵プログラムも思ったように動く事が多くなった。
  • テンプレートを少しは理解出来て、自分でもある程度作れるようになった。
  • 警告が出ない、綺麗なソースコードを書くようになった。
  • コードレビューをするようになった。
  • C++ のトレンドや、標準化委員会、boost などのレポートを読むようになった。

ただ、先は長い・・、自分の理解を超えるような考え方、概念がまだ沢山ある・・
まぁ、とりあえず、出来る範囲でゆっくり歩こうと思う。

ある人が言ってた、C++ を学ぶ最良の方法:

C++ をある程度出来る人にコードレビューしてもらう事。
間違った道から、正しい道に戻してもらう。


RL78 関係のフレームワークをメンテナンス

長い間、RX マイコンのフレームワークに集中していたので、RL78 のフレームワークには手を付けていなかった・・

しかし、最近、このフレームワークを使っている人が Qiita にコメントしていた。

使っている人がいるなら、RX マイコンのフレームワーク更新で改善されたエッセンスなどを RL78 にも反映したい。

そこで、それらの実装とテストを行った。

何故か、フラッシュが出来ない・・

Windows10 になって、RL78 の開発環境を作り直して、FIRST_sample を書こうと思ったが、エラーが出てフラッシュが出来ない。

CP2102N が悪いのかと思い、FTDI に変えてみたが、駄目で、エラーメッセージを頼りに、プロトコルのコードのパラメータを変えたり、色々したが駄目・・・

ルネサス・フラッシュ・プログラマーの最新版を導入して、それで書こうと思ったが、やはりうまく行かない・・・

※最新の RFP では、RL78 へのフラッシュ書き込みに、COM ポートで行う最小限のハードを使った場合をサポートしている。

ところが、FTDI で、再度やり直したら、今度は書き込みが正常に行われた・・・
※何が理由なのかさっぱり判らない(RFP のインストールが関係しているのかもしれない・・・)

改善した箇所

テンプレートクラスの実態を定義

以前の実装では、最適化しない(-O0)場合、テンプレート内スタティック変数の実態が無い為、リンクに失敗する。

テンプレートクラスでは、スタテック変数の実態を定義する必要があり、特殊な書き方が必要だ。
これは、書籍や C++ テンプレートの解説でも殆ど見ない方法だと思う。

※最適化を行うと、実態は必要無く(最適化すると、実態を経由しなくなる)問題にならない事が多い。

※デバッグが必要な場合、最適化は行わない。

namespace device {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  インターバル・タイマー・クラス
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    template <class _>
    struct itm_t {

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
        /*!
            @brief  12ビット・インターバル・タイマ・コントロール・レジスタ(ITMC)
            @param[in]  T   アクセス・クラス
        */
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
        template <class T>
        struct itmc_t : public T {
            using T::operator =;
            using T::operator ();
            using T::operator |=;
            using T::operator &=;

            bit_rw_t<T, bitpos::B15>   RINTE;  ///< 12ビット・インターバル・タイマの動作制御
            bits_rw_t<T, bitpos::B0, 12> ITCMP;  ///< 12ビット・インターバル・タイマのコンペア値設定

        };
        typedef itmc_t< rw16_t<0xFFF90> > ITMC_;
        static ITMC_ ITMC;

...

    };
    // テンプレート内、スタティック定義、実態:
    template<class _> typename itm_t<_>::ITMC_ itm_t<_>::ITMC;

    typedef itm_t<void> itm;

↑のように実装する事でリンクエラーを回避出来る。

「itm_t」クラスは、疑似的にテンプレート化してある。
これは、ヘッダーのみで運用する場合、実態を定義するのに都合が良い。

PORT 定義クラスを更新

シングルポートを定義するテンプレートクラスを最新の物にした。

RX マイコンのフレームワークで得た、知見を組み込んである。

ただ、RL78 のポート関係レジスターは、構造的では無い構成なので、多少異なる構成となっている。

namespace {

    // 吸い込みなので、三番目のパラメーターを「false」とする。
    // LED::P = 1 で、実際のポートは、0になり、LED が点灯する。
    typedef device::PORT<device::port_no::P4, device::bitpos::B3, false> LED;

}

int main(int argc, char* argv[])
{
    utils::port::pullup_all();  ///< 安全の為、全ての入力をプルアップ

    LED::DIR = 1;  // 出力設定

    bool f = true;
    while(1) {
        utils::delay::milli_second(250);  ///< 0.25 秒毎の点滅
        LED::P = f;
        f = !f;
    }
}

PSG_sample を追加

ついでなので、先日実装した PSG エミュレーションで音楽演奏のプロジェクトを追加した。

とりあえず、思ったように鳴っているようだ。

VScode の設定を追加

VScode でソースを編集する場合に、インテリセンスを活用する為、設定ファイルを追加してある。

ただ、理由が不明で、赤線がでる場合がある・・・

これは、今後の課題とする・・・


まとめ

RL78 フレームワークを利用している方には、色々細かく修正したので、最新版を取得すると、コンパイルが通らないかもしれない。

多分、修正にはそんなに多くの苦労は無いものと思うが、新しい版を受け入れてもらいたい。