使用J1939的DBC实现多包发送
(1)添加J1939DBC文件
在CAN网络中右键Databases,点击add,添加DBC文件。DBC文件路径:C:\Users\Public\Documents\Vector\CANoe\SampleConfigurations13.0.118\J1939\MoreExamples\TransportProtocol\J1939.dbc。
(2)Network节点CAPL编程
指定多包数据长度,使用for循环将message按照字节顺序发出去。关键代码如下:
//====================================capl=====================================================
on key 'S'
{
LONG size;
ConfigBRM();
size = pgBRM.dlc;
if ((size > 8) && (size <= 1785))
{
for( i = 1; i < size; i++ )
{
pgBRM.BYTE(i) = (i & 0xff);
}
output( pgBRM );
}
}
ConfigBRM()
{
LONG i;
LONG j;
pgBRM.dlc = 49;//0x31
pgBRM.dp = 0;
pgBRM.prio = 7;
// pgBRM.pf = 0x02;
pgBRM.pgn = 0x000200;
pgBRM.ps = 0x56;
pgBRM.edp = 0;
pgBRM.sa = 0xF4;
//初始化BRM报文数据域
}
//充电机收到多包请求,发送多包应答
on pg GBT27930::TPCMxx
{
if (this.ControlByte == 0x10 && this.sa == 0xf4)
{
if(this.PGNumber == 0x0200)//BRM PGN 0x000200
{
u32CurrentTPCM_PGN = 0x200;
@sysvar::GBT27930::BRM::ID::DLC = this.TotalMessageSize;
@sysvar::GBT27930::BRM::ID::PS = this.ps;
@sysvar::GBT27930::BRM::ID::SA = this.sa;
pgTPCM.ps = 0xF4;
pgTPCM.sa = 0x56;
pgTPCM.ControlByte = 0x11;
pgTPCM.NumberOfPacketsThatCanBeSent = this.TotalNumberOfPackets;
u8BRMtotalBytes = this.TotalMessageSize;
pgTPCM.NextPacketNumberToBeSent = 0x01;
pgTPCM.TotalNumberOfPackets = 0xff;
pgTPCM.MaximumNumberOfPackets = 0xff;
pgTPCM.PGNumber = 0x200;
output(pgTPCM); //TP.CM_CTS
}
}
}
//充电机收到多包数据,发送多包应答
on pg GBT27930::TPDT
{
float f32tmpTotalMaxPermChargingVoltage = 0.0;
float f32BatterySystemVoltage_tmp = 0.0;
char u8ManufacturerName[5];
char u8VIN[18];
char i = 0;
if(u32CurrentTPCM_PGN == 0x200)
{
if(this.SequenceNumber == 0x01)
{
//数据包1解析
}
else if(this.SequenceNumber == 0x02)
{
//数据包2解析
}
else if(this.SequenceNumber == 0x03)
{
//数据包3解析
}
else if(this.SequenceNumber == 0x04)
{
//数据包4解析
}
else if(this.SequenceNumber == 0x05)
{
//数据包5解析
}
else if(this.SequenceNumber == 0x06)
{
//数据包6解析
if(pgTPCM.NumberOfPacketsThatCanBeSent == 6){
pgTPCM.ps = 0xF4;
pgTPCM.sa = 0x56;
pgTPCM.ControlByte = 0x13;
pgTPCM.TotalMessageSize = u8BRMtotalBytes;
pgTPCM.TotalNumberOfPacketsEoMA = 0x06;
pgTPCM.PGNumber = 0x200;
output(pgTPCM);//有可能是6包数据,接收完成应答
}
}
else if(this.SequenceNumber == 0x07)
{
//数据包7解析
if(pgTPCM.NumberOfPacketsThatCanBeSent == 7){
pgTPCM.ps = 0xF4;
pgTPCM.sa = 0x56;
pgTPCM.ControlByte = 0x13;
pgTPCM.TotalMessageSize = u8BRMtotalBytes;
pgTPCM.TotalNumberOfPacketsEoMA = 0x07;
pgTPCM.PGNumber = 0x200;
output(pgTPCM);//有可能是7包数据,接收完成应答
}
}
}
}
在On pg TPCMxx和On pgTPDT中实现数据发送,数据接收,包括多包请求应答,多包数据接收完成应答
(3)多包报文接收
多包报文接收,使用on pgTPCMxx和on pgTPDT进行接收和解析。具体解析方法可参考demo工程。路径:C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 13.0.118\J1939\MoreExamples\TransportProtocol。
CANoe自带的Demo是基于CAN,在第二层链路层实现的。CAN只能发送DLC max = 8 byte 的数据,大于8个字节,就使用CAPL来实现分包发送。(当然规则是按照J1939 通信规则来的)这里应该是使用的多个output发送CAN报文实现的。
使用ISO 15765-2 TP层传输协议发送
(1)在测试节点处添加OSEK_TP.dll,该文件中封装了很多函数,可以在CAPL环境中直接使用。OSEK_TP.dll在CANoe安装目录下可搜索到。
(2)在help文档中搜索:OSEK_TP,了解使用方法:OSEK TP » Functions » Sending of Data » CanTpSendData。
CANoe的CanTp建模库(DLL)实现了CAN上的传输协议ISO/DIS 15765-2。它用于控制大量数据的传输。CANoe的安装目录中包含了建模库OSEK_TP.DLL,这使得使用ISO/DIS 15765-2 TP作为节点模型也很容易。
ISO 15765 也是基于CAN 的高层(传输层)协议。上层/应用层的>8 byte的数据会基于该协议进行分包发送。现在是基于UDS 诊断服务on CAN 会使用到,它和J1939 TP 的分包规则是不同的。对于CANoe和CAPL封装dll以及J1939协议较熟悉的情况下,可以自己使用C++封装dll文件实现多包的收发