仕事では、最近、組み込みアプリケーション用の C コードを生成できる Simulink Coder を含む MATLAB/Simulink のトレーニングを受けました。やってみたかったので、Arduinoを買って飛び込みました。 簡単なスケッチは問題なく書けますが、Simulinkで生成されたコードを統合しようとすると、壁にぶち当たります。
最初は Arduino IDE を使用し、次に Eclipse と Arduino プラグインを使用し、最後に Xcode とembedXcode テンプレートを使用しました。(私のSimulinkの仕事用マシンはPCですが、「無許可のソフトウェア」をインストールすることは許可されていないので、残りは自宅のMacで行いました。) 3つとも同じavr-gccコンパイラを使用しています。
3 つすべてに同じ障害点がありました。生成された関数呼び出しで「未定義の参照」エラーが発生しました。これは、基本的な構文やヘッダーのインクルードではなく、リンカの問題であると考えています。Eclipse と Xcode のコード補完は正常に機能しており、コール シグネチャを何らかの方法で変更すると、エラーが変化します。データ構造への参照を作成できます。
私の知る限り、デフォルトのメイクファイルは、フォルダー内のすべてのファイルをコンパイルおよびリンクするように設定されています。少なくとも Xcode を使用して、「mass_model2.o」ファイルが作成されています。最後に、"myFunction.c" および "MyFunction.h" ファイルを個別に単純な関数呼び出しで手動で作成すると、デバイス上で期待どおりにコンパイルおよび実行されます。
必死になって、生成された「.c」ファイルの内容全体をコピーし、同じ「.h」参照を保持して、メイン スケッチ ファイルの mysetup()
とloop()
関数の後に貼り付け、プロジェクトから「.c」ファイルを削除しました。 . これは実際にコンパイルして実行しました!ただし、生成されたコードを使用するために手を加える必要はありません。
これを適切にコンパイルおよびリンクするにはどうすればよいですか?
Simulink コードは非常に冗長なので、重要な部分を次に示します。
mass_model2.h の抜粋:
#include "rtwtypes.h"
#include "mass_model2_types.h"
/* External inputs (root inport signals with auto storage) */
typedef struct {
int16_T PotPos; /* '<Root>/PotPos' */
} ExternalInputs_mass_model2;
/* External outputs (root outports fed by signals with auto storage) */
typedef struct {
int16_T ServoCmd; /* '<Root>/ServoCmd' */
} ExternalOutputs_mass_model2;
/* External inputs (root inport signals with auto storage) */
extern ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
extern ExternalOutputs_mass_model2 mass_model2_Y;
/* Model entry point functions */
extern void mass_model2_initialize(void);
extern void mass_model2_step(void);
mass_model2.c の抜粋:
#include "mass_model2.h"
#include "mass_model2_private.h"
/* External inputs (root inport signals with auto storage) */
ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
ExternalOutputs_mass_model2 mass_model2_Y;
/* Model step function */
void mass_model2_step(void)
{
// lots of generated code here
}
/* Model initialize function */
void mass_model2_initialize(void)
{
// generated code here
}
他の参照ヘッダー「rtwtypes.h」と「mass_model2_private.h」は、生成されたコードで使用される特定の型を定義しますint16_T
。これらのファイルはプロジェクトに含まれており、それらに関連するエラーは表示されません。
私のスケッチ ファイルでは、setup()
関数は を呼び出しますmass_model2_initialize()
。loop()
入力 (ポテンショメータ) を読み取り、 に値を設定しmass_model2_U.PotPos
、 を呼び出しますmass_model2_step()
。次にmass_model2_Y.ServoCmd
、値を取得して出力用のサーボに書き込み、最後にdelay()
.