Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

XCP スレーブ ソフトウェアのカスタマイズ

Simulink® エクスターナル モード シミュレーション用の XCP 通信プロトコルは、マスター/スレーブ方式の通信プロトコルです。既定では、ソフトウェアは次の XCP エクスターナル モード シミュレーションをサポートします。

  • ERT (ert.tlc) および GRT (grt.tlc) システム ターゲット ファイルを使用して生成されるコードのための開発用コンピューター上。

  • 一部のサポート パッケージ用。

カスタム ターゲット ハードウェアのシステム ターゲット ファイルが ERT または GRT システム ターゲット ファイルから派生している場合、用意された API を使用して XCP ターゲットの接続性を提供できます。XCP エクスターナル モードの制限事項が適用されます。

エクスターナル モードのターゲット接続性ソフトウェアは以下で構成されます。

  • エクスターナル モード抽象化レイヤー

  • XCP スレーブ プロトコル層

  • XCP スレーブ トランスポート層

  • XCP プラットフォーム抽象化レイヤー

エクスターナル モード抽象化レイヤー

エクスターナル モード シミュレーション中に Simulink と通信するには、ターゲット アプリケーションはエクスターナル モード抽象化レイヤーから関数を呼び出さなければなりません。

ソース コード ファイルの親フォルダーは次のとおりです。

matlabroot\toolbox\coder\xcp\src\target\ext_mode

この層の API は include\ext_mode.h で宣言され、src\xcp_ext_mode.c で実装されます。

Simulink と通信するために、ターゲット アプリケーションはエクスターナル モード抽象化レイヤーで公開されたサービスを使用します。このフロー チャートは、Simulink との通信を確立するために必要なターゲット アプリケーションの段階を表しています。

次の表は、ターゲット アプリケーションが各段階で呼び出さなければならない関数を示しています。

段階関数目的

INITIALIZE

extmodeParseArgs

エクスターナル モードのコマンド ライン引数を抽出する。

modelName_initialize

生成された Simulink モデル コードを初期化する。

extmodeInit

エクスターナル モードのターゲット接続性を初期化する。

HOST START REQUEST

extmodeWaitForHostRequest

[実行] ボタンをクリックしたときに作成される、開発用コンピューターからの開始要求を待機する。

RUN

modelName_step

生成された Simulink モデル コードの 1 つのステップを実行する。

extmodeEvent

モデルのサンプル時間 ID の場合、モデル ステップ関数によって生成された信号をサンプリングし、開発用コンピューターに送信するために通信プロトコルのトランスポート層にパケットの内容を渡す。

extmodeBackgroundRun

物理的な通信インターフェイスとのパケットの送受信を行い、選択した通信プロトコルに従ってパケットの内容を処理する。

HOST STOP REQUEST OR SIMULATION COMPLETE

extmodeStopRequested

エクスターナル モード シミュレーションの停止要求を開発用コンピューターのモデルから受信するかどうかをチェックする。この要求は、[停止] ボタンをクリックしたときに作成される。

extmodeSimulationComplete

生成されたモデル コードの実行が完了したかどうかをチェックする。
RESET

modelName_terminate

生成された Simulink モデル コードを終了する。

extmodeReset

エクスターナル モードのターゲット接続性を初期状態にリセットする。

以下の疑似コード例は、ターゲット アプリケーションでさまざまなフローチャート段階を実装する方法を示しています。RUN 段階の間は、エクスターナル モードの実行時環境には少なくとも 2 つのスレッドが必要です。

  • 生成されたモデル コードの実行を行う周期的なスレッド。

  • エクスターナル モード通信スタックの実行とパケットの送信と受信を行うバックグラウンド スレッド。

疑似コードは、同じ while() ループ内で periodicThreadextmodeBackgroundRun を逐次的に実行することで、マルチスレッドのシミュレーションを行います。

/*------------- Pseudo-Code Example -------------*/
/* Define periodic thread */
void periodicThread(void)
{
  /* Run model step function */
  modelName_step();
  /* Notify external mode abstraction layer about periodic event */
  extmodeEvent(PERIODIC_EVENT_ID, currentSimulationTime);
}

/* Main function for target application */
main(int argc, char *argv[])
{
  /*------------- INITIALIZE -------------*/
  /* Parse external mode command line arguments */
  extmodeParseArgs(argc, argv);
 
  /* Initialize model */
  modelName_initialize();
 
  /* Initialize external mode target connectivity */
  extmodeInit(extModeInfo, finalSimulationTime);

  /*------------- HOST START REQUEST -------------*/
  /* Wait until a start request is received from development computer */
  extmodeWaitForHostRequest(EXTMODE_WAIT_FOREVER);
  

  /*------- HOST STOP REQUEST OR SIMULATION COMPLETE -------*/    
  /* While simulation is not complete and stop request is not received */
  while (!extmodeSimulationComplete() && !extmodeStopRequested()) {

    /*------------- RUN -------------*/    
    periodicThread();
    extmodeBackgroundRun();
  }

  /*------------- RESET -------------*/
  /* Terminate model */
  modelName_terminate();

  /* Reset external mode target connectivity */
  extmodeReset();
  return 0;
}

関数を呼び出すコードを表示するには、[システム ターゲット ファイル][ert.tlc] に設定してXCP 通信を使用したエクスターナル モード シミュレーションの例を実行します。次に、コード ジェネレーター フォルダーにある ert_main.c を開きます。

XCP スレーブ プロトコル層

XCP スレーブ プロトコル層では、自動化システムと測定システムの国際標準化団体 (ASAM) の規格である ASAM MCD-1 XCP に従って XCP コマンドとデータを解釈します。

ソース コード フォルダーは次のとおりです。

matlabroot\toolbox\coder\xcp\src\target\slave\protocol\src
エクスターナル モード シミュレーションでは、ビルド プロセスによって必要なファイルがビルド情報オブジェクトに自動的に追加されます。

XCP スレーブ トランスポート層

XCP スレーブ トランスポート層は、ASAM の仕様に従って通信メディアに対してメッセージを送受信します。

ソース フォルダーは以下のとおりです。

matlabroot\toolbox\coder\xcp\src\target\slave\transport\src
エクスターナル モード シミュレーションでは、ビルド プロセスによって必要なファイルがビルド情報オブジェクトに自動的に追加されます。

XCP プラットフォーム抽象化レイヤー

XCP プラットフォーム抽象化レイヤーは次のものを提供します。

カスタマイズの例については、カスタム抽出化レイヤーの作成を参照してください。

XCP ドライバー

XCP ドライバーは通信チャネルを通じて XCP メッセージを送受信します。エクスターナル モード シミュレーションでは、ビルド プロセスによってドライバー ファイルがビルド情報オブジェクトに自動的に追加されます。

XCP ドライバーは rtiostream API に基づいています。たとえば、ホストベースのエクスターナル モード シミュレーションでは以下の rtiostream ファイルが使用されます。

  • matlabroot\toolbox\coder\rtiostream\src\rtiostreamtcpip.c

  • matlabroot\toolbox\coder\rtiostream\src\rtiostream_serial.c

rtiostream 通信チャネルの実装とテストの詳細については、以下を参照してください。

カスタム プラットフォーム抽象化レイヤーについては、rtiostream ファイルをビルド情報オブジェクトに追加しなければなりません。例については、カスタム抽出化レイヤーの作成を参照してください。

メモリ アロケーター

XCP スレーブ ソフトウェアでは、内部データ構造体を保持するために、可変サイズの連続メモリ ブロックを動的に割り当てる必要があります。

エクスターナル モード シミュレーションでは、ビルド プロセスによってメモリ アロケーター ファイルがビルド情報オブジェクトに自動的に追加されます。

xcpMemBlockSizes および xcpMemBlockCounts プリプロセッサ マクロによってメモリの割り当てが定義されます。

既定のメモリ アロケーターは、最大で 16 の異なるメモリ ブロック セットを割り当ておよび割り当て解除できます。各セットでは、既定の割り当てをコンパイル中にオーバーライドできます。以下を指定できます。

  • XCP_MEM_BLOCK_N_SIZE プリプロセッサ マクロによるブロック サイズ。

  • XCP_MEM_BLOCK_N_NUMBER プロセッサ マクロによる各セットのブロック数。

たとえば、以下のプロセッサ マクロは 64 バイトのブロックを 4 個と 256 バイトのブロックを 8 個作成します。

#define XCP_MEM_BLOCK_1_SIZE 64
#define XCP_MEM_BLOCK_1_NUMBER 4
#define XCP_MEM_BLOCK_2_SIZE 256
#define XCP_MEM_BLOCK_2_NUMBER 8

異なるセットのブロック サイズを昇順で構成します。

XCP_MEM_BLOCK_N_SIZE < XCP_MEM_BLOCK_N+1_SIZE

最小のブロック サイズ XCP_MEM_BLOCK_1_SIZE は、ポインターを保持するために十分な大きさがなければなりません。

XCP_MEM_ALIGNMENT プリプロセッサ マクロによるメモリ アロケーターのアライメントを構成します。以下に例を示します。

#define XCP_MEM_ALIGNMENT 8

その他のプラットフォーム抽象化レイヤーの機能

このファイルでは、プラットフォーム抽象化レイヤー インターフェイスが定義されます。

matlabroot\toolbox\coder\xcp\src\target\slave\platform\include\xcp_platform.h
カスタム プラットフォーム抽象化レイヤーの機能を実装するには、XCP_CUSTOM_PLATFORM プリプロセッサ マクロを追加して情報オブジェクトをビルドします。xcp_platform_custom.h という名前のファイルで、カスタム機能の実装を提供します。XCP_CUSTOM_PLATFORM を定義しない場合、ビルド プロセスでは Linux® および Windows® システムをサポートする既定のファイルが使用されます。

以下の表では、ターゲット ハードウェアで配布する XCP スレーブ ソフトウェアに提供しなければならない機能について説明します。

機能詳細

相互排除

"相互排除" サポートを使用してシステムのデータ構造にアクセスするために、XCP ドライバーは基本 API に依存して定義、初期化、ロックおよびロック解除を行います。

ターゲット ハードウェアの相互排除をサポートするには、カスタム実装を提供します。

Linux および Windows の既定の実装では、相互排除がサポートされています。

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
...
#define XCP_MUTEX_DEFINE(lock) HANDLE lock
#define XCP_MUTEX_INIT(lock) lock = CreateMutex(0, FALSE, 0)
#define XCP_MUTEX_LOCK(lock) WaitForSingleObject((lock), INFINITE)
#define XCP_MUTEX_UNLOCK(lock) ReleaseMutex(lock)

#else 
...
#include <pthread.h>
#define XCP_MUTEX_DEFINE(lock) pthread_mutex_t lock
#define XCP_MUTEX_INIT(lock) pthread_mutex_init(&(lock), NULL)
#define XCP_MUTEX_LOCK(lock) pthread_mutex_lock(&(lock))
#define XCP_MUTEX_UNLOCK(lock) pthread_mutex_unlock(&(lock))
...
#endif

スリープ

指定された時間が経過するまで呼び出しスレッド スリープを作成するスリープ API を提供します。Linux および Windows システムの既定の実装は次のとおりです。

#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
...
#define XCP_SLEEP(seconds,microseconds)  Sleep((seconds) * 1000 \  
+ (((microseconds) + 1000 - 1) / 1000))

#else 
...
#if _POSIX_C_SOURCE >= 199309L
#define XCP_SLEEP(seconds,microseconds)  do {struct timespec t;\
 t.tv_sec = seconds; t.tv_nsec = microseconds * 1000; nanosleep(&t, NULL);} while(0)
#else
/* nanosleep is not available. Use select instead. */
#define XCP_SLEEP(seconds,microseconds)  do {struct timeval t; t.tv_sec = seconds;\
 t.tv_usec = microseconds; select(0, NULL, NULL, NULL, &t);} while(0)
#endif /* _POSIX_C_SOURCE >= 199309L */
...
#endif

ログ

診断メッセージを生成するために、XCP スレーブ ソフトウェアにはターゲット ハードウェアによって提供されるログ サービスをサポートするカスタム出力 API が必要です。XCP_PRINTF プリプロセッサ マクロを定義しない場合、既定の実装は空です。

アドレス変換

XCP 標準は、メモリ内の変数のアドレスを 32 ビットのアドレスと 8 ビット拡張として表します。

XCP マスターは、ビルド プロセスによって作成されるデバッグ情報を解析して、モデルの信号およびパラメーターのアドレスを抽出します。デバッグ情報は DWARF または PDB 形式です。

XCP マスターは、引数 addressExtension および address を含む XCP コマンドを送信して、パラメーターおよび信号へのアクセスを要求します。

addressExtension および address の情報がターゲット ハードウェアによって受信されると、XCP スレーブはアドレスをターゲット ハードウェアのメモリ内の変数の位置に変換しなければなりません。変数の位置はローダーによって割り当てられ、ターゲット固有です。

XCP_ADDRESS_GET() マクロを使用して変換ロジックを指定します。Linux および Windows システムの既定の実装は次のとおりです。

#if defined(__MINGW32__) || defined(__MINGW64__)
#define XCP_ADDRESS_GET(addressExtension, address) \ 
(uint8_T*) ((uintptr_t) address)
#else
#define XCP_ADDRESS_GET(addressExtension, address) \ 
(uint8_T*) ((address) + (uint8_T*)&__ImageBase)
#endif
現在、32 ビットのハードウェア アーキテクチャのみがサポートされているため、addressExtension は 0 です。

メモリの設定およびコピー

メモリのコピー操作およびメモリの設定操作の最適化されたバージョンを指定できます。

XCP_MEMCPY および XCP_MEMSET プリプロセッサ マクロを定義しないと、既定の実装では標準 C 関数 memcpy および memset が指定されます。

#ifndef XCP_MEMCPY
#define XCP_MEMCPY memcpy
#endif

#ifndef XCP_MEMSET
#define XCP_MEMSET memset
#endif

コマンド ライン引数の解析

ターゲット ハードウェアでコマンド ライン引数の解析がサポートされていない場合、プリプロセッサ マクロ EXTMODE_DISABLE_ARGS_PROCESSING を定義します。

-w オプションを置き換えるために、このコマンドを使用して Simulink から接続メッセージを受け取るまでターゲット アプリケーションが待機状態に移行したままになることを指定できます。

set_param(modelName, 'OnTargetWaitForStart', 'on');
ビルド プロセスは必要なオプション (-DON_TARGET_WAIT_FOR_START=1) をコンパイラに提供します。

カスタム抽出化レイヤーの作成

ビルド プロセスのために、カスタム プラットフォームの抽出化レイヤーを作成するコード生成後のコマンドを定義できます。

  1. ヘッダー ファイル xcp_platform_custom.h を指定します。この Linux の例では必要な関数が定義されます。

    #ifndef XCP_PLATFORM_CUSTOM_H
    #define XCP_PLATFORM_CUSTOM_H
    
    /* XCP_ADDRESS_GET */
    #include <stdint.h>
    #define XCP_ADDRESS_GET(addressExtension, address)  (uint8_T*) ((uintptr_t) address)
    
    /* XCP_MUTEX */
    #include <pthread.h>
    #define XCP_MUTEX_DEFINE(lock)    pthread_mutex_t lock
    #define XCP_MUTEX_INIT(lock)      pthread_mutex_init(&(lock), NULL)
    #define XCP_MUTEX_LOCK(lock)      pthread_mutex_lock(&(lock))
    #define XCP_MUTEX_UNLOCK(lock)    pthread_mutex_unlock(&(lock))
    
    /* XCP_SLEEP */
    #include <sys/time.h>    /* gettimeofday */ 
    #if _POSIX_C_SOURCE >= 199309L
    #include <time.h>       /* for nanosleep */
    #else
    #include <stddef.h>
    #include <sys/select.h> /* for select */
    #endif
    
    /* _POSIX_C_SOURCE >= 199309L */
    #if _POSIX_C_SOURCE >= 199309L
    #define XCP_SLEEP(seconds,microseconds)  do {struct timespec t;\
     t.tv_sec = seconds; t.tv_nsec = microseconds * 1000; nanosleep(&t, NULL);} while(0)
    #else
    /* nanosleep is not available. Use select instead. */
    #define XCP_SLEEP(seconds,microseconds)  do {struct timeval t; t.tv_sec = seconds;\
     t.tv_usec = microseconds; select(0, NULL, NULL, NULL, &t);} while(0)
    #endif /* _POSIX_C_SOURCE >= 199309L */
    #endif
    

  2. コード生成後のコマンドを定義します。

    function myXCPTargetPostCodeGenCommand(buildInfo)
     
      buildInfo.addDefines('-DXCP_CUSTOM_PLATFORM', 'OPTS');
    
      % Configure the default memory allocator
      buildInfo.addDefines('-DXCP_MEM_BLOCK_1_SIZE=64', 'OPTS');
      buildInfo.addDefines('-DXCP_MEM_BLOCK_1_NUMBER=46', 'OPTS');
      buildInfo.addDefines('-DXCP_MEM_BLOCK_2_SIZE=256', 'OPTS');
      buildInfo.addDefines('-DXCP_MEM_BLOCK_2_NUMBER=10', 'OPTS');
     
      % Add my rtiostream
      buildInfo.addSourceFiles(customRtIOStreamFileName, ...
                               customRtIOStreamSrcPath);
     
      % If the target hardware does not support parsing of command
      % line arguments
        buildInfo.addDefines('-DEXTMODE_DISABLE_ARGS_PROCESSING', 'OPTS');
     
    end

参考

| | | | | | | | |

関連するトピック

外部の Web サイト