このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。
コードジェネレーターによってモデルで定義したとおりにアルゴリズムコードが生成されます。外部コード統合ワークフローの選択で説明されている手法を使用してモデルに外部コード(カスタムコードやレガシコードなど)を含めることができます。
コードジェネレーターは,生成されたモデルコードを実行するインターフェイスも提供します。このインターフェイスとモデル コードは一緒にコンパイルされ、実行可能プログラムが作成されます。次の図は、実行ファイルの高水準オブジェクト指向図を示します。
リアルタイムプログラムのオブジェクト指向図
一般に,生成コードの組み込みスタイルとラピッドプロトタイプとでは,モデル実行ドライバーの概念設計に相違はありません。以下の節では,シミュレーション(非リアルタイム)とリアルタイムの両方のシングルタスク環境とマルチタスク環境のモデルの実行について説明します。ほとんどのモデルコードについて,マルチタスク環境ではモデルの実行が最も効率的になります(最速のサンプルレート)。
以下の概念は,モデルコードの実行の仕組みを説明する際に役立ちます。
初始化:
は,インターフェイスコードとモデルコードを初期化します。模型
_initialize
ModelOutputs:現時点でサンプルヒットをもつモデル内のすべてのブロックを呼び出し,それらに出力を生成させます。
は,メジャータイムステップまたはマイナータイムステップで実行できます。メジャータイムステップでは,出力は指定されているシミュレーションのタイムステップです。マイナータイムステップでは,連続状態を更新するため,インターフェイスによって微係数が積分されます。模型
_output
ModelUpdate:
により,現時点でサンプルヒットをもつブロックが呼び出され,それらに離散状態や同様のタイプのオブジェクトを更新させます。模型
_update
ModelDerivatives:連続状態をもつモデル内のブロックを呼び出し,微係数を更新させます。
は,マイナータイムステップにおいてのみ呼び出されます。模型
_derivatives
ModelTerminate:
は,有限時間で実行するよう設計されている場合にプログラムを終了します。それにより,リアルタイムのモデルデータ構造体は破棄され,メモリの割り当ては解除され,データのファイルへの書き込みが可能となります。模型
_terminate
リアルタイムのプログラムでは,CPU時間が100%必要というわけではありません。この要件により,自由時間にバックグラウンドタスクを実行する機会が与えられます。
バックグラウンドタスクには,データをバッファーまたはファイルに書き込んだりする操作も含まれ,これによってサードパーティ製のデータ監視ツールによるプログラムデータへのアクセスや,プログラムパラメーターの更新が可能となります。
しかし,モデルコードのリアルタイム実行を行うには,プログラムがバックグラウンドタスクをプリエンプトできることが重要となります。
プログラムがタスクを管理する方法は,操作環境の機能によって異なります。
リアルタイムのプログラムでは,他のタスク呼び出しが(割り込みまたはリアルタイムオペレーティングシステムの作業プリミティブのどちらかによって)実行される前にモデルのコードの実行を完了させるようにするには,タスクを呼び出すタイミングに注意が必要です。このタイミングには,外部ハードウェアとのデータの読み取りや書き込みのための時間も含まれています。
次の図は,割り込みのタイミングを示しています。
タスクのタイミング
サンプルの間隔は,タスクの呼び出し間でモデルコードを実行するのに十分な長さでなければなりません。
上の図では2つの隣接した縦矢印の間の時間がサンプルの間隔です。上の図の空のボックスは,1つのステップを間隔内で完了できるうえ,バックグラウンドタスクのための時間もさらに確保できるプログラムの例を示しています。図の下方にあるグレーのボックスは,サンプルの間隔が短すぎた場合にどうなるかを示しています。タスクが完了する前に他のタスク呼び出しが実行されます。そのようなタイミングは,実行エラーとなります。
リアルタイムプログラムが恒久的に実行されるよう設計されている場合(つまり,而
ループが終了しないよう最終時間が0または無限の場合),シャットダウンコードは実行されません。
タイミングエンジンの仕組みの詳細については,絶対時間と経過時間の計算を参照してください。
エクスターナルモードにより,仿金宝app真软件®ブロック線図と生成コードから作成されるスタンドアロンプログラムとの間の通信が可能となります。このモードでは、リアルタイムのプログラムは、プロセス間通信サーバーとして機能し、Simulink エンジンからの要求に対して応答します。
デバッグ用のモデルの構成では,モデル実行の完了時にシステムの状態,出力,時間を垫ファイルに保存する方法について説明しています。データログ記録を行う関数LogTXY
は,シングルタスク環境とマルチタスク環境とで異なった動作をします。
シングルタスク環境やマルチタスク環境でLogTXY
がどのように呼び出されるかについて見ると,シングルタスクでは,LogTXY
がModelOutputs
の後で呼び出されることに注意してください。このModelOutputs
の呼び出しの間,時間tでヒットするブロックが実行されます。一方で,マルチタスクでは,LogTXY
は,時間tでヒットするブロックとタスク識別子が0のブロックのみを実行するModelOutputs (tid = 0)
の後で呼び出されます。これにより,シングルタスクとマルチタスクのログ記録では,ログが記録された値における違いが存在します。特に,周期が1.0秒の高速サンプル時間と10.0秒の低速サンプル時間の2種類のサンプル時間をもつモデルを検討します。時間t = k * 10 k = 0、1、2……では,高速(tid = 0
)ブロックと低速(tid = 1
)ブロックの両方が実行されます。マルチタスクモードで実行する場合,LogTXY
が呼び出されると,低速ブロックは実行しますが,前回の値のログが記録されます。一方,シングルタスクでは,現在の値のログが記録されます。
もう一つの違いは,使子系统にデータをログ記録する際に生じます。启用子系统内でイネーブル端子と高速ブロックを駆動する低速信号をもつような启用子系统を検討します。この場合,有効な信号の評価は低速タスクで生じ,高速ブロックは1つのサンプル期間の遅延を確認します。このように,ログが記録された値は,これらの相違を示します。
シングルタスクとマルチタスクでログが記録されたデータの相違について要約すると,相違がみられるのは以下のような場合です。
ルート外港ブロックのサンプル時間が,最高速サンプル時間より遅い
状態をもつブロックのサンプル時間が,最高速サンプル時間より遅い
ブロックが启用子系统にあり,イネーブル端子を駆動する信号が,この启用子系统内のブロックのレートより遅い
最初の2つのケースでは,シングルタスクとマルチタスクとでログが記録された値が異なる場合でも,モデルの結果は相違ありません。実際の相違は,ログ記録がどこで(どの時点で)行われたかという点のみとなります。3番目(启用子系统)のケースでは,リアルタイム環境で見られる遅延となります。
この疑似コードは,非リアルタイムのシングルタスクシステムのモデルの実行を示しています。
main(){初始化While (time < final time) ModelOutputs——主要时间步长。LogTXY——记录时间、状态和根输出。ModelUpdate——主要的时间步骤。集成——对具有连续状态的模型进行小时间步长的集成。ModelDerivatives Do 0或更多ModelOutputs ModelDerivatives EndDo——迭代次数取决于求解器积分导数以更新连续状态。EndWhile终止}
最初に初期化フェーズが開始します。これは,モデル状態の初期化と実行エンジンの設定で構成されています。その後でモデルはステップごとに実行されます。最初にModelOutputs
が時間tに実行され,次にワークスペースI / Oデータがログに記録され,ModelUpdate
によって離散状態が更新されます。次に,モデルに連続状態がある場合,ModelDerivatives
は,時間
(ここで,hはステップのサイズ)の状態を生成するため,連続状態の微係数を積分します。そして,時間は
に向かって進み,処理が繰り返されます。
モデル実行のModelOutputs
フェーズとModelUpdate
フェーズの間は,時間内に現在の位置に到達したブロックのみが実行されます。
この疑似コードは,非リアルタイムのマルチタスクシステムのモデルの実行を示しています。
main(){初始化While (time < final time) ModelOutputs(tid=0)——主要时间步长。LogTXY——记录时间、状态和root——输出。ModelUpdate(tid=0)——主要时间步长。集成——对具有连续状态的模型进行小时间步长的集成。ModelDerivatives Do 0或更多ModelOutputs(tid=0) ModelDerivatives EndDo(迭代次数取决于求解器。)积分导数来更新连续状态。endintegration For i=1:NumTids ModelOutputs(tid=i)——主要时间步长。ModelUpdate(tid=i)——主要时间步骤。终止}
マルチタスク操作は,出力関数と更新関数がこれらの関数に渡される“タスク識別子”(tid
)によって分割されるため,シングルタスク実行より複雑です。これにより,重複割り込みを使用し,異なるタスク識別子をもつこれらの関数を複数回呼び出すことが可能となります。また,リアルタイムオペレーティングシステムを使用すれば,複数のタスクが可能となります。シミュレーションでは,リアルタイムシステムにプリエンプションが存在しない場合に発生順にコードを実行することで,複数のタスクがエミュレートされます。
マルチタスク実行では,タスクのレートは基本レートの倍数だと仮定されます。金宝app仿真软件製品では,固定ステップマルチタスクモデルを作成した場合,これが強制されます。マルチタスクの実行ループは,ModelOutputs
およびModelUpdate
に対してタスク識別子(tid
)の引数を使用する点を除き,シングルタスクの実行ループと非常に似ています。
金宝app仿真软件编码器™ではなく,ターゲットファイルで生成されたコードからのtid
値は使用できません。特定のサブシステムまたは関数タイプのコードを生成する際,金宝app仿真软件编码器はtid
の使用を追跡します。ターゲットファイル内でコードを生成する際は,スコープがサブシステムまたは関数のタイプをもたないため,この引数を追跡できません。そのため,tid
が未定義の変数となってターゲットファイルのコンパイルが失敗します。
この疑似コードは,モデルが割り込みレベルで実行されるリアルタイムシングルタスクシステムにおけるモデルの実行を示しています。
rtOneStep(){检查中断溢出启用"rtOneStep"中断ModelOutputs——主要时间步长。LogTXY——记录时间、状态和根输出。ModelUpdate——主要的时间步骤。集成——对模型的小时间步进行集成——具有连续状态。ModelDerivatives做0或更多ModelOutputs ModelDerivatives EndDo(迭代次数取决于求解器)积分导数来更新连续状态。main(){初始化(包括安装rtOneStep作为一个中断服务例程,ISR,用于实时时钟)。While(time < final time)后台任务。EndWhile掩码中断(禁止rtOneStep执行)完成任何后台任务。 Shutdown }
リアルタイムのシングルタスク実行は,コードが自由に実行されるのではなく周期的なタイマーの割り込みによって関数rt_OneStep
が駆動されるという点を除き,非リアルタイムなシングルタスク実行と非常に似ています。
プログラムの基本サンプルレートで指定した区間では,モデルコードを実行するために割り込みサービスのルーチン(ISR)がバックグラウンドタスクをプリエンプトします。基本サンプルレートは,モデルで最高速となります。モデルが連続ブロックをもつ場合,積分ステップサイズにより基本サンプルレートが決定されます。
たとえば,モデルコードが100 Hzで動作するコントローラーの場合,0.01秒ごとにバックグラウンドタスクが割り込まれます。この割り込みの間、コントローラーはアナログ デジタル コンバーター (ADC) からの入力を読み取り、出力を計算し、これらの出力をデジタル アナログ コンバーター (DAC) へ書き込み、その状態を更新します。そして、プログラム コントロールはバックグラウンド タスクに戻ります。これらのステップは、次の割り込みの前に実行しなければなりません。
この疑似コードは,モデルが割り込みレベルで実行されるリアルタイムマルチタスクシステムでモデルがどのように実行されるかを示しています。
rtOneStep() {Check for interrupt overflow Enable "rtOneStep" interrupt ModelOutputs(tid=0)——主要时间步长。LogTXY——记录时间、状态和根输出。ModelUpdate(tid=0)——主要时间步长。集成——对具有连续状态的模型进行小时间步长的集成。ModelDerivatives Do 0或更多ModelOutputs(tid=0) ModelDerivatives EndDo(迭代次数取决于求解器。)积分导数和更新连续状态。endintegration For i=1:NumTasks If (hit in task i) ModelOutputs(tid=i) ModelUpdate(tid=i) EndIf EndFor} main(){初始化(包括安装rtOneStep作为一个中断服务例程,ISR,用于实时时钟)。While(time < final time)后台任务。EndWhile掩码中断(禁止rtOneStep执行)完成任何后台任务。 Shutdown }
リアルタイムなマルチタスク環境においてモデルを割り込みレベルで実行するのは,重複割り込みがタスクの同時実行に使用される点を除き,前記のシングルタスク環境に非常に似ています。
リアルタイムオペレーティングシステムの作業プリミティブ使用時のシングルタスク環境またはマルチタスク環境でのモデルの実行は,上記で説明した割り込みレベルの例に非常に似ています。以下の疑似コードは,リアルタイム作業プリミティブを使用したシングルタスクモデル用です。
tSingleRate() {MainLoop:如果clockSem已经"given",则由于溢出而出错。等待clockSem ModelOutputs——主要时间步长。LogTXY——记录时间,状态和根——输出ModelUpdate——主要时间步骤集成——次要时间步骤集成——对于具有连续状态的模型。ModelDerivatives做0或更多ModelOutputs ModelDerivatives EndDo(迭代次数取决于求解器)积分导数来更新连续状态。main(){初始化启动/生成任务"tSingleRate"。启动时钟,对一个clockSem信号量做一个“semGive”。等待“模型运行”信号量。关闭}
このシングルタスク環境では,モデルはリアルタイムオペレーティングシステムの作業プリミティブとして実行されます。この環境では,シングルタスク(tSingleRate
)を作成し,モデルコードを実行します。このタスクは、クロック ティックが実行されると呼び出されます。クロック ティックにより、clockSem
(クロックのセマフォ)がモデルタスク(tSingleRate
)に与えられます。モデルのタスクは,実行前にセマフォを待機します。クロックティックは,モデルの基本的なステップサイズ(基本レート)で実行されます。
この疑似コードは,リアルタイム作業プリミティブを使用したマルチタスクモデル用です。
tSubRate(subTaskSem,i){循环:等待信号量subTaskSem。ModelOutputs(tid=i) ModelUpdate(tid=i) EndLoop} tBaseRate() {MainLoop:如果clockSem已经"given",则由于溢出而出错。Wait on clockSem For i=1:NumTasks If (hit in task i)如果任务i正在执行,则由于溢出导致错误输出。对任务i. EndIf EndFor ModelOutputs(tid=0)——主要时间步长执行“semGive”。LogTXY——记录时间、状态和根输出。ModelUpdate(tid=0)——主要时间步长。循环:——对具有连续状态的——模型进行小时间步长的集成。ModelDerivatives Do 0或更多ModelOutputs(tid=0) ModelDerivatives EndDo(迭代次数取决于求解器)。积分导数来更新连续状态。main(){初始化启动/生成任务"tSubRate"。 Start/spawn task "tBaseRate". Start clock that does a "semGive" on a clockSem semaphore. Wait on "model-running" semaphore. Shutdown }
このマルチタスク環境では,モデルはリアルタイムオペレーティングシステムの作業プリミティブを使用して実行されます。そのような環境においてモデルのコードを実行するには,いくつかのモデルタスク(tBaseRate
およびいくつかのtSubRate
タスク)が必要となります。基本レートタスク(tBaseRate
)はサブレートタスクより優先されます。tid = 1
のサブレートタスクは,tid = 2
のサブレートタスクより優先されるという具合です。この基本レート タスクは、クロック ティックが実行されると呼び出されます。クロック ティックにより、clockSem
がtBaseRate
に与えられます。tBaseRate
が最初にすることは,時間内に現在の位置でヒットをもつサブタスクにセマフォを与えることです。基本レートタスクのほうが優先順位が高いため,実行が継続されます。次に,サンプル時間が最も高速なモデルのブロックで構成される最も高速なタスク(tid = 0
)を実行します。この実行の後で、クロックのセマフォの待機を再開します。クロック ティックは、モデルの基本的なステップ サイズで実行するために構成されます。
ラピッドプロトタイピングプログラムのフレームワークでは,モデル定義間で変更のない一般的なアプリケーションプログラミングインターフェイス(API)が装備されています。
嵌入式编码器®製品は,組み込みプログラムフレームワークと呼ばれる別のフレームワークを提供しています。組み込みプログラムフレームワークでは,モデル向けに調整したAPIを最適化して提供しています。生成コードの組み込みスタイルを使用する場合,組み込みシステムでどのようにコードを実行するかをモデル作成します。したがって,モデル内の定義は,組み込みターゲットに対して特定のものである必要があります。モデル名,パラメーター,信号ストレージクラスなどの項目は,コードの組み込みスタイルのAPIの一部に含まれます。
生成コードの組み込みスタイルとラピッドプロトタイピングの主な相違点は,後者には含まれているエントリポイント関数が少ないという点です。組み込みスタイルのコードは,1つの関数
のみをもつように構成できます。模型
_step
このためモデルの実行コードは,循环…EndLoop
ステートメントを排除し,ModelOutputs
、LogTXY
およびModelUpdate
を1つのステートメント
にまとめます。模型
_step
生成された組み込みコードの実行方法の詳細については,モデルのエントリポイント関数に対するCコード生成の構成を参照してください。