「ソフトウェアー・エンジニアリング」カテゴリーアーカイブ

ソフトウェアー関係の話題など・・

最近は、github にプッシュしてます~

RXマイコン別性能(レイトレースによる)その2

RX66Tを入手したので、レイトレースを実行してみた。

その中で、RX65N Envision kit のコードを標準的にして、他のデバイスも評価していたが、LCDへの転送は、ポートバスによるソフトウェアー書き込みになっている。
水平ライン毎に、レンダリング時間を描画しているが、ポート経由だと、フォント描画がボトルネックになっている事実などがあり、コーディングを整理した。

まず、各マイコン別のタイムを表にしたので参考にしてもらいたい。
※今回、RX64M も加えた。

型番 動作周波数 [MHz] ROM RAM 実時間 [ミリ秒] 価格 [円]
R5F524TAADFP RX24T 80 256K 16K 1224 974 (572/10)
R5F565NEDDFB RX65N 120 2M 640K 784 1910 (1320/10)
R5F564MFCDFC RX64M 120 2M 512K 751 2120 (1570/10)
R5F566TEBDFP RX66T 160 512K 64K 602 900(参考)
R5F571MFDDFC RX71M 240 2M 512K 439 2600 (1940/10)

RX66Tの価格は、RSコンポーネンツで1個購入時のもので、チップワンストップで扱うようになれば、多少異なると思う。

描画ハードに関して、RX64M、RX66Tは、実際にはLCDを接続していないが、RX64MはRX71M、RX66TはRX24Tと同一のインターフェースがあるものとしているので正確だと思う。
※ポート経由の描画オーバーヘッドは、RX66Tで118ミリ秒もある。(ただRAMに書くだけだと484ミリ秒)

通常、描画時間は、ライン毎に%表示されるが、ソフトによるポートバスでは、オーバーヘッドがかなり大きいので、その部分をコメントアウトして、描画後に1回だけ表示するようにしている。

RX66TのRXv3コアの評価は、この結果からはイマイチ判らないが、RX71MやRX64Mの値からすると、やはり少し効率が高いようだ、ただ、浮動小数点演算が多いので、イマイチ参考にならない。

現段階でも、CPはRX66Tがもっとも優れていると言える。

ソースコードなどは、Github のRX/RAYTRACER_sample に全てある。


EMLE 端子のプルダウンを入れてから、フラッシュの書き込みは一度も失敗しないようになった。

ルネサスRX66T(その1)

ルネサスRXマイコンを購入する場合、自分の場合「チップワンストップ」がほとんどで、他ではほぼ買わない(値段が一番安く、種類が豊富、個数割引もあるので)。

RX66Tは、発表されてからかなりたつものの、未だにチップ単体での販売はされていない。

ところが、ツイッターで「RX66TでLチカした」とゆーツイートを見つけた・・
※変換基板だったので、デバイス単体で入手したようだった。
ツイートした人はマイクロマウスをやってる人のようで、「どうやって入手したの?」と聞いたが連絡は取れず、色々調べたら「RSコンポーネンツ」で販売している事を見つけた。
1個900円と少し高いと思ったが、早く試してみたかったので、早速1個購入した。
※それにRXマイコンも10周年らしぃのでw
※現在(4月9日)、ルネサスのHPでも、RX66Tの販売先としてはどこも登録されていない。
※次の日には届いて、変換基板にハンダ付け。
※購入した型番は「R5F566TEBDFP」で、PGA 差動入力なし、USB なし、100 ピン、プログラムフラッシュ 512K、RAM 64K、データフラッシュ 32K

早速、変換基板に取り付け

写真のハンダ付けはちょっと汚いが、一応ブリッジや接触不良は無いものと思う。(よく確認した)
いつものように「直付」する為、裏側をカプトンテープで保護する。

ユニバーサル基板に直接乗せ、ガイドとして、適当なヘッダーピンを刺しておき、対角のピンにハンダを流して、変換基板と、下のユニバーサル基板を固定する。
後は、電源ライン、MD端子、クリスタル関係、リセットSW、シリアルラインなど、最低限必要な線だけ配線する。


  • (20) PD5/RXD1 <--- TXD (USB Serial)
  • (22) PD3/TXD1 ---> RXD (USB Serial)
  • (6) MD L:Boot、H:Run
  • (1) /RES
  • (5) VCL GND 間に 0.47uF
  • (11) XTAL 10MHz、GND間に 8pF
  • (13) EXTAL 10MHz、GND間に 8pF
  • (2) EMLE 4.7K で プルダウン(エミュレーターイネーブル)
  • (15) PE2/NMI 10K でプルアップ

rxprog も、RX66T 用にプロトコルを追加して、LED 点滅は直ぐに動作した。
RX66T関係のデバイス定義は、発表と同時くらいに、ハードウェアーマニュアルをダウンロードして、実装していたので、ソフトの準備はそれなりに出来ていた。
RX66T の内部構成は、RX24T よりRX64M 系に近い。
今回入手したデバイスは、USB は内臓していないバージョンだが、ラインナップには USB 付きもある、その場合、内臓クロックは12の倍数にする必要があり、144MHz 動作になってしまうと思う(最高速は160MHzなので少しもったいない)。

static void micro_second(uint32_t us)
{
    while(us > 0) {
#if defined(SIG_RX64M) || defined(SIG_RX63T) || defined(SIG_RX71M)
        for(uint32_t n = 0; n < (F_ICLK / 4285714); ++n) {
            asm("nop");
        }
#elif defined(SIG_RX65N)
        for(uint32_t n = 0; n < (F_ICLK / 4444444); ++n) {
            asm("nop");
        }
#elif defined(SIG_RX24T)
        for(uint32_t n = 0; n < (F_ICLK / 4444444); ++n) {
            asm("nop");
        }
#elif defined(SIG_RX66T)
        for(uint32_t n = 0; n < (F_ICLK / 3346666); ++n) {
            asm("nop");
        }
#else
#  error "delay.hpp requires tune dummy operations"
#endif
        --us;
    }
}

RX66T は、RXv3 コアとなっており、実測による簡単なソフトループだが、今までのRXコアより15~20%くらい速いようだ。
※同じバイナリーでこれだけ高速なのは、驚くべき性能だと思う。
※ちゃんとしたベンチマークは後ほど行う予定

現在の問題として、フラッシュプログラム中に停止する症状がある。
これは、原因を特定出来ていない・・・
とりあえず、rx_prog.conf のシリアル速度を、230400から115200に落としたら、多少安定して書き込めるようなので、当面そうしておく。
※RX64M、RX71M、RX24T では、問題無いのだが・・・

とりあえず
FIRST_sample/RX66T(LED 点滅)
SCI_sample/RX66T(シリアル通信)
は、動作する事を確認した。

※RX66T では、SCI のベースクロックは、PCLKBを利用するが、このクロックの最大は60MHzで、内臓クロックを160MHzで動かす場合、最大では40MHzとなる。


フラッシュ書き込み時にハングアップする原因が判ったと思う。
RX66Tでは、EMLE端子が増設された、「1」でエミュレーターイネーブルなので、とりあえずGNDに落としておいたが、これが原因のようだ、4.7Kでプルダウンしたら、安定して書き込めるようになった。
多分、フラッシュ書き込み時などに一瞬出力になる場合があるのだろう・・
※ボーレートは関係無かった。

Makefile 、環境毎の違いを補正

既に、「glfw_app」などで行っていたのだが、RXマイコンの開発環境でも、boost を使うようになった為、Makefile の修正を行った。
※プロジェクトの数が多いので、主要な部分のみ行った。

boost は、パッケージマネージャーでインストールするのが標準的となったので、環境毎にパスを追加で指定しなければならない。
そこで、以下のようなスクリプトで、環境を識別して、内部変数を設定している。

# Include path for each environment
ifeq ($(OS),Windows_NT)
SYSTEM := WIN
LOCAL_PATH  =   /mingw64
else
  UNAME := $(shell uname -s)
  ifeq ($(UNAME),Linux)
    SYSTEM := LINUX
    LOCAL_PATH = /usr/local
  endif
  ifeq ($(UNAME),Darwin)
    SYSTEM := OSX
    OSX_VER := $(shell sw_vers -productVersion | sed 's/^\([0-9]*.[0-9]*\).[0-9]*/\1/')
    LOCAL_PATH = /opt/local
  endif
endif

INC_SYS     =   $(LOCAL_PATH)/include

これで、Windows(MSYS2)、Linux、OS-Xの違いを識別して、適切な「パス」を設定できる。
OS-X では、OS のバージョンも抜き出している。

他、emacs を起動した場合の TAB を強制的に指示する為、以下の「おまじない」をファイルの先頭に追加した。

# -*- tab-width : 4 -*-

さらに、既に2019年だが、今まで「C++14」を指定していたコンパイルオプションを「C++17」に変更しておいた。

PFLAGS      =   -std=c++17 $(CP_OPT) $(OPTIMIZE) $(MCU_TARGET) $(DEFS)

github のREADMEを英語ベースにする試み・・

最近、VSCodeでマークダウンを編集している。
これが、凄く快適で、画面をスプリットして、リアルタイムに描画イメージを確認しながら作業出来る。

そんな事もあって、トップページの README を英語にして、日本語はリンクにしてみた。
自分、英語が得意では無いので、翻訳は、Google 先生にほぼお任せ状態で、ネィティブな人には、かなり痛い英語かもしれない。
まぁ、無いよりはマシ程度と考えている。

まだ、全部を翻訳していないが、順次追加していこうと思う。

VSCode にはマークダウンを PDF 化する拡張機能があり、これを使う事で、ブラウザ以外でも読めるファイルが作れる事から、RXマイコン関連の事や、ブログで書いた細かい話などをまとめた。

https://github.com/hirakuni45/RX/blob/master/docs/cpp_spin_rx_story.md

これもまだまだ未完成なので、今後加筆修正していこうと思う。

Visual Studio Code を使う為の設定

自分は、マルチプラットホームにこだわりがあり、色々な異なった環境でも同じような操作性を提供できる事に注目している。

Visual Studio Code は、マイクロソフトのオープンソースによるもので、アプリケーションとしてはテキストエディターだが、単なる文書を書くだけではない、色々な拡張機能を追加でき、カスタマイズ出来る点で大きな広がりがある。
拡張機能は、emacs が先人でもあるが、emacs がスタートした時代は古く、VSC は最近の「流行」を取り入れて斬新な物になっている、emacs を現代風に作り直したアプリケーションとも言えると思う。
※emacs は Lisp だが、VSCは Json なので、より多くの人に受け入れやすい。

「創作活動のほとんどは、文書を作る動作が起点になっている。」と言う事実に改めて気がつく。

既に多くの人が、VSC を利用した拡張機能をリリースしており、自分で新規に作らなくても、インストールして利用する事が出来る。
また、VSC の設定方法や Tips など豊富にある、ただ、目的の機能を実現する方法は複数(無限)あり、VSC のバージョンとも関連するので、シンプルな方法を選んで取り込む必要がある。

自分が VSC で感激した点:
・拡張機能が豊富で、検索してインストールする事がコンビニエンス。
・Git と連携していて、git で行う操作を標準で色々行える、git 用フロントエンドアプリを使うより強力で判りやすく便利かもしれない。
・Markdown 形式を標準でサポートしており、プレビューしながら記述出来る。
※拡張機能を入れると PDF 化する事も出来る。
・Terminal 機能があり、MSYS2 の bash などを呼び出して使う事が出来る。
・C++ では非常に有能なインテリセンスが使える。
※インクルードパスの設定が重要
・プラットホーム毎の「固有」設定が出来る。
・比較的軽い。

それでも、小躍りする前に事前の調査が重要、「道具」類は、良さそうと思って使ってみても、細かいとこで気に入らない事も多い。
少し使ってみて、「何だコレ!」って思った事もあったけど、やはり「短所」より「長所」が勝っており、将来性を考えたら、コレを使わない理由が無い事に気がつく。

今まで emacs を中心に使ってきた、ただ、積極的に Lisp を使う気になれなくて、ほぼコードを書くだけで使っていた。
※知り合いは、自分で Lisp を書いて、自分の欲しい環境を色々実装している。
それを横目で観ていて、自分もやってみたいと思っていたが、もう少しハードルを下げた方法は無いのかとも思っていた。

最近の VSC では、「ワークスペース」と言う概念を使う事ができる点で、異なった環境を柔軟に切り替える事が出来る。
※以前は、フォルダーのルートを指定するシンプルな物だったが、それを少し拡張して、複数フォルダーに関連するファイル郡を一括して扱う事が出来るようになった。
「ワークスペース」では、設定が書かれた専用ファイルを開く事から始めるので、固有の設定を取り込む事が出来る。

まずインストール。
MSYS2 は現状でも、ツールの中心なので、インストールする、詳しい方法は、https://github.com/hirakuni45/RX を参照の事。
※MSYS2 は MinGW とは異なったアプリケーションなので、必ずMSYS2 を使うように。

・Terminal で MSYS2 の bash が起動出来るようにする設定、「settings.json」を編集して、以下のように追加しておく。
※「settings.json」の直接編集の正しい方法は「ぐぐって」もらうとして、自分の場合は、
「設定」などで、「settings.json で編集」などのリンクがあるので、それをクリックして編集している。
※キーワードを入れると候補が表示されるので判りやすい。

{
    "git.ignoreLegacyWarning": true,
    "git.autoRepositoryDetection": "subFolders",
    "C_Cpp.default.cppStandard": "c++14",
    "C_Cpp.default.cStandard": "c99",
    "files.autoSave": "afterDelay",
    "C_Cpp.default.intelliSenseMode": "gcc-x64",
    "C_Cpp.intelliSenseEngineFallback": "Disabled",
    // MSYS2 bash のパスと、起動設定
    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
    "terminal.integrated.env.windows": {
        "MSYSTEM": "MINGW64",
        "CHERE_INVOKING": "1"
    },
    "terminal.integrated.shellArgs.windows": [
        "--login"
    ],
    "terminal.integrated.cursorStyle": "line",
    "editor.renderWhitespace": "all"
}

※必要な部分のみコピーする場合は、「,」に注意

・拡張機能を入れよう~
※「拡張機能」ボタンを押して、検索ボックスでキーワードを入れれば、候補がリストされ、簡単にインストール出来る。

(1) C/C++ (Microsoft)
※自分は、マイクロソフトの物を入れているが、検索すると複数の物が見つかるので、自分の嗜好に合った物を使えば良いだろう。
※現段階で、gcc などでインテリセンスを機能させる設定が判っていない。

(2) Emacs Friendly Keymap
※とりあえず、キーバインドを Emacs 風にしている、vi や他のエディター用もあるし、自分でキーバインドを設定する事も出来る。
※VSCでは、「ESC」キーは別の意味で使われており、一般的な Emacs のメタキーとして利用するには反故が多いようだ。
なので、「M-v」は「ALT+v」として機能する、今まで「ESC」を使ってきたが、矯正する必要がありそうだ・・・
まぁ確かに、ESC を押してから v を押すより、ALT+v の方が利便性が高い。

(3) Japanese Language Pack for VS Code (Microsoft)
英語のメニューでも、そんなに困らないが、日本語の対応は流石に本家だけあって良く出来ている


最後はインテリセンスの設定だが、MSYS2 上の gcc g++、clang などで運用するには、もう少し調査が必要だと思う。

思いつくインクルードパスを設定しても、思ったように、インテリセンスが機能しない・・・

色々調べたが、何故思ったように機能しないかも不明で、WEBにある「こうすればおけー」と言った情報を見て、そのように設定してみたが、やはり駄目・・

何か特殊な設定をするのか、別の拡張機能を入れるのか、謎である・・・

RX65Nボードの設計(その1)

RX66Tが発表になり、デバイスが入手出来るのを待っていたが、なかなかデバイス単体で購入できる状態にならないので、RX65Nのボードを先に作ろうかと思い作業を始めた。
※169ピンのRX65Nを5個購入した(@1560)
※ついでにPFCコンバーター専用ICなども購入、こちらは、CNC用インバーターなどの前段に使う予定でいる。

RX65N Envision Kit はまぁ良いのだが、惜しい部分がある。
・バッテリーバックアップがない
・RTCのクリスタルが接続されていない
・付属LCD(480x272)の視野角が狭く、表示品質がイマイチ
・無線LANがない
・SDRAMがない
・オーディオ出力がない
・バッテリー駆動系の部品などが無い
・後載せ部品など基本的な仕様
などで、本当は 最高速で動作する 240MHz の RX71M の方も捨てがたいが、DRW2Dコントローラーが魅力なので、とりあえずRX65Nで進める。
ピンアサインは RX71M、RX64M とほぼ同一なので、少し工夫すれば乗せかえる事も出来そうだが、RX71M用は、また基板を作れば良いだろう。

無線LANは、コストで有利な ESP8266 や ESP32 を繋げておけば良さそうだが、天邪鬼なので、マイクロチップ社の WiFi モジュール ATWINC1500 を乗せられるようにしておく予定でいる。
※スピードを評価したい事もあるし(ESP8266より高速に通信できると思う)、SPI 接続の代表的な物を使いたい、ただ、コストは ESP に比べると3倍くらい高い。(個数を沢山買えば、1.5倍くらいにはなりそう・・)

EDA ツールは KiCAD を使っているのだが、最新バージョン(5.02)をインストールしたら、非常に機能が追加されており、シンプルで使いやすくなっていて驚いたー(素晴らしいとしか言い様がない!)
※ただ、4.x系とファイルの互換で問題がありそうで、4.x用ファイルを読み込めない場合があるようだ・・

ボードのコストは、Wifi、SDカードインターフェース、100BaseEthernet、256Mbit SDRAM、LCD などなど乗せても、部品代だけなら Envision Kit と同等くらいで収まる。

ただ、問題もある。
実際に設計を始めて問題になったのはピン定義だ、SDRAM(16ビットバス)、SDHI(SDカード)、Ethernet、LCDなど、169ピンデバイスで、これらを全部使うピン定義を考えたが、信号が被って、同時利用は出来ないようだ・・・

LCD のバスを「8ビットシリアル」にする事で何とかアサイン出来る事が判った、ポートは余っているのに、そこにアサイン出来ない(定義が無い)のは「何で」ってなる・・
※8ビットシリアルを通常の RGB バスに変換するのに8ビットラッチを2個は用意する必要があると思う。

将来的にはマイクロコントローラのピン定義は、全てのピンで全てのペリフェラルを自由に割り当て出来るような構成になるものと思うが、LSIの設計段階で、それが大きなハードルになる場合もあるのだろう、現状では、そのような柔軟な設定が出来るマイクロコントローラは少ない。
そこまでの柔軟性は必要無くても、最低限、主要な機能を使う為の標準的定義が仕様として出来ないのは如何なものか・・・

KiCADのシンボルや footprint は、ネットを探すと自分の欲しい物はほとんど入手できる場合が多いが、部分的に気に入らない場合や、ライセンスなどの問題があったりして、一つや二つなら自分で作っても大した手間ではない。
また、5.x系の為、4.x系のライブラリが読めない事があるようだ。
※秋月電子とかで、そのような物を集めて、またはサービスとして作成して公開して欲しいと思う。
自分が使う部品は、GitHub に上げてある。
https://github.com/hirakuni45/RX/tree/master/KiCAD_lib

パルストランス内臓イーサーネットモジュラージャック RJ-45

回路設計と言っても、ルネサス社が出しているサンプルボードの回路図で必要な部分を流用すれば良い、最近は基板を作るハードルが下がっているので、失敗しても気軽に作り直しが出来る、ただ、やはり4層基板で作りたいので、それほど安くは出来ないかもしれないが、日本国内の基板屋に比べて1/4~1/10程度だろうと思う。

MicroChip ATWINC1500-MR210PB WiFiモジュール

LCD は秋月で売っているものの、タッチパネルが付いていないので、AliiExpress でタッチパネル付きの物を購入した、送料入れて22ドル程度だったが、表示品質は高そうだ、秋月で売っているものとバックライトLEDの仕様が異なるが、「CAT4238」を使えば、流れる電流値の設定変更だけで対応出来そうではある、LCDのピンアサインは共通のようだ。

SDRAM は、秋月で128メガビット品を@300で入手出来るが、256メガビット品「IS42S16160-7TL」を購入、@423だった。(16ビットバス)
RX65Nは内臓RAMはそこそこあるものの、グラフィックスなど、容量の大きいオブジェクトを扱う場合、SDRAMは必須と言える。
※外部に接続されたSDRAMの速度は、内臓RAMに比べてかなりスローダウンすると思えるのだが、実メモリが数十メガバイトあるのは、本当に有利だ、C++ の標準ライブラリや boost も気兼ねなく使え、PC 環境と遜色無く、プログラムを実装できると思える。
また、Minix のような実行環境も揃えられるだろう。
※ gcc を動かしたいが、完全な POSIX 環境を作るのは簡単では無いだろうな・・

RX65N Envision Kit、DRW2D エンジンの仕様?不具合?

先日、RX65N に内臓の描画エンジンを使ってみたが、描画の管理を色々テスト、評価する段階で暗礁に乗り上げた。
RX65Nの場合、内臓メモリは限られているので、ダブルバッファとフリッピングによる手法を行うには無理がある。
そこで、とりあえず、シングルバッファによる方法で、描画と表示を最適化して、何とかならないかと試行錯誤してみたが、「問題」に当たった。

予定では、画面表示と描画を細かく管理する事で、高速な描画エンジンとの連携で何とかなると思っていたが、思っていたように動作せず、悩んでいる。

まず、問題をシンプルにする為、簡単な描画シーケンスを実行してみた。

    d2_startframe(d2_);
    d2_clear(d2_, 0x000000);
    d2_setcolor(d2_, 0, col);
    d2_rendercircle(d2_, 480/2*16, 272/2*16, rad*16, 0);
    d2_endframe(d2_);

上記のプログラムでは、画面全体を消去して、中心に円を描画する、描画の半径は、フレーム毎に変えるようにしている。
※実際に描画にかかる実時間は、半径が最大でも1ms程度と思われる。

普通に考えると、「描画中」は、描画アクセスが優先されるので正しい表示にならないのは判る。
しかし、実際にこのプログラムを走らせると、描画が終わってからも、正しい表示がされない。
※正しい表示がされるのは、次のフレームからになり、毎フレームこの処理を繰り返すと、ほとんど何も表示出来ない常態になってしまう。
ここからは想像なのだが、DRW2Dエンジンにディスプレイリストを渡して描画すると、DRW2Dエンジンがメモリバスを奪い取って放さず、GLCDCの読み出しが無効になってしまい、表示の読み出しが失敗しているように見える。
DRW2Dのキャッシュをフラッシュするとか、描画領域を変更するとか色々考え付く方法を試したが、一旦描画を始めてしまうと、描画の終了に関わらず、メモリバスを占有して離さないようだ、この状態は、垂直同期信号のトリガーでリセットされる。
これは、参った、この状況では、いくらパフォーマンスが高くても、リアルタイム性を要求するような描画を行えない。

何か不足している設定があるのでは?

もしかして、「バス」の優先度を設定するレジスターがあるのでは?
ハードウェアーマニュアルを良く見て、「あーーー」と唸ってしまった、「拡張バスマスタ優先度制御レジスタ (EBMAPCR)」というのがあった・・・
ヨクヨク、サンプルソースコードを見ると、GLCDC、DRW2Dの初期化時にこのレジスターにプライオリティーを設定してる・・

    {  // メインバス2優先順位設定(GLCDC、DRW2D)
        device::BUS::EBMAPCR.PR1SEL = 0;
        device::BUS::EBMAPCR.PR2SEL = 3;
        device::BUS::EBMAPCR.PR3SEL = 1;
        device::BUS::EBMAPCR.PR4SEL = 2;
        device::BUS::EBMAPCR.PR5SEL = 4;
    }

それに習って、上記のように優先順位を設定してみたら、思った通りの表示が行えた~

この問題解決に随分時間をかけてしまったようだ・・・

上の黒い「帯」でDRW2Dエンジンが描画を行っている・・

RX65N Envision Kit 、DRW2Dエンジンを使う

RX65Nには、描画をブーストするDRW2D描画エンジンがある。
ただ、ハードウェアーレジスタの詳細は公開されておらず、C言語による操作ライブラリが公開されている。
今までは、フレームバッファに対する描画は、ソフトウェアーによる描画のみを使っていたが、当然ハードウェアーの方がパフォーマンスは高く、描画中は、他の処理を実行出来る為、効率も良さそうだ。
また、DRW2Dの描画機能は、アンチエリアス付の描画が行え、「線幅」の概念があるので、かなり柔軟で品質の高い描画が簡単に行える。

そこで、DRW2Dライブラリの機能をC++から呼び出すラッパーを実装してみた。
※DRW2Dライブラリのバージョンは1.02をベースにしている。

DRW2Dの基本的な動作は、メモリー上に描画コマンド・リストを定義しておき、その先頭ポインタを描画エンジンに渡す事で描画を行う仕組みとなっている。

描画状況により、割り込みが起動でき、DRW2Dライブラリでは、標準的に割り込みサービスを呼び出すように設計されている。

「drw2d_mgr」クラスでは、初期化で、割り込みベクターを登録している。
「void drw_int_isr(void);」はDRW2Dライブラリの割り込みサービスの入り口で、それを登録しておけば良い、ただ、この割り込みは、グループベクタAL1になっていて、「icu_mgr」クラス内の AL1 dispatch クラスが、内部で振り分けを行うようになっている。
※割り込み関数アトリビュートを付けないようにしなければならない。

extern "C" {
    extern void drw_int_isr(void);
};
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  DRW2D 制御/マネージャー
        @param[in]  DRW     DRW2D クラス
        @param[in]  XSIZE   X 方向ピクセルサイズ
        @param[in]  YSIZE   Y 方向ピクセルサイズ
        @param[in]  PXT     ピクセル・タイプ
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <class DRW, int16_t XSIZE, int16_t YSIZE, glcdc_def::PIX_TYPE PXT>
class drw2d_mgr {

...

    icu_mgr::install_group_task(DRW::get_irq_vec(), drw_int_isr);

...

};

DRW2Dの初期化は、以下のように行うようで、「drw2d_mgr」クラスの初期化「start();」から呼んでいる。
この呼び出し後、DRW2Dエンジンを利用出来るようだ。

    d2_ = d2_opendevice(0);
    d2_inithw(d2_, 0);
    rb_ = d2_newrenderbuffer(d2_, dlis, stsz);

「d2_newrenderbuffer」のプロトタイプは以下のようになっている。
dlis: initialsize - number of displaylist entries in the first page (minimum is 3)
stsz: stepsize - number of displaylist entries in following pages (minimum is 3)

内部で「malloc」を使ってメモリを割り当てているので、固定長で使えるように改修する必要があるかもしれない・・

DRW2DライブラリのAPIは非常に豊富に用意されているが、とりあえず、良く使いそうな物だけラップした。
また、座標系のクラスなどを積極的に利用するようにした。
DRW2Dライブラリの構成はOpenGLのコマンドストリームの考え方に近いので(高速、柔軟性、機能性を追及すると、大体、このような構成になる)マネージャーを実装するのは比較的やりやすい。

アンチエリアスされた「線」と「サークル」の描画

とりあえず、基本が出来たので後は、スプライトなどテクスチャーの描画などだ、フォントが一通り描画できるようになったら、ソフトウェアーのエンジンと入れ替えたい・・・

drw2d_mgr.hpp

NESのパッドを付けてみたら・・

部屋をかたずけていたら、NESのコントローラーが出てきた、本体は無い、多分これは、20年くらい前のもので、その時務めていた会社(ライブプランニング)からNESのソフトと本体など借りた時(丁度「暴れん坊天狗」の NES 版「Zombie Nation」を作っていた頃だ)本体は返したがコントローラーだけ自宅に置き去りになったものと思う。

NESパッド

折角なので、RX65N Envision kit のNESエミュレーターのパッドとして使ってみた。

ネットを探して、コントローラーのピンアサインを探して、コネクタを付けた。

白:Vcc(電源、通常+5V)
茶:GND(電源、0V)
橙:P/S(パラレル、シフト切り替え)
赤:CLK(クロック)
黄:OUT(シリアル出力)

ところが・・・
ボタンを押しても反応が無い・・・
配線を確認したが、問題無さそう、ファミコン互換パッドでは問題無く動作する。

これは多分、クロックの遅延が足りないものと思い、クロックの遅延ループを6回から20回にして動作するようになった。
この純正パッドはC-MOS「4021B」を使っているが、互換パッドに使われているICは、4021Bの互換ICで、クロックの許容範囲が広いものと思う。

uint8_t update(uint32_t cnt = 20) noexcept
{
    P_S::P = 0; // seirial
    uint8_t d = 0;
    for(uint8_t i = 0; i < 8; ++i) {
        d <<= 1;
        if(!OUT::P()) ++d;
        CLK::P = 1;
        utils::delay::loop(cnt);
        CLK::P = 0;
        utils::delay::loop(cnt);
    }
    P_S::P = 1; // parallel
    data_ = d;
    return data_;
}

上記のように、ループ数を「6」から「20」に変更した。
※120MHz動作の場合なので、もっとCPUクロックが速い場合は調整する必要がある。

static void loop(uint32_t cnt)
{
    while(cnt > 0) {
        asm("nop");
        --cnt;
    }
}

loop 関数は上記のように「nop」を実行するだけのものだ。

RX65N Envision Kit には、上記のように接続してある。

FAMIPAD.hpp

今回の話とは関係無いが、写真の圧着工具、安い割りにはなかなかに良い!
この小さいコネクタの圧着では、まともにできずに、ラジオペンチで修正したり、最悪ハンダ付けしたりと苦労してきたが、この工具なら、ほぼ間違いなく綺麗に圧着できる。
専用の工具は非常に高価で、たいてい1種類のピンにしか対応しないので、DIYでは買う機会は無いのだが、この工具ならそれに匹敵する、すばらしい!

RXマイコン別性能(レイトレースによる)

RX66Tは、まだデバイスが入手できていないので評価はまだだが、RX24T、RX65N、RX71M(RX64M)の全般的な性能評価を行った。
※RX64Mは最大動作周波数がRX71Mの半分で、他はRX71Mと同等なので、スルーしている。
又、最大動作周波数でベンチマークしている。

今回の評価では、「レイトレース・プログラム」を使った。
現実的には、このベンチマークでは不十分とも思えるが、浮動小数点演算が混在したプログラムを走らせるようなアプリの評価では、整数演算とのバランス(浮動小数点の比率が高めだけど・・)で、十分参考になると思える。
※整数演算のみの評価では、他のマイコンと比べるとRXマイコンは、CISC系で、ルネサスが独自に工夫しており、実行効率が優れている為、評価するまでもなく速い。
※現状では、消費電力辺りの能力、強力な各種ペリフェラルなど、色々な面で、敵ナシだと思う。(gcc を使わない場合の開発環境が有料、又、やはりコストは多少高い、その点で、他より劣る)

RX200シリーズなどのFPUを持たないマイコン(RXv1コア)は、手持ちが無いので評価していないが、コストの問題から下位のシリーズを使う場合でも、CPの高いRX24Tの存在があり(RX220とあまりコストが変わらないと言うのは言い過ぎだと思うが・・)低価格路線では、それを目安にする事ができる。
※自分としては、RX200シリーズはFPUを持たないし、動作周波数も低く、あまりメリットを感じない。
これは多分、RL78などの8/16ビットマイコンとの差別化で、同じような価格帯で、性能差が大きすぎると差別化が難しい為と思われる、それでも、32ビットコアのメリットは大きい。
※RXマイコンが、ARM、PIC32、ESP32に比べて割高感があるので、「敬遠」している人がいるかもしれないが、たとえば、RX65Nと同等の機能を持った、ARMと比べた場合、同等の性能を出す事が出来るシリーズは無かったり、価格もそれほど変わらない場合も多い。
今回評価していないものの、RX630(100MHz)などもあり、RXマイコンは色々な場面で有用だと思える。

RX24T、8ビットバス、I/Oポート制御
RX65N、フレームバッファ制御
RX71M、フレームバッファ制御
型番 動作周波数 [MHz] FPU ROM RAM 実時間 [ミリ秒] 価格 [円]
R5F524TAADFP RX24T 80 256K 16K 1670 974 (572/10)
R5F565NEDDFB RX65N 120 2M 640K 812 1910 (1320/10)
R5F571MFDDFC RX71M 240 2M 512K 410 2600 (1940/10)
ESP32(参考) 160 4M 520K 13000 550
STM32F4(参考) 72 × 1M 192K 52000 320
STM32F756BGT6(参考) 216 1M 320K 620 1820 (1250/10)

備考:
・コンパイラは「rx-elf-gcc 6.4.0」で、最適化「-O3」でバイナリーを作成。
・ESP32 の結果が悪すぎるのは、LCD とのインターフェースに問題があるように思う。(描画のオーバーヘッドが大きいものと思う)
・内臓メモリのサイズと値段は相関があるので、単純にCPを比べる事は出来ない。
・ESP32、STM32F4、STM32F7 の結果は、ネット情報による。
・RX65NのCPが意外に高い、LCD接続が容易で、トータルで考えた場合、バランスが良い。
・RX71M、RX65Nは、フレームバッファを使い、描画コストが低い、STM32F7も同様の方式と思われる。
・RX24Tは、RAMが少ないので都度描画を行っている、描画コストがそれなりにある。
・ベンチマークに使ったソースは、Arduino 向けの物なので、細かい部分で、動作が微妙に異なり、条件も違う。
・RX マイコンでは、float の平方根を求める専用命令(FSQRT)を使っている。(STM32F7もそれは同様なようだ)