Simulink Coder

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

ターゲットの接続性に対応する通信チャネルの作成

この例ではプロセッサインザループ (PIL) シミュレーション用の通信チャネルを実装する方法を説明します。

この通信路を使用すると、異なるプロセス間でのデータの交換が可能になります。この通信路がサポートする PIL シミュレーションなどの機能は、ホスト マシンで実行している Simulink ソフトウェア環境と、ターゲット ソフトウェアで実行している配布コードとのデータの交換を必要とします。

ここでは、rtiostream インターフェイスについてと、rtiostream インターフェイスがさまざまな接続タイプにおいてターゲット接続ドライバー形式で実装可能な一般的な通信路をどのように提供するかについて学習します。この例では、TCP/IP プロトコルを経由して既定の実装を使用する方法について紹介します。

2 つのエンティティ Station A および Station B において、rtiostream インターフェイスを使用した通信路の設定とデータ交換の方法について学習します。この例の目的は、Station A と Station B の両方がデスクトップ コンピューターの同じプロセス内で設定されることです。

ターゲット接続ドライバーを使用してオンターゲット PIL シミュレーションをサポートする方法について学習します。オンターゲット シミュレーションで、Station A と Station B は、通信路経由でデータを交換するターゲット コンピューターとホスト コンピューターを表します。ホスト側のターゲット接続ドライバーは、MATLAB 製品に読み込まれて呼び出される共有ライブラリとして実装されます。ターゲット側のドライバーは、ターゲット上で実行されるアプリケーションにリンクされたソース コードまたはライブラリでなければなりません。

さらに、この例では、次の実行に必要な手順を説明します。

  • TCP/IP に独自のターゲット側ドライバーを設定し、既定のホスト側 TCP/IP ドライバーで稼働するようにします。

  • シリアル通信用に指定されたホスト側ドライバーを設定します。

  • 通信路のホスト側とターゲット側の CAN または USB を使用するなどして、カスタム ターゲット接続ドライバーを実装します。

rtwdemo_sil_pil_scriptrtwdemo_sil_pil_scriptrtwdemo_custom_pil_scriptrtwdemo_custom_pil_script も参照してください。

既定の TCP/IP を実装するためのソース コードの表示

ファイル rtiostream_tcpip.c は、クライアント側とサーバー側の TCP/IP 通信を実装します。クライアント モードまたはサーバー モードで稼働するようにドライバーを設定するには、起動パラメーターが使用されます。カスタム実装の開始点としてこのソース ファイルを使用することもできます。通常、それぞれの側の通信路は、サーバーまたはクライアント実装のどちらか一方だけを必要とします。クライアントとサーバーの各ドライバーがそれぞれ異なるアーキテクチャで実行される場合、各アーキテクチャのドライバー コードを別々のソース ファイルに配置すると便利な場合があります。

ヘッダー ファイル rtiostream.h には、関数 rtIOStreamOpen/Send/Recv/Close のプロトタイプが含まれています。カスタム実装のためには、これをインクルードします (#include を使用)。

% Location of TCP/IP driver source code
rtiostreamtcpip_dir=fullfile(matlabroot,'rtw','c','src','rtiostream',...
                              'rtiostreamtcpip');

% View rtiostream_tcpip.c
edit(fullfile(rtiostreamtcpip_dir,'rtiostream_tcpip.c'));

% View rtiostream.h
edit(fullfile(matlabroot,'rtw','c','src','rtiostream.h'));

共有ライブラリファイルの場所

MATLAB 製品からターゲット接続ドライバーにアクセスするには、ターゲット接続ドライバーを共有ライブラリにコンパイルしなければなりません。この共有ライブラリはシステム パスに存在しなければなりません。既定の TCP/IP ドライバーの共有ライブラリは、matlabroot/bin/$ARCH (ここで、$ARCH はシステム アーキテクチャ、たとえば win64 など) に存在します。

% The shared library filename extension and location depends on your operating
% system.
sharedLibExt=system_dependent('GetSharedLibExt');

% Shared library for both Station A and Station B
libTcpip = ['libmwrtiostreamtcpip' sharedLibExt];
disp(libTcpip)
libmwrtiostreamtcpip.dll

ターゲット接続ドライバーのテスト

カスタム ターゲット接続ドライバーを実装する場合は、MATLAB からこれをテストできると便利です。以下の例では、既定の TCP/IP ターゲット接続ドライバーを読み込む方法、およびこのドライバーを使用して Station A と Station B 間でのデータの交換を行う方法について説明します。

ドライバーにアクセスするには、MEX ファイル rtiostream_wrapper を使用します。この MEX ファイルを使用すると、共有ライブラリを読み込み、関数 rtiostream にアクセスして、rtiostream チャンネルを開閉したり、データを送受信したりすることができます。

この例では、Station A と Station B の両方がホスト コンピューターで実行されます。Station A は TCP/IP サーバーとして、Station B は TCP/IP クライアントとして設定されます。ホストとターゲット間の通信を行う場合、通常、ホストは TCP/IP クライアントとして、ターゲットは TCP/IP サーバーとして設定されます。

% Choose a port number for TCP
if usejava('jvm')
    % Find a free port
    tempSocket = java.net.ServerSocket(0);
    port = num2str(tempSocket.getLocalPort);
    tempSocket.close;
else
    % Resort to a hard-coded port
    port = '14646';
end

% Open the Station A rtiostream as a TCP/IP server
stationA = rtiostream_wrapper(libTcpip,'open',...
                                 '-client', '0',...
                                 '-blocking', '0',...
                                 '-port',port);

% If the communication channel opens, the return value is a
% handle to the connection; a return value of -1 indicates an error.
assert(stationA~=(-1)) % Test for expected return value

% Open the Station B rtiostream as a TCP/IP client
stationB = rtiostream_wrapper(libTcpip,'open',...
                                 '-client','1',...
                                 '-blocking', '0',...
                                 '-port',port,...
                                 '-hostname','localhost');
% If the communication channel opens, the return value is a
% handle to the connection; a return value of -1 indicates an error.
assert(stationB~=(-1)) % Test for expected return value

Station B から Station A へのデータの送信

ターゲット接続ドライバーは、8 ビット バイトでデータ ストリームを送信するように設計されています。プロセッサがバイトでアドレスを指定できない場合、データは最小のアドレスを指定可能な語長で送信されます。

% Send Some Data from Station B to Station A
msgOut = uint8('Station A, this is Station B. Are you there? OVER');

[retVal, sizeSent] = rtiostream_wrapper(libTcpip,...
                                       'send',...
                                       stationB,...
                                       msgOut,...
                                       length(msgOut));
assert(retVal==0); % A return value of zero indicates success
assert(sizeSent==length(msgOut)); % Check that bytes in the message were sent

% Allow time for data transmission to complete
pause(0.2)

% Receive data on the Station A
[retVal, msgRecvd, sizeRecvd] = rtiostream_wrapper(libTcpip,...
                                                 'recv',...
                                                 stationA,...
                                                 100);
assert(retVal==0); % A return value of zero indicates success
assert(sizeRecvd==sizeSent); % Check that bytes in the message were received

% Display the received data
disp(char(msgRecvd))
Station A, this is Station B. Are you there? OVER                                                   

Station A から Station B への応答の送信

% Send data from Station A to Station B
msgOut = uint8('Station B, this is Station A. Yes, I''m here! OVER.');
[~, sizeSent] = rtiostream_wrapper(libTcpip,... %#ok
                                       'send',...
                                       stationA,...
                                       msgOut,...
                                       length(msgOut));
% Allow time for data transmission to complete
pause(0.2)

% Receive data on Station B
[~, msgRecvd, sizeRecvd] = rtiostream_wrapper(libTcpip,... %#ok
                                                 'recv',...
                                                 stationB,...
                                                 100);

% Display the received data
disp(char(msgRecvd))
Station B, this is Station A. Yes, I'm here! OVER.                                                  

接続を終了して共有ライブラリをアンロード

% Close rtiostream on the Station B
retVal = rtiostream_wrapper(libTcpip,'close',stationB);
assert(retVal==0); % A return value of zero indicates success

% Close rtiostream on the Station A
retVal = rtiostream_wrapper(libTcpip,'close',stationA);
assert(retVal==0) % A return value of zero indicates success

% Unload the shared library
rtiostream_wrapper(libTcpip, 'unloadlibrary');

シリアル通信用のホスト側ドライバーの使用

TCP/IP のドライバーの代替としてシリアル通信に指定されたホスト側ドライバーを使用できます。シリアル ドライバーを設定するには、TCP/IP ドライバーの場合と同様の手順を使用します。詳細は、『Embedded Coder リファレンス』ドキュメンテーションの「rtiostream_wrapperrtiostream_wrapper」を参照してください。

独自のターゲット側ドライバーを設定する手順

ターゲットにイーサネット接続が存在し、TCP/IP スタックを使用できる場合は、次の手順に従います。

1. rtiostream.h で定義された rtiostream インターフェイス経由で使用できるように TCP/IP スタックのラッパーを記述します。2. 前述の例と同様に、データを送受信するターゲットのテストアプリケーションを記述します。3. MEX ファイル rtiostream_wrapper とホスト側の TCP/IP ドライバーを使用して、ターゲットで実行されているドライバー ソフトウェアをテストできます。4. 稼働中のターゲット側ドライバーが存在する場合は自動生成されたコードのビルドにドライバー ソース ファイルを含めなければなりません。

PIL モードによって使用される既定のホスト側ドライバーは、TCP/IP クライアントとして設定されることに注意してください。つまり、ターゲット側ドライバーに必要なのは、TCP/IP サーバーとしての稼働を設定することだけです。

ホスト側でサポートされていない通信路を使用する必要がある場合は、ホストとターゲットの両方のドライバーを記述しなければなりません。この場合でも、MEX ファイル rtiostream_wrapper を使用して rtiostream ドライバーをテストできます。

独自のホスト側ドライバーを設定する手順

多くのさまざまな通信路を使用してターゲット接続ドライバーを実装できます。たとえば、特別なシリアル接続経由でホストとターゲット間の通信を実装する必要があるとします。この場合、ホストとターゲットの両方にドライバーを指定しなければなりません。

ホスト側では、MEX ファイル rtiostream_wrapper を使用してドライバーをテストできます。ドライバーに printf を使用する診断出力が含まれる場合は、共有ライブラリが rtiostream_wrapper によって読み込まれるときに printf を mexPrintf と置き換えなければなりません。

また、稼働中のホスト側デバイス ドライバーが存在する場合、これらを Simulink ソフトウェア環境で使用できるようにしなければなりません。PIL シミュレーションでこれを行うには、sl_customization を介して共有ホスト側の共有ライブラリを登録します。