C関数
C プログラミング言語から関数をインポートできるようにする、回路図エディターの C 関数コンポーネントの説明。
C 関数コンポーネントを使用すると、C プログラミング言語を使用して任意の関数を持つコンポーネントを実装できます。
他の信号処理コンポーネントと同様に、C関数はブロックの機能を定義する入力、出力、および関数で構成されています。このセクションでは、C関数コンポーネントの各タブとサブタブで設定できるオプションについて詳しく説明します。
さらに、C 関数では、ライブラリ インポート タブを介して追加のライブラリ ファイル (.dll、.so、.a) を追加したり、追加ソース タブを介して外部 C/C++ 言語ソース ファイルを追加したりできます。
一般タブ
このタブでは、C関数コンポーネントの名前、実行速度、入力、出力、グローバル変数、パラメータなど、C関数コンポーネントの一般的なプロパティを定義できます。図1は「一般」タブのユーザーインターフェースを示しています。

入力と出力
入力端子と出力端子は、それぞれ「入力」タブと「出力」タブ内で定義されます。
C 関数コンポーネントに新しいターミナルを追加するには、テーブルに新しい要素を追加するための緑色のプラス記号ボタンをクリックするだけです (図 2 )。
端末名
コンポーネント上のすべての端子には、一意の名前を付ける必要があります。新しい端子を追加すると、その名前は自動的に設定されます。端子の名前を変更するには、変更したい名前をダブルクリックし、新しい名前を入力してください。
端末に名前を付けるときは、次の 2 つの規則に従うことが重要です。
- 名前列は空にできません。
- 名前にスペースを含めることはできません。

タイプ
「タイプ」列では、端末の信号タイプを定義できます。信号タイプは以下の4つの値に設定できます(図3 )。
- 継承、
- 本物、
- int 、および
- uint 。

信号値の型継承は、入力端子と出力端子で異なる意味を持ちます。
入力端子の信号タイプが継承に設定されている場合、その端子は接続されている端子から信号タイプを継承します。
出力端子の信号タイプが継承に設定されている場合、端子の信号タイプは内部ルールによって決定されます。
real、int 、 uintの値は、端子の信号タイプを明示的に設定するために使用されます。入力端子の信号タイプが明示的に設定されている場合、同じ信号タイプの端子のみがその端子に接続できます。
信号データ型の詳細については、信号タイプのドキュメントを参照してください。
寸法
「ディメンション」列を使用して、端子の信号ディメンションを定義できます。信号ディメンションは、 inheritまたは整数(例:1)のいずれかで指定できます。信号値タイプと同様に、信号値ディメンションinherit は入力端子と出力端子で異なる意味を持ちます。
入力端子の信号次元が継承に設定されている場合、その端子は接続されている端子から信号次元を継承します。
出力端子の信号次元が継承するように設定されている場合、端子は信号次元が最も大きい入力端子から信号次元を継承します。
直接フィードスルー
[直接フィードスルー]列 (図 4 ) には、端子が直接フィードスルー端子であるかどうかを決定するチェックボックスがあります。
端子が直接フィードスルーとして定義されている場合、その電流値によってコンポーネントの出力の 1 つの電流値が決定されることを意味します。
入力端子および/または出力端子が直接フィードスルーとして設定されているかどうかに応じて、Cコードの作成時に特定のルールに従う必要があります。これにより、コンパイルが成功し、シミュレーション結果が有効になります。これらのルールについては、 「Cコードの記述ルール」を参照してください。
直接フィードスルー端子の詳細については、コンポーネントのソートと代数ループのドキュメントを参照してください。

端末の取り外し
端末を削除するには、削除する端末の行にある赤いマイナス記号ボタン (図 5 ) をクリックし、 [OK]をクリックします。

端末の並べ替え
端末の順序を変更するには、まず移動する端末の行を選択し、上矢印記号または下矢印記号のいずれかをクリックします。

グローバル変数
グローバル変数は、すべてのコンポーネントの関数からアクセスできます(図7および図12 )。グローバル変数の値は、異なる関数呼び出し間で保持されます。
変数名
ターミナル名のセクションで定義されているターミナルの命名規則は、グローバル変数の命名にも適用する必要があります。
変数型
「Type」列を使用して、グローバル変数の信号型を定義できます。信号型は、(図7 ) real 、 int 、 uintのいずれかに設定できます。
信号データ型の詳細については、信号型のドキュメントをご覧ください。
ベクトルと行列
グローバル変数はベクトルや行列としても定義できます。ベクトルや行列のサイズは、図7のvar2およびvar3変数に示すように、静的に定義する必要があります。

変数の削除
変数はターミナルと同じ方法で削除されます (ターミナルの削除のセクションを参照してください)。
パラメータ
パラメータを使用すると、C関数コンポーネントに外部変数を渡すことができます。これらの外部変数は、名前空間を介してC関数に伝播されます。
C 関数コンポーネント内で外部変数を参照できるようにするには、パラメーターテーブル内で宣言する必要があります (図 7 )。そうしないと、エラーが発生します (図 9 )。
グローバル変数にアクセスするのと同じ方法で、コンポーネントの関数内でパラメータにアクセスできます。

パラメータ名
「端末名」セクションで以前に定義した端末命名規則も適用する必要があります。
パラメータタイプ
「Type」列を使用して、パラメータの信号タイプを定義できます。信号タイプは、 real 、 int 、 uint のいずれかに設定できます。
信号データ型の詳細については、信号タイプのドキュメントを参照してください。
パラメータの削除
変数は端末と同じ方法で削除されます (「入力と出力」セクションを参照してください)。
Pythonの反復可能オブジェクトを使ってCの配列を初期化する
パラメータがPythonの反復可能オブジェクト(リスト、セット、またはタプル)として定義されている場合、自動的にC言語の配列初期化子に変換されます。例えば、 param1 = [1, 2, 3] は{1, 2, 3} に変換されます。
機能
関数タブでは、任意のinit 、 output 、およびupdate関数を定義できます。
関数を実装したら、 「構文チェック」ボタン (図 10 ) を押して、コードが構文的に正しいかどうかを確認できます。

コードが構文的に正しい場合は「エラーは見つかりません」というメッセージが表示されます。そうでない場合は、コード検証ダイアログが表示されます(図11 )。コード検証ダイアログ内のすべてのエラーメッセージには、ヘッダーと内容が含まれています。ヘッダーをクリックすると、エラーの原因となった関数に自動的にリダイレクトされます。

C関数は標準のmath.hライブラリの数学関数と定数のサポートを組み込んでいます。
Cコードの書き方のルール
C コードを書くときは、従う必要がある特定のルールがあります。
- 入力と出力はinit_fncで初期化しないでください。
- 反復処理ごとに値を保持するすべての変数は、 stateとして定義する必要があります。出力は反復処理ごとに値を保存できません。
- 入力が直接フィードスルーでない場合は、 output_fncで直接使用することはできません。
- 出力がフィードスルーでない場合、 output_fncで計算することはできません。この場合、出力はupdate_fncで計算する必要があります。このタイプの出力は状態変数として動作します。output_fncで出力値を使用することはできますが、値を代入することはできません。
- 出力がフィードスルーの場合、その値はoutput_fncで計算する必要があります。
- コンポーネント上の端子フィードスルーは、C コードに従って設定する必要があります。
出力関数(output_fnc)
output_fnc関数は、コンポーネントの出力信号を更新するために使用され、各シミュレーション ステップで呼び出されます。
output_fnc関数の例

init_fnc関数でグローバル変数にアクセスする例
初期化関数(init_fnc)
init_fnc関数は、コンポーネントの状態変数を初期化するために使用され、シミュレーションの開始時、最初のシミュレーション ステップの前に呼び出されます。

更新関数 (update_fnc)
update_fnc関数は、コンポーネントの状態変数を更新するために使用され、 output_fnc関数の後の各シミュレーション ステップで呼び出されます。

ライブラリインポートタブ
ベンダーがコントローラアルゴリズムの実装の詳細を隠蔽したい場合、何らかのプリコンパイル済みライブラリがエンドユーザーと共有されます。通常、これらのライブラリは、Windowsオペレーティングシステムの場合はダイナミックリンクライブラリ(.dll)、Linuxオペレーティングシステムの場合は共有オブジェクト(.so)、一部の独自アーキテクチャの場合はアーカイブライブラリ(.a)の形式で提供されます。
ライブラリ インポートタブでは、これらのライブラリ ファイルをインポートできます。
DLL/SOライブラリ
C 関数に加えて、ライブラリ インポートタブでは共有ライブラリ (Windows の場合は .dll、Linux の場合は .so) とヘッダー ファイルをインポートできます。共有ライブラリ ファイルに対応するヘッダー ファイルには、共有ライブラリにある関数プロトタイプが含まれている必要があります (共有ライブラリの関数のサブセットにすることができます)。共有ライブラリのヘッダー ファイルには、共有ライブラリにない関数を含めることはできません。共有ライブラリとヘッダー ファイルのパスの近くにあるブラシアイコンをクリックするだけで、インポートを削除できます。パスの選択 (相対または絶対) はモデルの保存時に保存されます。これは、コンパイルされたモデルを別の場所に移動する場合に非常に重要です。DLL /SO 関数タブには、ライブラリ インポートタブのユーザー インターフェイスが表示されます。
- コンパイル時のロード- ライブラリは、VHIL アプリケーション (レガシー) のコンパイル中に静的にリンクされます。
- 実行時ロード- シミュレーション開始時にライブラリがロードされます。このロードタイプの主な利点は、共有ライブラリ内の関数実装を変更し、モデルを再コンパイルすることなく変更を適用できることです。変更を適用するには、シミュレーションを停止し、共有ライブラリを再コンパイルして、シミュレーションを再実行するだけです。
DLL とヘッダー ファイルが正常にインポートされると、関数は図 16のように表示されます。
関数プロトタイプをコピーするだけで、「関数」タブ内でDLL関数を呼び出すことができます。図17に例を示します。
台風図書館
Typhoonライブラリは、アーカイブライブラリ(.a)ファイルがTyphoon HILデバイスに適していることを示します。つまり、ソースファイルはHILデバイスで使用されるARM A9および/またはARM A53プロセッサ向けにコンパイルされていることを意味します。
コントローラ アルゴリズムの実装の詳細を非表示にしながらも、HIL デバイス上でシミュレーションをリアルタイムで実行したい場合は、ライブラリ (.a) ファイルを使用すると便利です。
HILデバイスはARM A9またはARM A53プロセッサアーキテクチャを使用しているため、ソースコードをコンパイルするには専用のCコードコンパイラを使用する必要があります。これらのコンパイラは、すべてのTyphoon HILソフトウェアインストールに含まれており、すぐに使用できます。
- ウィンドウズ
- ARM A9
- <installation folder>/compilers/windows/z7/gnu/arm/nt/bin/arm-xilinx-eabi-gcc
- <installation folder>/compilers/windows/z7/gnu/arm/nt/bin/arm-xilinx-eabi-ar
- ARM A53 (Windows):
- <installation folder>/compilers/windows/zu/gnu/aarch64/nt/aarch64-none/bin/aarch64-none-elf-gcc
- <installation folder>/compilers/windows/zu/gnu/aarch64/nt/aarch64-none/bin/aarch64-none-elf-ar
- ARM A9
- リナックス
- ARM A9:
- <installation folder>/compilers/linux/z7/gnu/arm/lin/bin/arm-xilinx-eabi-gcc
- <installation folder>/compilers/linux/z7/gnu/arm/lin/bin/arm-xilinx-eabi-ar
- ARM A53:
- <installation folder>/compilers/windows/zu/gnu/aarch64/lin/aarch64-none/bin/aarch64-none-elf-gcc
- <installation folder>/compilers/windows/zu/gnu/aarch64/lin/aarch64-none/bin/aarch64-none-elf-ar
- ARM A9:
- ARMコンパイラを使用して、すべてのソースコードファイル(.c)をオブジェクトファイル(.o)にコンパイルします。
- ARMアーカイバを使用して、すべてのオブジェクトファイル(.o)を1つのライブラリ(.a)ファイルに結合します。
ライブラリファイルの生成方法を、簡単なソースファイルと適切なヘッダーファイルを用いて例を挙げて説明します。抜粋したコードは以下のとおりです。
<math_functions.h> #ifndef _MATH_FUNCTIONS_ #define _MATH_FUNCTIONS_ double sum(double, double); double sub(double, double); #endif <increment.h> #ifndef _INCREMENT_ #define _INCREMENT_ double increment(double); #endif <sum.c> #include "math_functions.h" double sum(double a, double b) { return a + b; } <sub.c> #include "math_functions.h" double sub(double a, double b) { return a - b; } <increment.c> #include "increment.h" double increment(double a) { return a + 1; }
このリンクでは、ライブラリファイルの生成方法について説明しています。この例では、ARM A53用の.aファイルを生成するコマンドは次のとおりです。
aarch64-none-elf-gcc -Iinclude -c src\increment.c -o src\increment.o aarch64-none-elf-gcc -Iinclude -c src\sub.c -o src\sub.o aarch64-none-elf-gcc -Iinclude -c src\sum.c -o src\sum.o aarch64-none-elf-ar rcs libexample_a53.a src\increment.o src\sub.o src\sum.o
ライブラリファイルを入手したら、ヘッダーファイルと同様にインポートするだけです。これは図18に示されています。
ヘッダーファイルのインポートは、DLL/SOライブラリのインポートとは少し異なります。専用のフィールドはなく、ヘッダーは「追加ソース」タブ( 「追加ソース」タブ)からインポートされます。
追加ソースタブ
このタブでは、C関数に加えて、CおよびC++言語のソースファイル(*.c、*.cpp、*.h)をインポートできます。図19は「追加ソース」タブのユーザーインターフェースを示しています。
すべてのCソースファイルには独自のヘッダーファイルが必要であり、これもインポートする必要があります。インポートするすべてのCファイルに対して1つのヘッダーファイルを作成し、そのヘッダーファイルのみをインポートすることもできます。インポートしたヘッダーファイルから関数プロトタイプをコピーするだけで、「関数」タブ内で関数を呼び出すことができます。図17に例を示します。
C 関数コンポーネントは、すべての HIL デバイスと VHIL でサポートされています。