この大リーグボール養成ギブスを付けた状態で色々高速化を試みてきました。羊の皮を取り去り本来の実力を見てみたいと思います。設定を変更することで簡単にできました。変わることになります。プリスケーラーの設定は変更が必要と思っていましたが、なんとそのままで動作しました。なると私の安いロジアナ(サンプリングの上限が100MSa/s)では波形を確認できません。CLK(水色)とデータ(黄色)が下図です。程度のクロックが出ているようです。ブレッドボード環境でこの周波数で動作していることもすごいですね。この速さはとてつもないと思います。最後に今回の高速化対応での線分描画時間の測定結果を下表に示します。20.94X(旧Twitter)に投稿したメッセージに添付した動画を貼っておきます。dot)での塗りつぶし処理を高速化したことについて書きました。この時のデモ表示を見ているとラインの描画が目で見えるほど遅いので何とか高速化できないものか考えてみました。制御部がC言語での標準な制御方法ではまどろっこしい程の処理なのでレジスタ直書きやアセンブラ化すればかなり速くなりそうです。method)と記す)ので記録しておきたいと思います。後で気が付きましたが「ポケコン(G850)高速ライン描画」の記事でも引用していた「ラインルーチンの高速化の手法」のページにライン描画の高速化について判り易くまとめられていて、ここにダブルステップの手法が書かれていますが評価結果として高速化はできなかったとの結論でした。今回提案する傾き予測法は本ページの末尾にまとめたように実際に高速化への効果が確かめられた描画法です。1.今回のお品書きライン描画手法について下記の内容を記載します。最後にまとめとして上記手法の評価結果を記載します。以降にライン描画の各手法について記載します。高速化のために整数だけの処理でラインを描画する手法でブレゼンハムのアルゴリズムとして広く知られています。下記のソースはネット上のソースを参照せずに独自に起こしたものですが、ブレゼンハムのアルゴリズムと同等の処理になっています。高速化の観点からループ内での条件分岐を最小限にするために傾きの大きさにより場合分けし、二つのループ処理に分割しています。1ピクセルを描画する外部処理です。上記の改良版でラインが中心点から見て点対称なので始点側と同時に終点側も描画することでループ回数を1/2にして高速化しています。始点~終点間の距離が偶数の場合、中心のポイントの描画が欠落してしまうことに対する対処です。上記の描画では傾きが1(45°)以下の場合と1より大きい場合の二通りに場合分けして処理しましたが、傾き予測法では傾きの大きさによりループ処理を更に2分割します。下図に示すように傾きの大きさと移動方向の条件により、次の移動方向を決定できるケースがあり、これを利用して高速化しています。前述の両端からの描画手法も併用します。1/2以下なので下図の上側の緑色の■のように縦移動直後は必ず横移動になります。1/2以上なので下図の下側の緑色の■のように横移動直後は必ず縦移動になります。ループのための条件ジャンプの比率が1/2になり効果は少ないですが若干高速化します(ループ処理の展開による高速化)。逆に言うと1回のループ処理で多くのドットを処理してもそれに比例して条件分岐が増えれば高速化できません(当然処理量が比例して多くなっても高速化できません)。従って高速化するためには上図のようにループ内の条件ジャンプの増加を抑えつつ、より多くのドットを処理するようにする必要があります。{上記は速度優先で同様な処理が2カ所にありましたが、速度低下を最小限にしてコードを短くしたバージョンを追記します。dot)を接続した環境を使いました。本のラインデータに従ってライン描画処理を実行した際の時間を計測しました。毎の割込み処理でインクリメントするカウンタ値で時間を計測しています。-Os(サイズ優先)です。計測結果を下表に示します。何もしないダミー関数にし、ライン描画アルゴリズムの処理自体の時間を計測し直した結果が下表です。倍速いという結果になりました。使って高速化したのでメモっておきたいと思います。機能を使って高速化します。下記の変更/追加を行います。以下に対処した内容について記載します。機能自体の説明もある程度記載します。初期化の時のプリスケーラの設定を変更するだけです。CPU(CH32V203)のブロック図を下図に示します。ペリフェラルのバスに接続されています。メモリの高速なデータ転送を実現します。CPU(CH32V203)のブロック図ペリフェラルと言ってもそれを制御するペリフェラル用のレジスタは下図のようにメモリにマッピングされています。チャンネルとペリフェラルは下図のように対応付けされています。リクエストマッピングこの対応付けを表にしたものが下表になります。チェンネル3を使用することになります。チャンネルで複数のリクエストに対応している関係上、下記の様にリクエスト要求側でリクエストを有効にする設定が必要になります。制御レジスタのビット構成を下図に示します。あとはサンプルソースを参照して設定することで容易に動作しました。制御レジスタ唯一悩ましかったのが次の点でした。対象であり、この場合のペリフェラルサイズ(PSIZE)とメモリサイズ(MSIZE)の設定で悩みました。DMA_MemoryDataSize_HalfWordと設定したところ、メモリ上のデータの1バイト目だけしか転送されませんでした。変更することでうまく動作するようになりました。設定部分のソースを以下に貼っておきます。方が妥当だと思いますがサンプルのままで弄っていません。&DMA_InitStructure);}連続書込み部分のソースは下記になります。大きい場合は分割して転送するようにしています。文を入れれば一つのループにできますが速度優先で二つのループにしています(実質的な速度は殆ど変わらないとは思いますが)。化前の画面クリア時(0x0000の連続書込み)のロジアナ波形です。出力間に隙間時間がかなりあります。化後のロジアナ波形です。化した連続書込み処理を利用して、円と四角形の塗りつぶし描画処理を追加しました。レベルになるとマイコンのソフト処理では流石に転送と転送の間に隙間時間が発生してしまいます。機能を有しており、効率よくテータ転送ができるようになっています。機能を使用することで隙間時間なく転送できるようになり、処理時間を短縮出来ました。コントローラの書き込み対象の四角形範囲を指定できる機能により、四角形の塗りつぶしはかなり高速化しました。書込みと並行して別の処理をすることもソフトウェア次第で可能になります。化後のデモ画面を貼っておきます。描画デモ画面例X(旧Twitter)のメッセージに添付した動画も貼っておきます。不安定要素が残存するもののセンスしたデータをきれいに描画できるようになりました。最大8個の測位データが含まれる通信データの塊(package)を5個中1個の割合でした処理できていませんでした。処理できるようにしたいと思います。多く処理できるようにします。具体的な高速化ポイントは下記のとおりです。値を0~90度の区間分持つことにしました。240)を考慮し、下記のようにしました。64倍で送られてきます。データ内の角度からの変換はシフト処理のみでできるようにしました。要素の配列を持つことになります。配列上は角度0の場合もゼロの値になりますが、角度0の場合は配列を参照せずに結果はゼロと判断するようにしました。プロフラムで行いました。テーブルのソースは下記になります。データ処理を浮動小数点を使わず、全て整数処理で行うことができるようになり、かなり高速化できました。中、1個だけ処理ができています。時間が掛かっていることになります。8個のポイントを描画しています。浮動小数点演算での処理(従来方式)下図は整数演算処理化した改善版のロジアナ波形です。処理できるようになったので処理率は従来の20%から33%に改善されました。発生している部分がLCD描画している箇所ですが、従来は8回の描画に隙間が見えましたが、高速化したことにより、隙間が見えなくなっています(マーカー1の部分)。時間が掛かっていることが判ります。データと同様にリトルエンディアンです。データの受信バッファからバイト単位でデータを抜き取り、シフト処理でワードデータ等を抽出していました。高速化のために受信バッファ内のポインタをキャストすることでデータ抽出を行わず直接参照するようにしました。高速化後のロジアナ波形が下図になります。程度に高速化できました。ロジアナ波形の最後に追加した"receiving"はLiDARからのデータを割込み処理で受信中であることを示すディバッグのための信号です。データを受信できていないことが判ります。出力されるデータを受信できるようにすることで受信待ち時間を最小にして高速化しました。下図がダブルバッファー化後のロジアナ波形です。処理率はほぼ100%に改善できました。繋いでデータ抽出し、LCD上にリアルタイムで表示できるようになりました。データのほぼ100%を処理し表示できるようになりました。デュアルコア)等の例が多く、数百円レベルのマイコンでの例は見かけません。データをLCDに表示できるようになりました。2024/07/21X(旧Twitter)に投稿したメッセージに添付した動画を貼っておきます。着荷したので試してみました。データをリアルタイムで表示できました。今回はシリアル通信と割込み機能を試してみたいと思います。割込みを使ったシリアル受信機能を実装します。データを受信し、LCD上に表示することに挑戦してみたいと思います。2.割込みを使ったシリアル受信の実装サンプルを参照して実装は簡単にできました。ヘッダファイルと割込み処理のコードを貼っておきます。説明する部分はあまりありませんが、受信バッファは2のべき乗サイズにしてリングバッファにしています。バッファからの読出し時には割込み処理との競合防止のため、受信割込み禁止にしています。2020年8月頃に購入したものです。下の写真は裏側にある基板の部分です。左下の元々あったコネクタのピッチが狭いため、左上のコネクタを瞬間接着剤でプリント基板に接着しています。中央部にある裏側への配線は元々あったものです。写真(表面)カバーを外した状態が下の写真です。カバーを外したかというとこの個体は調子が悪かった(特に角度情報)ためです。