MATLAB Coder(2)
MATLAB Coder(1)からの続きです。
今回は、M-Fileで書いたアルゴリズムをハードウェアに実装するための方法について考えて見ます。
M-Fileでもって演算アルゴリズムを作成し、MATLABである程度の検証を行ったとしましょう。次は、実際にハードウェアに実装して、ちゃんと動くか試してみる番です。なんだかんだ言って、実機に勝る検証対象はありませんからね。
具体的には、マイコンを用意して、そこにCコードをコンパイルしたファームウェアを書き込む形になるかと思います。
さて、何も考えずに、MATLAB Coderを使ってM-FileをCコードに変換したら終了、めでたしめでたし。という風に行けばいいのですが、さすがにそれは油断しすぎです。それでうまく行ったとしても、よっぽどラッキーだっただけでしょう。
実行速度の確認
私がこれを仕事で請けるとしたら、真っ先に「必要な演算スピードは?」という点を確認します。音声フィルターくらいなら何とかなっても、無線の変調・復調をCでやるのはかなり厳しい気がします。(DSPにぶち込んだらイケるのかな・・・?やっぱり厳しいかな・・・?)
どうしても、ns(ナノ秒)オーダーでの演算がしたくって・・・というのであれば、FPGA化をお勧めします。この場合、方法は3つあります。
・XilinxやAlteraが出しているSimulinkブロックセット で実装して、HDLを生成する
・Simulinkモデルで書いて、HDL CoderでHDLを生成する
・手でHDLを書く
このうち、一番上と一番下はやったことがあるので、うまく行くことは分かっています。2番目の方法は、たぶん大丈夫な気がしないでもないですが、使ったことが無いので何ともいえません。
大穴の大冒険としては、M-File → C コード → (動作合成して)HDL という手も無きにしもあらずです。しかし、動作合成ツールの制限はかなりキツイので、M-Fileから生成したCコードをそのままブチ込むのは勇気が要りそうです。
戦略の概要
とりあえず、実行速度は何とかなりそうだ、という話になったとしましょう。
そうなるともう、動くかどうかはM-Fileの内容次第です。後はひたすらエラーをつぶしていって、最後の最後にオリジナルM-Fileとの動作比較という流れになるかと思います。
ここまで済んだら、ハードウェアに載せてみて最終確認です。
M-Fileの修正
M-FileからのCコード生成で起きうる問題はたくさんありますが、大きく2つに大別できると思っています。
問題(1)セル配列やTry/Catch構文など、コード生成できないロジックが存在する
問題(2)呼び出しているMATLAB関数が、コード生成に対応していない
それぞれ、別々のアプローチが必要です。
コード生成できないロジックの発見と修正
まずこれを見つけるのが大変なわけですが、その点MATLABはよく出来ています。M-Fileの関数のおしりに、 %#codegen というコメントを入れることで、「これはコード生成のためのM-Fileだよー」と通知できます。すると、コード生成用にコードアナライザーがチェックしてくれます。
%#codegen はコード生成フラグ
たとえば、コード生成向けなのにセル配列を使っていたら、キッチリ警告してくれます。
エラー部分に、赤い波線がつく
これを、どうにかこうにか直します。どう直すかはケース・バイ・ケースです。
最初はすごく大変な作業になる可能性もありますが、仕方がありません。出来る事といえば、「今後、このM-Fileをいじるときは、コードアナライザーがエラーを出さないような形にしてくださいね」という形で運用をお願いするしかありません。
呼び出しているMATLAB関数が、コード生成に対応していない
よっぽど無いとは思いますが、万が一あるようであれば、何とかしないといけません。ちなみに、これはコード生成させてみないと分からないので、コード生成のエラーログを見て判断します。
対処方法は大きく2つです。
対策(1):呼び出しているMATLAB関数と同等の処理を、M-Fileで書き直す
対策(2):コード生成後は、Cで用意したライブラリーを呼び出すようにする
対策の1番目は、コレで済むならベストです。しかし、これで何とかなるケースは少ないんじゃないかと思います。
すると仕方なく2番目の対策を取ることになります。画面に何か表示したいだとか、ちょっと特殊な数学関数を使いたいだとか、M-Fileでどうこうするのが難しそうなケースです。
実は、MATLAB CoderはC 関数呼び出しをサポートしています。
(MATLAB Coderマニュアルより引用)C 関数の呼び出し
そのため、ハードウェア上での画面表示だとか、ちょっと特殊な数学関数だとかを、C言語で実装しておいて、それを呼び出すことが出来ます。
そのためには、まず「特殊な処理」をしたい関数だけを、独立したM-Fileにくくりだします。そして、MATLAB上での実行、MATLAB Coderでのコード生成、それぞれのフェーズで切り替えます。
場合に応じて、参照するM-Fileを切り替える
このようにすれば、MATLABで実行する時と、コード生成する時とで処理を切り分けることが出来ます。MATLABで実行するときはMATLABコマンドプロンプトに表示を行い、ハードウェアで実行するときにはRS232Cからキャラクタ出力する、というような感じで切り分けられます。
(ちなみに、MATLABパスを変更したら、念のため rehash コマンドを実行するのをお忘れなく。)
コード生成と、動作確認
なんとかかんとかエラー対処を行ったとしたら、いよいよコード生成してから動作確認です。まずはMEX関数で生成するのが良いかと思います。
すると、コード生成後にラッパーと結合されて、MATLABで動作する形のMEXファイルが生成されます。
このMEXファイルは、もともとのM-Fileと全く同じようにMATLABコマンドプロンプトから呼び出す事が出来ます。そのため、もともとのM-Fileとの動作比較も容易に行えます。
ハードウェアへ
最後にハードウェアに乗っけるわけですが、やるとしたら次のような構成になるかと思います。MATLAB Coderの出力タイプは「C/C++スタティックライブラリ」とします。
コード生成されるのは、あくまでアルゴリズムの部分だけです。そのため、main関数、スタートアップ処理、ドライバー部分などは、手で書く必要があります。
次のようなM-Fileからコード生成すると、
次のようなアルゴリズムの本体、
および、次のような初期化・終了関数が生成されます。
よって、手書きのmain関数からは、処理前に initialize関数、終了前に terminate 関数を呼び出します。あとは、必要なタイミングで処理関数(上の例でいけば、codertest関数)を呼び出します。
なお、これらを含んだCファイル、Hファイルは、1つのフォルダーにまとめて生成されます。
よって、これらのC、H、そして手書きのCをまとめてコンパイル・リンクすれば完成です。
まとめ
しょせんCコードなので、生成できてしまえば、どうという事はありません。しかし、そこに至るまでに色々と苦労されるかと思います。
あと、ハードウェアに載せる所をかなりいい加減に書きましたが、ここは普通の組み込みシステム開発と同じように色々大変な思いをするはずなのでご注意ください。