【CanTp】車両診断通信 その32【シミュレーション⑲】

【CanTp】車両診断通信 その32【シミュレーション⑲】 車両診断通信

バックナンバーはこちら。
https://www.simulationroom999.com/blog/diagnostic-communication-backnumber/

はじめに

ISO-TPのシミュレーションをしよう。のシリーズ。
A-COMSTACKからCanTpだけを引っこ抜いてくる。

登場人物

博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

どれがAUTOSAR-CanTp?

フクさん
フクさん

さて、A-COMSTACKからCanTpだけを引っこ抜いてみよう。

太郎くん
太郎くん

具体的にはどうするの?

フクさん
フクさん

CanTpの本体はすでに分かってて、
その名もずばりcantp.c

太郎くん
太郎くん

確かにそのままだね。

フクさん
フクさん

ただし、cantp.cだけで閉じてるわけじゃなく、
各種ヘッダファイルが芋づる式に必要になるはずなんだよねー。
簡単に言うと、以下の流れになる。
①cantp.cを持ってくる
②cantp.cのビルドが通るようにヘッダファイルを集めてくる

太郎くん
太郎くん

②が大変そうだなぁ。

フクさん
フクさん

とりあえずやってみよう。

必要なファイル群

太郎くん
太郎くん

なんとか、ビルドが通るようになった・・・。

フクさん
フクさん

とりあえず、必要になったヘッダファイルを書きならべてみよう。

Compiler_Cfg.h
ComStack_Types.h
MemMap.h
Os.h
Platform_Types.h
Rte_Os_Type.h
Rte_Type.h
Std_Types.h
t_syslog.h
CanTp.h
CanTp_Cbk.h
CanTp_Cfg.h
Compiler.h
SchM_CanTp.h
CanIf.h
PduR_CanTp.h

※ TOPPERS ATK2の上で動作することを前提とした環境であるため、そこからヘッダを持ってくる必要もある。

TOPPERS ATK2

フクさん
フクさん

あとはmain関数とかタイマ割り込みとか排他制御を実現するstubを用意しておけばとりあえずOKかな。

タイマ割り込みエミュレーション

太郎くん
太郎くん

main関数が必要なのはわかるけど、
タイマ割り込みと排他制御はどう実現するの?

フクさん
フクさん

まずタイマ割り込みだけど、
Windowsのマルチメディアタイマーってのを使う。
具体的に言うと、timeSetEventってAPIを使用する。

timeSetEvent
太郎くん
太郎くん

あれ?
普通のタイマーAPIとは違うの?

フクさん
フクさん

うん。似てるし、使い方もコールバック式であれば一緒かな。
ただ、裏でリアルタイムスレッドってのが回ってるみたいで
通常タイマより遥かに精度が良い
今回は1[ms]オーダーの精度が欲しいんでマルチメディアタイマーを使うことした。

太郎くん
太郎くん

ふーん。

フクさん
フクさん

具体的なコードを書いちゃうとこんな感じ。

// タイムイベントとして呼び出されるコールバック関数
static void CALLBACK 
callback(unsigned int timerID, unsigned int msg, unsigned int usrParam, unsigned int dw1, unsigned int dw2) 
{
	_pcallback();
}

void setcallback( void (*pcallback)())
{
   unsigned int timer;

   _pcallback = pcallback;
   // タイムイベントの開始
   timer = timeSetEvent(1, 1, (LPTIMECALLBACK) callback, (DWORD) NULL, TIME_PERIODIC);
   if(timer == 0) { printf("タイムイベントの生成に失敗\n"); exit(0); }

   // ループ
   while(1) {
      Sleep(5000);
   }

   // タイムイベントの終了
   timeKillEvent(timer);
}
太郎くん
太郎くん

なんか終了しないコードになってるけどいいの?

フクさん
フクさん

まぁ今回はプログラムの終了条件が無いんでね。
プロセスごと終了する前提なんで、後始末は雑になってる。

太郎くん
太郎くん

(うーん、良い子のみんなはマネするなよ!系だな。)

フクさん
フクさん

とりあえず、これでmsオーダーのタイマ割り込み相当のエミュレーションはできるってことになる。

排他制御

太郎くん
太郎くん

あと、排他制御は?

フクさん
フクさん

これもWin32APIを使う。
具体的にはMutex。

Using Mutex Objects - Win32 apps
You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes.
フクさん
フクさん

AUTOSARのコード側でWindows関連のヘッダをインクルードすると
型定義が衝突したりするんで、一度関数でラップして別ソースとして切り離しておいた方が良いね。
具体的なコードにすると以下。

void* _CreateMutex(void* lpMutexAttributes, int bInitialOwner,char* lpName)
{
	return CreateMutex( (LPSECURITY_ATTRIBUTES)lpMutexAttributes, bInitialOwner, lpName);
}

unsigned int _WaitForSigleObject(void* hHandle, unsigned int dwMilliseconds )
{
	return WaitForSingleObject( hHandle,dwMilliseconds);
}

int _ReleaseMutex( void* hMutex )
{
	return ReleaseMutex( hMutex );
}
太郎くん
太郎くん

使いどころとはどうなるの?

フクさん
フクさん

割り込みエミュレーションしたコールバック関数群の入り口と出口に設定だね。
たとえば受信割り込みコールバックだと以下な使い方になる。

int rx_interrupt( void *param, canMessage* msg )
{
	_WaitForSigleObject( hMutex,-1);
	
	/* なにかしらの処理 */
	
	_ReleaseMutex(hMutex);
	return 0;
}
太郎くん
太郎くん

あーホントに入り口と出口だね。

太郎くん
太郎くん

でもこれだと他の割り込みが入らない状態になるけど?

フクさん
フクさん

まぁ多重割込までエミュレーションしようと思ったらこれだとダメだけど、
今回はCanTpが割り込みと認識する程度で良いんで、
多重割込は意識しなくても良いかな。

フクさん
フクさん

一応、最低限の足回りは揃った感じかな。
次回からAUTOSARの仕様と向き合ることになると思うよ。

太郎くん
太郎くん

(不安しかない)

まとめ

フクさん
フクさん

まとめだよ。

  • A-COMSTACKのCanTpの本体はcantp.c。
  • 多くのヘッダファイルも持ってくる必要がある。
  • タイマ割り込み、排他はWin32APIで実現。

バックナンバーはこちら。

コメント

  1. no name より:

    上記ヘッダファイルについて、Os.hなど一部ファイルは、a-comstackのフォルダ内になかったのですが、a-comstack以外にもダウンロードする必要がありますか(あるいは自前で用意する形でしょうか。)

    • KEI より:

      当時の状況としてはうろ覚えである点、ご了承ください。

      基本的にはA-COMSTACKから取得したヘッダー群という認識でいます。
      しかし、当時とパッケージ内容部の状況が変わった可能性もあります。

      Os.hに関してはTOPPERS ATK2にも同様の物が入っているはずなので、そちらを参照してみてください。

タイトルとURLをコピーしました