バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
前回はCANoeでXCP関連の処理を追加する際の方針として
どこのノードに何をさせるかを確認。
加えてCANoeシステム変数の追加方法の確認も行った。
これにより、実際のCAPLを書き出してもOKな状態になったため
XCP関連のCAPLコードを記載していく。
登場人物
博識フクロウのフクさん
イラスト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
テストノードに追加するXCPセットアップ関連のCAPLコード
あとはCAPLを書いていけばOKなんで、さっとコードを書いてしまおう。
includes
{
}
variables
{
msTimer NewTimer;
float TmpSingnal;
int ev;
int rcv_ev = 0;
message 2 xcp_rcv;
}
on timer NewTimer
{
write("Target=%X", TmpSingnal );
}
on preStart
{
}
on key ' '
{
setTimerCyclic(NewTimer,0,10);
}
on signal Target
{
TmpSingnal = getSignal(Target);
}
on message 2
{
if (this.byte(0)>0xC0){
xcp_rcv = this;
rcv_ev = 1;
}
}
void sendrcvmessage(byte sndData[],byte rcvData[])
{
message 0x1 xcpmsg = {
dlc = 0xF,
FDF = 1,
BRS = 1
};
int i,j;
for( i = 0; i<64;i++ )
{
xcpmsg.byte(i) = sndData[i];
}
output(xcpmsg);
rcv_ev = 0;
for(i=0;i<20;i++){
if( rcv_ev!=0 ){
for( j=0;j<64;j++ ){
rcvData[j] = xcp_rcv.byte(j);
}
break;
}
testWaitForTimeout(100);
}
}
void xcp_startup()
{
byte data[20][64] = {
{0xFF, 00},
{0xFD},
{0xFC},
{0xD6}, // FREE DAQ
{0xD5, 0x00, 0x02, 0x00}, // ALLOC_DAQ 2
{0xD4, 0x00, 0x00, 0x00, 0x01}, // ALLOC_ODT DAQ:0 ODTcount=1
{0xD4, 0x00, 0x01, 0x00, 0x01}, // ALLOC_ODT DAQ:1 ODTcount=1
{0xD3, 0x00, 0x00, 0x00, 0x00, 0x03}, // ALLOC_ODT_ENTRY DAQ:0,ODT:0,ODTentry:3
{0xE2, 0x00, 0x00, 0x00, 0x00, 0x00}, // SET_DAQ_PTR DAQ:0,ODT:0,ODTentry:0
{0xE1, 0xFF, 0x04, 0xFF, 0x00, 0x01, 0x00, 0x00}, // WRITE_DAQ BIT:FF,Size:4,ex:FF,ADDR:0x00000100
{0xE1, 0xFF, 0x04, 0xFF, 0x04, 0x01, 0x00, 0x00}, // WRITE_DAQ BIT:FF,Size:4,ex:FF,ADDR:0x00000104
{0xE1, 0xFF, 0x04, 0xFF, 0x08, 0x01, 0x00, 0x00}, // WRITE_DAQ BIT:FF,Size:4,ex:FF,ADDR:0x00000108
{0xE0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00}, // SET_DAQ_LIST_MODE DAQ:0,EV:3,PRE:1,PRI:0
{0xDE, 0x02, 0x00, 0x00}, // START_STOP_DAQ_LIST MODE:2(select),DAQ:0
{0xD3, 0x00, 0x01, 0x00, 0x00, 0x02}, // ALLOC_ODT_ENTRY DAQ:1,ODT:0,ODTentry:2
{0xE2, 0x00, 0x01, 0x00, 0x00, 0x00}, // SET_DAQ_PTR DAQ:1,ODT:0,ODTentry:0
{0xE1, 0xFF, 0x04, 0xFF, 0x00, 0x01, 0x00, 0x00}, // WRITE_DAQ BIT:FF,Size:4,ex:FF,ADDR:0x00000100
{0xE1, 0xFF, 0x04, 0xFF, 0x04, 0x01, 0x00, 0x00}, // WRITE_DAQ BIT:FF,Size:4,ex:FF,ADDR:0x00000104
{0xE0, 0x02, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00}, // SET_DAQ_LIST_MODE DAQ:1,EV:3,PRE:1,PRI:0
{0xDE, 0x02, 0x01, 0x00} // START_STOP_DAQ_LIST MODE:2(select),DAQ:1
};
byte rcvdata[64];
int i;
for(i=0;i<20;i++){
sendrcvmessage( data[i], rcvdata );
}
}
void start_daq()
{
byte sndmsg[64] = {0xDD, 0x01};
byte rcvdata[64];
sendrcvmessage( sndmsg, rcvdata );
}
void stop_daq()
{
byte sndmsg[64] = {0xDD, 0x00};
byte rcvdata[64];
sendrcvmessage( sndmsg, rcvdata );
}
on preStop
{
stop_daq();
}
testcase MyTestCase()
{
xcp_startup();
start_daq();
@daq_start = 1;
testWaitForTimeout(60000);
stop_daq();
@daq_start = 0;
}
MainTest()
{
MyTestCase();
}
テストノードのCAPLコード確認
なんかCAPLと言えばCAPLなんだけど、
テストノードに記載する場合ってちょっと雰囲気かわるんだっけ?
例えば、MainTest()とかがあるけど、これが呼ばれるタイミングとかどうなってるの?
ネットワークノードとテストノードは結構性格が違うね。
ネットワークノードはイベントドリブン方式で
CANの送信や受信をトリガーとして動くことを想定している。
対して、テストノードはシーケンシャル方式で、
CAPLに記載された順番に処理していく。
ってイメージだ。
と言ってもテストノードもイベントを拾うことはできるので、
それほど大きな差はないかもね。
太郎くんが気にしているMainTest()って関数はCANoe上のテストノードの再生ボタンを押すたびに実行される関数だ。
って、ことは同じ処理を必要に応じて何回もできるってことなのか。
そうなるね。
割と便利な機能なので必要に応じて利用すると良いだろう。
まとめ
まとめだよ。
- CANoeテストノードに記載するXCPセットアップ関連のCAPLコード開示。
- ネットワークノードはイベントドリブン型、テストノードはシーケンシャル型とやや性格が違う。
- といっても、テストノードでもCAN送信/受信イベントは受け取れるので気にするほどの差ではない。
バックナンバーはこちら。
コメント