MATLAB コードを使用した
C コードの生成
クイック
スタート ガイド
(R2016a)MATLAB Coder を使用することで MATLAB コード から C コードを生成で きます。MATLAB 内での動作に必要なインターフェイスが含まれるスタ ンドアロンの ANSI‐C コードまたは C コードを、コンパイル済みの MEX ファイルとして生成できます。本クイック スタート ガイドは、スタン ドアロン ANSI‐C コードの生成方法について説明します。コード生成用の MATLAB コードの準備に関する情報については、『MATLAB Coder 用 MATLAB コードの準備:クイック スタート ガイド』[1]を参照してくださ い。
スタンドアロン
C コードの生成手順
スタンドアロン C コードを生成する前に、必ず MEX ファイルを常に生成 して、このファイルが MATLAB で正しく実行するかを確認します。 MEX ファイルにはさまざまなチェックが含まれているため、ランタイム エラーの検出と修正をより簡単に行うことができます。詳細については [1] を参照してください。 MEX ファイルの生成と動作の検証 [1] 最初のスタンドアロン C コードの生成 外部 C プロジェクトにおける、生成された C コードの理解 生成された C コードのカスタマイズ 生成された C コードを外部プロジェクトに統合最初のスタンドアロン
C コードの生成
スタンドアロン C コードを生成するには、[ビルド] を [ソース コード]、 [スタティック ライブラリ]、[ダイナミック ライブラリ] または [実行フ ァイル] のいずれかに切り替えます。 スタティック ライブラリ、ダイナミック ライブラリ、実行ファ イルはどう違うのですか? 生成された C コードに関する限り、違いはありません。 スタティッ ク/ダイナミ ック ライブ ラリ MATLAB Coder は C 言語ベースのプロジェクトでリン ク可能なスタティック/ダイナミック ライブラリをビ ルドします。 場所: codegen/lib/<最上位レベル名> (dll) 実行可能フ ァイル メイン関数を指定する必要があります。その上で、 MATLAB Coder は生成されたコードを呼び出す実行フ ァイルをビルドします。 場所: codegen/exe/<最上位レベル名>生成された
C コードの理解
コメント 元になった MATLAB コードを C コード内にコメントとして追加しておく と、その C コードの由来をより簡単に理解できることがよくあります。 、[コード外観] を選択。メモリの割り当て MATLAB Coder では配列は 3 つのタイプに区別されます。 固定サイズの配列 (例: 12 行 3 列) MATLAB Coder ではメモリは常にスタック上に割 り当てられます。スタックに空きが無い場合は 静的メモリとして割り当てられます。 最大サイズが既知 であるが、サイズ が不明の配列 (‘max‐size arrays’) サイズが不明の配列がコードに含まれていない 場合は、動的メモリ割り当てを使用しないよう に選択できます。下図のように、すべての配列 が可変サイズである場合に使用するか、または 所定のサイズより大きい配列のみに使用できま す。[詳細設定]、[メモリ] を選択 (下図参照) サイズがまったく 不明の配列 (最大 サイズが不明) サイズが不明の配列のメモリへの割り当ては、 常に実行時に発生します (emxEnsureCapacity の 呼び出しによる動的なメモリ割り当て)。
C コードのカスタマイズ
より効率的な C コードを生成するベストプラクティスを次に示します。 すべての配列にサイズの上限があることを確認する (該当する場合) 必要に応じて配列のサイズ情報を追加します。 例: assert(N < 25); y = zeros(1,N); 生成されたコードが参照により引数を渡すことを確認する C では配列は常に参照により渡されます。ただし、MATLAB Coder は、変 数をサブ関数に渡す前に、変数のローカル コピーを作成しなければな らない場合があります。 ヒント: インプレース構文 “a = foo(a)” を呼び出し側と関数宣言の 両方で使用すると、ローカルでコピーを行う必要がなくなりま す。 x = foo(x,b) … function a = foo(a,b) …. y = foo(x,b) … function a = foo(a,b) …. 入出力名が呼び出し側と関数宣 言の両方で同一。 MATLAB Coder は ‘x’ のローカ ル コピーを作成する必要はあり ません。 呼び出し側で入出力変数に 2 つ の異なる名前を使用。したがっ て、‘foo’ への呼出し後に変数 ‘x’ および ‘y’ の両方が存在する。 MATLAB Coder はメモリをコピー しなければなりません 論理配列インデックスの使用を控える 論理配列インデックスとは、配列のサブ要素の操作を論理インデックス に基づいて実行する機能です。たとえば、次のように 255 より大きいす べての要素を切り取ることができます。 x(x>255) = 255; 通常は次のように書き換えることで、より優れたコードになります。 for ii=1:numel(x), if (x(ii)>255), x(ii) = 255; end, end スカラー入力を強調する MATLAB Coder では ‘x’ がスカラーであることを認識できない場合があり ます。たとえば、‘a’ は常に少なくとも 1 つの正の要素をもつと仮定した 場合、x = find(a>0, 1,'first') はスカラーですが、MATLAB Coder はこれが空 にならないことを認識できないため、‘:1’ として入力します。 スカラー入力を強調するには、この行を次のように変更しま す。 x = find(a>0, 1,'first'); x = x(1);
生成された
C コードを外部プロジェクトに統合
使用するファイル [ワークフローの完了] のステップで zip ファイルとしてパッケージ化す ることですべてのファイルを取得します。 メモリのレイアウト MATLAB の行列順序は列が優先されます。2 次元行列における連続要素 が 1 つの列の要素に該当します。一方、C 言語は行優先です。 MATLAB Coder が生成する C コードは MATLAB の動作を模倣します。その ため、入力 (出力の場合も) 引数に複数次元 (2 次元以上) の行列がある場 合、外部 C のテストベンチに一致するように入力 (または出力) の転置が 必要な場合もあります。 引数の型 入力引数および返り値は、以下の C 関数に対応します。 固定サイズ配列 配列 へのポインター: x[10] 最大サイズ配列 (動的割り当ては しない) 実際の実行時の配列サイズをもつ配列へのポイ ンター:x_data[10] および x_sizes[2] 動的に割り当てら れた配列 “emxArrays”。 これは生成された .h ファイルで 定義される特別な型です。MATLAB Coder はこれ らの配列の作成、破棄を行う補助関数を提供し ています。詳細については、MATLAB Coder の”Atoms”デモを参照してください。[MATLAB Coder ドキュメンテーション]、[例]、[MATLAB コードからの C コードの生成]、[原子のシミュ レーションへの動的なメモリ割り当ての使用]よくある質問と答え
Embedded Coder が必要でしょうか? Embedded Coder は、以下を可能にすることで生成されたコードをカスタ マイズできるようにします。 Embedded Coder を使用すると、スタンドアロンのターゲット用に生成さ れた C コードをカスタマイズできます。Embedded Coder の主な特徴は次 に示す機能です。 ‐ 特定の組み込みプロセッサについてはコード置換ライブラリ (CRL)を使用します (たとえば ARM Cortex A/M、TI DSP) ‐ ソフトウェアインザループ (SIL) シミュレーションとプロセッサ インザループ (PIL) シミュレーションを実行します ‐ コード生成テンプレートおよび静的コード メトリクスを使用し ます ‐ #define ディレクティブを使用してグローバル変数を宣言します ファイル I/O サポートについて
MATLAB Coder の ‘load’、’Y fopen/fprintf/fclose’、’fread’ およびビデオとオ ーディオ ファイル リーダーの System object のサポートには制限があり ます。詳細についてはサポートされている関数の一覧を参照してくださ い。“coder.opaque” の例を参照することで、汎用ファイルの読み取り と書き込みの例を確認できます。 コマンドラインからの実行 コード生成およびすべてのオプションの設定はコマンドラインから行う ことができます。“codegen” と “coder.config” を参照してください。 メ ニュー (アプリの右上) の下の [スクリプトへの変換…] オプションを使用 するか、“coder” コマンドの “‐tocode” オプションを使用すると、 MATLAB Coder プロジェクトを MATLAB スクリプトに自動的に変換できま す。 独自の C コードから生成されたコードを呼び出すにはどうすればよ いですか? MATLAB Coder は生成されたコードを呼び出す方法を示すメイン ファイ ルを生成します。[詳細設定]、[すべての設定]、[Advanced]を参照してく ださい。 複数の関数のコード生成を行う場合の関数名の競合について 複数の関数について個々にコード生成を行う場合、MATLAB Coder で生成 される C 関数は、名前は同じでもいくつかのサブ関数の動作が異なる場 合もあります。これは、すべての関数のファイルを 1 つのディレクトリ に統合する際に競合につながる場合があります。 解決法: 最初のステップで、最上位レベルの関数をプロジェクト に定義する 機能を使用して、い くつかの関数のコードを同時に生成します。MATLAB Coder は設 計のすべてのパートを認識してコードを生成することで、名前 の競合を回避します。 ターゲット固有ライブラリの使用 (Embedded Coder は必須です) MATLAB Coder および Embedded Coder を使用して、演算子と関数をター ゲットに合わせた実装に置き換えることができます。Embedded Coder ド キュメンテーションの「コード置換ライブラリ (CRL)」を参照してくださ い。 再入可能でスレッドセーフなコードの作成 [詳細設定]、[メモリ] を選択してください。 マルチスレッド化されたスタンドアロン コードを生成できますか はい、‘parfor’ を使用すればできます。使用している C コンパイラが OpenMP をサポートしているか確認してください。 C++ コードの生成 C++ オプションを選択すると ([コードの生成] のステップで)、MATLAB Coder は C++ コンパイラがコンパイルできる C コード (拡張子は .cpp) を 生成します。 MATLAB Coder は 2 次元配列をどのように処理しますか?
MATLAB Coder は、2 次元配列を常に 1 次元配列に変換し、1 次元配列 にインデックスを設定する C コードを生成します。 • 生成されたスタンドアロン C コードを MATLAB 上で直接検証できますか ? コードを生成したら、[生成] の横にある [テスト] をクリックします (Embedded Coder が必要です)。また、MATLAB 単体テスト フレームワー クでこれを使用することができます。 MEX ファイルに実装されているランタイムチェックの機能を、C コ ードにも実装できますか? はい、R2015b から実装可能です。[詳細設定]、[デバッグ]ペインの[実行 時エラーチェックの生成]を有効にします。 便利な関数 詳細についてはドキュメントをご覧ください。 coder.ceval 既にもっている外部 C 関数を生成された C コードから呼び出します coder.cstructname 使用する MATLAB 構造体用に生成された C 構造体の名前を指定します coder.inline サブ関数のインライン化を行います。 MATLAB のサブ関数内で coder.inline(‘always’) が使われる場合、対応 するコードが生成された C コード内でイン ライン化されます coder.target ‘target’ を実行している場合は true を返 します。例: if isempty(coder.target) % MATLAB 実行時に使用されるコード else % コード生成時に使われるコード end coder.nullcopy 「ゼロ」と定義された変数に対して、初期 化ステートメントを抑止します。結果的に コードはやや高速化しますが、読み取られ る前に、すべての変数のスライスが書き込 まれていることを必ず確認する必要があり ます coder.config コマンドラインで “codegen” コマンドによ り C コードを生成する場合、必要なすべて のオプションを設定するためにコンフィグ レーションオブジェクトを生成します coder.cinclude 生成されたコードにヘッダー ファイルを含 めます。C コードが外部のヘッダー ファイ ルを必要とする場合に、coder.ceval と併用 すると便利です。