バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
前回、CAN回線ログを元にDAQパケットの送信周期が
本来であれば10[ms]であるべきところ、
実際は15[ms]周期となっていた。
一応原因のあたりは付いているので、
そこを確認していく。
登場人物
博識フクロウのフクさん
イラスト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
DAQパケット送信周期の精度が悪い理由
で、送信周期が狙い通り10[ms]にならないのって何が原因になるの?
一言で言うと
XCP BasicのPCシミュレーション用コードのイベントチャンネルの時間精度がそもそもあまり高くない。
ってことになるね。
え!
それって結構根深い話なんじゃ・・・。
まぁ完全に根幹の部分になるね。
該当コード
これは該当部分のコードを見ながら話した方が良いだろう。
ちなみにxcpsim.cのthreadって関数になる。
// Task Sheduler
static DWORD WINAPI thread(PVOID par) {
WORD i = 0;
WORD j = 0;
threadRunning = 1;
while (threadRunning) {
Sleep(10);
if (mainRunning) {
/* 10ms Task ECU Simulation */
ecuCyclic();
/* Event Channel 1 is cyclic 1 ms */
#ifdef XCP_ENABLE_DAQ
for (j = 0; j < 10; ++j) {
gTimer += 1;
XcpEvent(3);
}
#endif
/* Event Channel 1 is cyclic 10 ms */
#ifdef XCP_ENABLE_DAQ
#ifdef XCP_DPRAM_SERVER
dpramServerTriggerTask(1);
#else
XcpEvent(1);
#endif
#endif
if (i++ % 10 == 0) {
/* Event Channel 2 is cyclic 100 ms */
#ifdef XCP_ENABLE_DAQ
XcpEvent(2);
#endif
/* Flush every 100ms */
ApplXcpSendFlush();
}
/* XCP driver background processing */
#ifdef XCP_ENABLE_CHECKSUM
XcpBackground();
#endif
}
}
return 0;
}
該当コードの問題個所と状況
問題の箇所は10行目の
Sleep(10);
だな。
Sleep(10);
だから10[ms]待つってことだから別に間違っては無さそうな?
まぁイベントチャンネル3が1ms周期だから
これが実現できないってのはあるだろうけど、
今回はイベントチャンネル1の10[ms]周期だから問題にはならなそうに見えるかな。
Sleep(10);
は、「最低10[ms]は待つ」ってだけで厳密に10[ms]で戻ってくる保証はないんだよね。
PC依存な面もあるかもしれないが、Windowsの場合、大体15[ms]になることは多いな。
「大体15[ms]」?
あれ?15[ms]っていうと・・・もしや・・・。
そう。
このSleep(10)が15[ms]だからイベントチャンネル1が15[ms]になって、
結果としてDAQパケット送信間隔が15[ms]になる。
ダメじゃん!
まぁ一応対策も考えてるから、次回説明だな。
まとめ
まとめだよ。
- DAQパケット送信周期の精度が悪い理由を確認。
- イベントチャンネルが15[ms]になってる。
- Sleep(10)で10[ms]周期を作ろうとしているが、実際は15[ms]になってる。
- この部分はPC依存な面はある。
- Sleep(10)で10[ms]周期を作ろうとしているが、実際は15[ms]になってる。
- イベントチャンネルが15[ms]になってる。
- 上記により小手先の回収ではどうにもならなそう。
- 一応対策も考えてるので次回確認予定。
バックナンバーはこちら。
コメント