C関数

C プログラミング言語から関数をインポートできるようにする、回路図エディターの C 関数コンポーネントの説明。

C 関数コンポーネントを使用すると、C プログラミング言語を使用して任意の関数を持つコンポーネントを実装できます。

他の信号処理コンポーネントと同様に、C関数はブロックの機能を定義する入力、出力、および関数で構成されています。このセクションでは、C関数コンポーネントの各タブとサブタブで設定できるオプションについて詳しく説明します。

さらに、C 関数では、ライブラリ インポート タブを介して追加のライブラリ ファイル (.dll、.so、.a) を追加したり、追加ソース タブを介して外部 C/C++ 言語ソース ファイルを追加したりできます。

注: Typhoon HIL Control Centerソフトウェアの以前のバージョン(2023.2以前)で作成された一部のモデルでは、Cコード検証および代数ループ検出のアルゴリズムがより厳格になっているため、コンパイル(検証)エラーまたは警告が報告される場合があります。代数ループエラーが検出された場合、ほとんどの場合、ループを中断するためのユニット遅延コンポーネントを追加することで修正できます。

一般タブ

このタブでは、C関数コンポーネントの名前、実行速度、入力、出力、グローバル変数、パラメータなど、C関数コンポーネントの一般的なプロパティを定義できます。図1は「一般」タブのユーザーインターフェースを示しています。

1 .全般タブ

入力と出力

入力端子と出力端子は、それぞれ「入力」タブ「出力」タブ内で定義されます。

C 関数コンポーネントに新しいターミナルを追加するには、テーブルに新しい要素を追加するための緑色のプラス記号ボタンをクリックするだけです (図 2 )。

端末名

コンポーネント上のすべての端子には、一意の名前を付ける必要があります。新しい端子を追加すると、その名前は自動的に設定されます。端子の名前を変更するには、変更したい名前をダブルクリックし、新しい名前を入力してください。

端末に名前を付けるときは、次の 2 つの規則に従うことが重要です。

  • 名前列は空にできません。
  • 名前にスペースを含めることはできません。
2テーブルに新しい要素を追加するためのボタン

タイプ

「タイプ」列では、端末の信号タイプを定義できます。信号タイプは以下の4つの値に設定できます(図3 )。

  • 継承
  • 本物
  • int 、および
  • uint
3端末の信号タイプの変更

信号値の型継承は、入力端子と出力端子で異なる意味を持ちます。

入力端子の信号タイプが継承に設定されている場合、その端子は接続されている端子から信号タイプを継承します。

出力端子の信号タイプが継承に設定されている場合、端子の信号タイプは内部ルールによって決定されます。

real、intuintの値は、端子の信号タイプを明示的に設定するために使用されます。入力端子の信号タイプが明示的に設定されている場合、同じ信号タイプの端子のみがその端子に接続できます。

信号データ型の詳細については、信号タイプのドキュメントを参照してください。

寸法

「ディメンション」列を使用して、端子の信号ディメンションを定義できます。信号ディメンションは、 inheritまたは整数(例:1)のいずれかで指定できます。信号値タイプと同様に、信号値ディメンションinherit は入力端子と出力端子で異なる意味を持ちます。

入力端子の信号次元が継承に設定されている場合、その端子は接続されている端子から信号次元を継承します。

出力端子の信号次元が継承するように設定されている場合、端子は信号次元が最も大きい入力端子から信号次元を継承します。

直接フィードスルー

[直接フィードスルー]列 (図 4 ) には、端子が直接フィードスルー端子であるかどうかを決定するチェックボックスがあります。

端子が直接フィードスルーとして定義されている場合、その電流値によってコンポーネントの出力の 1 つの電流値が決定されることを意味します。

入力端子および/または出力端子が直接フィードスルーとして設定されているかどうかに応じて、Cコードの作成時に特定のルールに従う必要があります。これにより、コンパイルが成功し、シミュレーション結果が有効になります。これらのルールについては、 「Cコードの記述ルール」を参照してください。

直接フィードスルー端子の詳細については、コンポーネントのソート代数ループのドキュメントを参照してください。

4直接フィードスルーカラム

端末の取り外し

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

5端子取り外しボタン

端末の並べ替え

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

6 .端末の並べ替え

グローバル変数

グローバル変数は、すべてのコンポーネントの関数からアクセスできます(図7および図12 )。グローバル変数の値は、異なる関数呼び出し間で保持されます。

変数名

ターミナル名のセクションで定義されているターミナルの命名規則は、グローバル変数の命名にも適用する必要があります。

変数型

「Type」列を使用して、グローバル変数の信号型を定義できます。信号型は、(図7realintuintのいずれかに設定できます。

信号データ型の詳細については、信号型のドキュメントをご覧ください。

ベクトルと行列

グローバル変数はベクトルや行列としても定義できます。ベクトルや行列のサイズは、図7var2およびvar3変数に示すように、静的に定義する必要があります。

7 .グローバル変数のシグナルタイプの変更

変数の削除

変数はターミナルと同じ方法で削除されます (ターミナルの削除のセクションを参照してください)。

恣意的な定義

このセクションでは、C言語でサポートされている変数を任意に定義できます。図8は、 「一般」タブの「任意定義」セクションのユーザーインターフェースを示しています。

注:任意のCコード変数型は、任意の定義セクションで宣言できます。型を宣言せずに変数を導入した場合、デフォルトでint型が割り当てられます。
注意:任意の定義セクションで構造体 (struct) を定義する場合、C コードのエクスポートはサポートされません。
8任意の定義

パラメータ

パラメータを使用すると、C関数コンポーネントに外部変数を渡すことができます。これらの外部変数は、名前空間を介してC関数に伝播されます。

C 関数コンポーネント内で外部変数を参照できるようにするには、パラメーターテーブル内で宣言する必要があります (図 7 )。そうしないと、エラーが発生します (図 9 )。

グローバル変数にアクセスするのと同じ方法で、コンポーネントの関数内でパラメータにアクセスできます。

9パラメータparam1が名前空間で定義されていないために発生したエラー

パラメータ名

「端末名」セクションで以前に定義した端末命名規則も適用する必要があります。

パラメータタイプ

「Type」列を使用して、パラメータの信号タイプを定義できます。信号タイプは、 realintuint のいずれかに設定できます。

信号データ型の詳細については、信号タイプのドキュメントを参照してください。

パラメータの削除

変数は端末と同じ方法で削除されます (「入力と出力」セクションを参照してください)。

Pythonの反復可能オブジェクトを使ってCの配列を初期化する

パラメータがPythonの反復可能オブジェクト(リスト、セット、またはタプル)として定義されている場合、自動的にC言語の配列初期化子に変換されます。例えば、 param1 = [1, 2, 3] は{1, 2, 3} に変換されます。

注意: Python 反復可能オブジェクトの自動変換では、数値や文字列などの単純な型のみがサポートされます。

機能

関数タブでは、任意のinitoutput 、およびupdate関数を定義できます。

関数を実装したら、 「構文チェック」ボタン (図 10 ) を押して、コードが構文的に正しいかどうかを確認できます。

10構文チェックボタン

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

11 C関数コンポーネントのエラーを表示するためのダイアログ

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関数の例

12 output_fnc関数の例

init_fnc関数でグローバル変数にアクセスする例

初期化関数(init_fnc)

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

13 init_fnc関数の例

更新関数 (update_fnc)

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

14 update_fnc関数の例

ライブラリインポートタブ

ベンダーがコントローラアルゴリズムの実装の詳細を隠蔽したい場合、何らかのプリコンパイル済みライブラリがエンドユーザーと共有されます。通常、これらのライブラリは、Windowsオペレーティングシステムの場合はダイナミックリンクライブラリ(.dll)、Linuxオペレーティングシステムの場合は共有オブジェクト(.so)、一部の独自アーキテクチャの場合はアーカイブライブラリ(.a)の形式で提供されます。

ライブラリ インポートタブでは、これらのライブラリ ファイルをインポートできます。

DLL/SOライブラリ

C 関数に加えて、ライブラリ インポートタブでは共有ライブラリ (Windows の場合は .dll、Linux の場合は .so) とヘッダー ファイルをインポートできます。共有ライブラリ ファイルに対応するヘッダー ファイルには、共有ライブラリにある関数プロトタイプが含まれている必要があります (共有ライブラリの関数のサブセットにすることができます)。共有ライブラリのヘッダー ファイルには、共有ライブラリにない関数を含めることはできません。共有ライブラリとヘッダー ファイルのパスの近くにあるブラシアイコンをクリックするだけで、インポートを削除できます。パスの選択 (相対または絶対) はモデルの保存時に保存されます。これは、コンパイルされたモデルを別の場所に移動する場合に非常に重要です。DLL /SO 関数タブには、ライブラリ インポートタブのユーザー インターフェイスが表示されます。

その ライブラリのロードタイプ このプロパティでは、アプリケーション内で共有ライブラリをロード/リンクする方法を選択できます。値は次のとおりです。
  • コンパイル時のロード- ライブラリは、VHIL アプリケーション (レガシー) のコンパイル中に静的にリンクされます。
  • 実行時ロード- シミュレーション開始時にライブラリがロードされます。このロードタイプの主な利点は、共有ライブラリ内の関数実装を変更し、モデルを再コンパイルすることなく変更を適用できることです。変更を適用するには、シミュレーションを停止し、共有ライブラリを再コンパイルして、シミュレーションを再実行するだけです。
注: DLL/SO関数タブはWindows/Linux OS固有のライブラリであるため、VHILシミュレーションにのみ使用してください。HILデバイス用にモデルをコンパイルする場合は、このタブを使用しないでください(すべてのプロパティを空白にしてください)。共有ライブラリのパスまたはヘッダーファイルが指定され、HILデバイスがホストPCに接続されている場合、C関数の出力はデバイス上でゼロになります。DLLの詳細についてはhttps://en.wikipedia.org/wiki/Dynamic-link_library、SOの詳細についてはhttps://www.baeldung.com/linux/a-so-extension-filesをご覧ください。
15 DLL関数タブ

DLL とヘッダー ファイルが正常にインポートされると、関数は図 16のように表示されます。

16 DLL関数のプレビュー

関数プロトタイプをコピーするだけで、「関数」タブ内でDLL関数を呼び出すことができます。図17に例を示します。

17 DLLおよび追加ソース関数呼び出しの例

台風図書館

Typhoonライブラリは、アーカイブライブラリ(.a)ファイルがTyphoon HILデバイスに適していることを示します。つまり、ソースファイルはHILデバイスで使用されるARM A9および/またはARM A53プロセッサ向けにコンパイルされていることを意味します。

コントローラ アルゴリズムの実装の詳細を非表示にしながらも、HIL デバイス上でシミュレーションをリアルタイムで実行したい場合は、ライブラリ (.a) ファイルを使用すると便利です。

注:ライブラリ (.a) ファイルの生成は、さまざまなプロセッサ アーキテクチャのコード コンパイルに関する知識と、オブジェクト ファイルを使用してライブラリ ファイルを作成する方法が必要となるため、より熟練した C コード ユーザーを対象としています。

HILデバイスはARM A9またはARM A53プロセッサアーキテクチャを使用しているため、ソースコードをコンパイルするには専用のCコードコンパイラを使用する必要があります。これらのコンパイラは、すべてのTyphoon HILソフトウェアインストールに含まれており、すぐに使用できます。

注記: ARM コンパイラとアーカイバは次の場所にあります。
  • ウィンドウズ
    • 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:
      • <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
ライブラリ (.a) ファイルを作成するには、いくつかの手順を実行する必要があります。
  1. ARMコンパイラを使用して、すべてのソースコードファイル(.c)をオブジェクトファイル(.o)にコンパイルします。
  2. 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
注意:ライブラリファイル名には「lib」プレフィックスを付けることを強くお勧めします(例: example_a53.aではなくlibexample_a53.a )。そうしないと、モデルのコンパイルに失敗する可能性があります。

ライブラリファイルを入手したら、ヘッダーファイルと同様にインポートするだけです。これは図18に示されています。

ヘッダーファイルのインポートは、DLL/SOライブラリのインポートとは少し異なります。専用のフィールドはなく、ヘッダーは「追加ソース」タブ( 「追加ソース」タブ)からインポートされます。

18. Typhoonライブラリのインポート
注: ARM A9プラットフォームとARM A53プラットフォームの両方のライブラリファイルを作成する必要はありません。HILデバイスに適したライブラリファイルのみを作成してインポートできます。両方作成しても、コンポーネントがすべてのHILデバイスで動作することが保証されるだけです。

追加ソースタブ

このタブでは、C関数に加えて、CおよびC++言語のソースファイル(*.c、*.cpp、*.h)をインポートできます。図19は「追加ソース」タブのユーザーインターフェースを示しています。

19追加ソースタブ
ソースファイルのパスは、図に示すように相対パスまたは絶対パスを選択できます。 図20.
20ソースファイルの絶対パスまたは相対パス
パスの選択 (相対または絶対) はモデルの保存時に保存されます。これは、コンパイルされたモデルを別の場所に移動する場合に非常に重要です。
追加のソースファイルは、 プラス ボタンをクリックするか、 フォルダ ボタン、図のように 図21.
21 .単一または複数のソースファイルの追加
インポート先としてフォルダを選択すると、選択したフォルダとそのサブフォルダからすべてのソースファイルが再帰的にインポートされます。インポートされたファイルを表示するには、 フォルダプレビュー 表示されているボタン 図22.
22 .フォルダーソースのプレビュー

すべてのCソースファイルには独自のヘッダーファイルが必要であり、これもインポートする必要があります。インポートするすべてのCファイルに対して1つのヘッダーファイルを作成し、そのヘッダーファイルのみをインポートすることもできます。インポートしたヘッダーファイルから関数プロトタイプをコピーするだけで、「関数」タブ内で関数を呼び出すことができます。図17に例を示します。

C 関数コンポーネントは、すべての HIL デバイスと VHIL でサポートされています。

注: DLLセクションのプロパティが空でなく、HILデバイスが接続されている場合、C関数コンポーネントのすべての出力はHILデバイス上でゼロになります。図23は、この場合に表示される警告を示しています。
23 DLLセクション使用時のHILデバイス警告