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 フレームワークを利用している方には、色々細かく修正したので、最新版を取得すると、コンパイルが通らないかもしれない。
多分、修正にはそんなに多くの苦労は無いものと思うが、新しい版を受け入れてもらいたい。