一、报文格式
1.1协议数据单元(Protocol Data Unit, PDU)
J1939报文使用的基于CAN2.0B的拓展帧格式定义了一个完整的标准化通讯策略,通过PDU定义了一个框架,用来组织数据帧中J1939协议相关的信息。PDU由数据帧中的ID和数据场组成,数据帧和PDU的对应关系如下图所示。
- P(Priority),优先级字段,用于在仲裁过程中控制报文优先级。
- EDP(Extended Data Page),为扩展数据页位,在J1939中固定取值为0。
- P(Data Page),数据页位,可用来扩展参数组的数量。
- PF(PDU Format),为PDU格式字段,通过不同的取值来确定参数组编号(Parameter Group Number, PGN)是按照PDU1格式还是PDU2格式。
- PS(PDU Specific),特定协议数据单元字段,当PF的值为0-239时PS表示目标地址(PDU1格式),当PF的值为240-255时PS字段表示组扩展(PDU2格式),且报文只能广播。
- SA(Source Address),源地址字段,整个网络中SA的值必须是唯一的。
- Data Field,数据场,对于Classic CAN来说是8个字节,而CANFD则最多有64个字节数据。如果需要传输更多的数据,则需要借助J1939的传输协议。
图2. CAN2.0B帧格式与J1939PDU的对应关系
1.2参数组编号(PGN)
参数组是应用层中定义的与某个ECU相关的具有相同控制功能的若干个参数的组合,而PGN是用于唯一标识参数组的号码,在应用层中定义。PGN由三个字节组成,从最高位开始的前6个比特默认值为0,然后是EDP位和DP位,接下来两个字节分别是PF和PS。
图3. PDU与PGN的对应关系
1.3实例分析
实例分析1
typedef struct{
uint8 pf; //PF:为PDU格式字段,通过不同的取值来确定
//参数组编号(Parameter Group Number, PGN)是按照PDU1格式还是PDU2格式。
uint8 ps; //PS:特定协议数据单元字段,当PF的值为0-239时PS表示目标地址(PDU1格式),
//当PF的值为240-255时PS字段表示组扩展(PDU2格式),且报文只能广播。
uint8 prior; //优先级
uint8 framtype; //数据帧格式:标准帧还是扩展帧
uint8 transtype; //传递格式:规定传输方向
uint16 rate; //通信速率
}CCS_SLAVE_PROTOCAL_CONST_PARA;CCS_SLAVE_PROTOCAL_CONST_PARA const CCS_SLAVE_TX_PARA[CCS_SLAVE_TX_TOTAL]={
{0xE1,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,150}, //WL
{0xE2,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,160}, //WL
{0xE3,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,170}, //WL
{0xE4,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,180}, //WL
{0xE5,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,190}, //WL
{0xE6,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,200}, //WL
{0xEA,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,110}, //18
{0xEB,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,120}, //18
{0xEC,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,130}, //18
{0xED,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,140}, //18
// {0xEE,0xE0,6, CAN_FRAMTYPE_EXT,TT_ASYNC,550}, //18
};
将CCS_SLAVE_PROTOCAL_CONST_PARA结构体进行赋值,并进行初始化。CCS_SLAVE_TX_TOTAL代表了结构体的数量,了解枚举结构体的使用方法;
typedef enum{
CCS_SLAVE_TX_18E1E0XX=0,//WL
CCS_SLAVE_TX_18E2E0XX,//WL
CCS_SLAVE_TX_18E3E0XX,//WL
CCS_SLAVE_TX_18E4E0XX,//WL
CCS_SLAVE_TX_18E5E0XX,//WL
CCS_SLAVE_TX_18E6E0XX,//WLCCS_SLAVE_TX_18EAE0XX,//WL
CCS_SLAVE_TX_18EBE0XX,
CCS_SLAVE_TX_18ECE0XX,
CCS_SLAVE_TX_18EDE0XX,
// CCS_SLAVE_TX_18EEE0XX,CCS_SLAVE_TX_TOTAL
}CCS_SLAVEGAPP_PGN_TX;
枚举(enum)是一种数据类型,它的语法定义格式为:
enum 枚举名{枚举元素1,枚举元素2,......};
例如,一个星期有七天,使用枚举法进行定义为:
enum Day
{
Mon,Tue,Wed,Thu,Fri,Sat,Sun
};
需要注意的是,第一个枚举元素的默认值为0,后面的枚举元素的值在上一枚举元素的值上加1。因此,Mon=0,Tue=1,Wed=2,Thu=3,Fri=4,Sat=5,Sun=6.
但是,在定义枚举类型时,可以改变枚举元素的值:
enum Day
{
Mon=1,Tue,Wed,Thu,Fri,Sat,Sun
};
此时,Mon=1,Tue=2依次往后推;
enum Day
{
Mon,Tue,Wed=3,Thu,Fri,Sat,Sun
};
此时,Mon=0,Tue=1,Wed=3,Thu=4,Fri=5,Sat=6,Sun=7.