バックナンバーはこちら。
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を使用する。
あれ?
普通のタイマー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。
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で実現。
バックナンバーはこちら。
コメント
上記ヘッダファイルについて、Os.hなど一部ファイルは、a-comstackのフォルダ内になかったのですが、a-comstack以外にもダウンロードする必要がありますか(あるいは自前で用意する形でしょうか。)
当時の状況としてはうろ覚えである点、ご了承ください。
基本的にはA-COMSTACKから取得したヘッダー群という認識でいます。
しかし、当時とパッケージ内容部の状況が変わった可能性もあります。
Os.hに関してはTOPPERS ATK2にも同様の物が入っているはずなので、そちらを参照してみてください。