CANoe 中新建Node發checksum,並用CAPL 發檔位信息
建立一個Node
可以從DBC選一個msg :
寫一個TCU.can :
/*@!Encoding:1252*/
/*@!Encoding:1252*/
includes
{
}
variables
{
const byte FOUR_BITS_MAX=15;
byte process_counter[14] = {0, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0};
byte checksum_sb[14] = {56, 56, 56, 56, 56, 56, 56, 60, 60, 60, 60, 60, 28, 32};
}
/*******Msg_Timeout DTC Start*********/
/*
on sysvar sysvar::My::block_msg_268
{
if(@this==1)
{
ILFaultInjectionDisableMsg(TCU_T_APA268);
}
else
{
ILFaultInjectionEnableMsg(TCU_T_APA268);
}
}
*/
/*******Msg_Timeout DTC End*********/
dword applILTxPending (long aId, dword aDlc, byte data[])
{
switch (aId)
{
case 0x268:
UpdateProcessCounter(2);
if(1 == getValue(Env_rollingcounter_268))
{
/*error*/
}
else
{
data[6]=process_counter[2] & 0x0F;
}
//data[6]=process_counter[2] & 0x0F;
if(1 == getValue(Env_checksum_268))
{
/*error*/
}
else
{
data [7] = ClaculateChecksum_onebyte(0x268, 8, data);
}
//data [7] = ClaculateChecksum_onebyte(0x268, 8, data);
if(getvalue(Env_DlcError_268)==1)
ILFaultInjectionSetMsgDlc(TCU_T_APA268, 0);
else
ILFaultInjectionResetMsgDlc(TCU_T_APA268);
break;
default:
break;
return 1;
}
}
byte ClaculateChecksum_onebyte(long aId, long aDlc, byte pData[])
{
long checksum; //checksum is uint16
byte sum;
checksum = 0;
sum = 0;
checksum = pData[0] + pData[1]+ pData[2]+ pData[3]+ pData[4] + pData[5] + pData[6];
checksum = checksum ^ 0xFF;
sum = (byte) checksum;
return sum;
}
byte ClaculateChecksum_halfbyte(long aId, long aDlc, byte pData[])
{
byte checksum;
byte buffer_LSB = 0;
byte buffer_MSB = 0;
byte counter = 0;
checksum = 0;
for(counter = 0 ; counter < aDlc ; counter++)
{
checksum = (checksum & 0x0F) ^ ((pData[counter]) & 0x0F) ^ ((pData[counter]>>4) & 0x0F);
}
checksum = checksum & 0x0F;
return checksum;
}
void UpdateProcessCounter(byte counter)
{
if (process_counter[counter] >= FOUR_BITS_MAX)
{
process_counter[counter] =0;
}
else
{
process_counter[counter]++;
}
}
注意環境變量,Env_DlcError_268,Env_rollingcounter_268,Env_checksum_268
需要在DBC中定義:
TCU.can 2.0版本:
增加按鍵事件:比如按下b就掛倒檔(9):
on key ‘b’
{
Msg.byte(0) = 0xAA;
output(Msg);
// setSignal(EPBi::EPBi_T_APA256::EPB_Status,1);
setSignal(TCU::TCU_T_APA268::TCU_ActualGear,9);
}
完整如下:
/*@!Encoding:1252*/
/*@!Encoding:1252*/
includes
{
}
variables
{
const byte FOUR_BITS_MAX=15;
byte process_counter[14] = {0, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0};
byte checksum_sb[14] = {56, 56, 56, 56, 56, 56, 56, 60, 60, 60, 60, 60, 28, 32};
// message 0x268 TCU_T_APA268 = {dlc =1};
// message 0x7ff Msg= {dlc =1};
message 0x98 Msg= {dlc =1};
}
on key 'b'
{
Msg.byte(0) = 0xAA;
output(Msg);
// setSignal(EPBi::EPBi_T_APA256::EPB_Status,1);
setSignal(TCU::TCU_T_APA268::TCU_ActualGear,9);
}
/*******Msg_Timeout DTC Start*********/
/*
on sysvar sysvar::My::block_msg_268
{
if(@this==1)
{
ILFaultInjectionDisableMsg(TCU_T_APA268);
}
else
{
ILFaultInjectionEnableMsg(TCU_T_APA268);
}
}
*/
/*******Msg_Timeout DTC End*********/
dword applILTxPending (long aId, dword aDlc, byte data[])
{
switch (aId)
{
case 0x268:
UpdateProcessCounter(2);
if(1 == getValue(Env_rollingcounter_268))
{
/*error*/
}
else
{
data[6]=process_counter[2] & 0x0F;
}
//data[6]=process_counter[2] & 0x0F;
if(1 == getValue(Env_checksum_268))
{
/*error*/
}
else
{
data [7] = ClaculateChecksum_onebyte(0x268, 8, data);
}
//data [7] = ClaculateChecksum_onebyte(0x268, 8, data);
if(getvalue(Env_DlcError_268)==1)
ILFaultInjectionSetMsgDlc(TCU_T_APA268, 0);
else
ILFaultInjectionResetMsgDlc(TCU_T_APA268);
break;
default:
break;
return 1;
}
}
byte ClaculateChecksum_onebyte(long aId, long aDlc, byte pData[])
{
long checksum; //checksum is uint16
byte sum;
checksum = 0;
sum = 0;
checksum = pData[0] + pData[1]+ pData[2]+ pData[3]+ pData[4] + pData[5] + pData[6];
checksum = checksum ^ 0xFF;
sum = (byte) checksum;
return sum;
}
byte ClaculateChecksum_halfbyte(long aId, long aDlc, byte pData[])
{
byte checksum;
byte buffer_LSB = 0;
byte buffer_MSB = 0;
byte counter = 0;
checksum = 0;
for(counter = 0 ; counter < aDlc ; counter++)
{
checksum = (checksum & 0x0F) ^ ((pData[counter]) & 0x0F) ^ ((pData[counter]>>4) & 0x0F);
}
checksum = checksum & 0x0F;
return checksum;
}
void UpdateProcessCounter(byte counter)
{
if (process_counter[counter] >= FOUR_BITS_MAX)
{
process_counter[counter] =0;
}
else
{
process_counter[counter]++;
}
}
可以看到信號在按下b 後觸發了:
又比如,可以再加一個鍵盤事件:
on key 's'
{
ILFaultInjectionDisableMsg(TCU_T_APA268);
}
這個會stop msg
D4 8E 00 就是這條消息timeout 的DTC 。
那麼stop 消息後,要resend 怎麼辦呢?
on key 'e'
{
ILFaultInjectionEnableMsg(TCU_T_APA268);
}
Enable就好了。
注意信號和環境變量直接賦值時的符號,信號用$,環境變量用@
Setting a signal
To set signals you can either use the CANoe function
void setSignal(Signal sig, double value);
or the CAPL syntax for signal access
$Signalname = value;
Example
setSignal(MessageXYZ::SignalABC, 1.1) is equivalent to $SignalABC = 1.1;
HELP 裏面有很多有用的東西:
這個bus off的不會用,以後再研究。。。。。。。。。。。。。。。。。