Ref:J1939 Explained - A Simple Intro (2021)– CSS Electronics
Ref:CAN 帧ID 与J1939 PGN 转换例子_horse_2007s的博客-CSDN博客
Ref:在J1939中多帧数据如何发送,它是通过TP.CM_BAM和TP_DT报文发送_pvmsmfchcs的博客-CSDN博客
REf:tp.cm和tp.dt报文说明,为什么计算的pgn不对,1939里的GPN如何计算,什么时候的报文没有目标地址。_pvmsmfchcs的博客-CSDN博客
REf:解析CAN的J1939协议PDU报文_lx2385623371的博客-CSDN博客_j1939协议报文解读
大家看完以上的,也就清楚了,我还是根据个人理解,一步步展开。
根据其转换,利用J1939协议来解析。
主要说明:
1) PGN计算出现问题,如何解决的;
2)如何理解广播报文的含义,解释DM1的参数,DM1是啥,DTC是啥;
3)广播报文如何发送,需要拆分多少包;
由于这些内容是在实际做时遇到的具体问题,一个个问题解决。查阅了相关资料,感谢 @鼾声鼾语, @mengdeguodu_
部分内容是摘要其他blog的,已经加了引用出处。若侵权,请留言删除!
先贴概念:
DA表示报文要发送的目标地址
GE表示PS在PDU2中与PF的4个最低有效位能够共同确定4096个PDU2格式参数组
参数组与PGN
参数组数目=[240(PDU1)+16*256(PDU2)]*2(DP)=8672
PGN计算
PDU1格式:PGN=PF*256
PDU2格式:PGN=PF*256+GE
The J1939 protocol has a set of defining characteristics outlined below:
250K baud rate &29-bit extended ID
The J1939 baud rate is typically 250K (though recently with support for 500K) - and the identifier is extended 29-bit (CAN 2.0A)
Broadcast + on-request data
Most J1939 messages are broadcast on the CAN-bus, though some data is only available by requesting the data via the CAN bus
PGN identifiers & SPN parameters
J1939 messages are identified by 18(16,在广播报文里)-bit Parameter Group Numbers (PGN), while J1939 signals are called Suspect Parameter Numbers (SPN)
Multibyte variables & Multi-packets
Multibyte variables are sent least significant byte first (Intel byte order). PGNs with up to 1785 bytes are supported via J1939 transport protocol
举个栗子:
如18F00010, 按照定义可知PGN为61440, 根据1939-71可查到其对应的参数。
查看中文版
18ECFF10--->PGN 60671,未查到。00EC00--->60416;
18EBFF10-->PGN 60415,未查到。00EB00-->60160
原因: 广播报文需要按照 PDU format来算,其余的补0。
修改代码:这样还可以通过PDU format来查询。感谢 @鼾声憨语 的帮助
根据 CAN 帧ID 与J1939 PGN 转换例子_horse_2007s的博客-CSDN博客
PDU格式PF:PDU有两种类型PDU1和PDU2,PDU1向特定地址发送报文,PDU2向全局地址发送报文。
当PF为0~239时,表征报文为PDU1;
当PF为240~255时,表征报文为PDU2。
特定域PS:功能由PF决定,
当PF为PDU1时,PS表示目标地址;
当PF为PDU2时,与PS的4个最低有效位能够共同确定4096个PDU2格式参数组。
程序修改:(程序上传到个人资源: J1939的ID转PGN码源码程序)
根据SAEJ1939-21(参考5.10.1),长度大于8字节的消息被拆分成若干个小的数据包,然后使用单独的数据帧对其逐一传送。每个数据包都会被分配搭配一个从1到255的序列编号。最后一个数据包的数据域余下未使用的字节全部设置为“FF”
[例子:感谢! @mengdeguodu_
SA:=41
Ref: J1939广播DM1报文_mengdeguodu_的博客-CSDN博客
SAEJ1939-73中定义DM1字节1为灯状态,字节2预留,当字节1=00,字节2=FF,0x41节点完整的DM1报文为:0x18FECA41:00 FF AC F3 E1 01 30 F3 E3 01,字节数大于8,将会使用“多帧传输”参数组。
所以0x18FECA41:00 FF AC F3 E1 01 30 F3 E3 01将会被拆分成两条:01 00 FF AC F3 E1 01 30,02 F3 E3 01 FF FF FF FF
TP.DT报文ID为:0x18EBFF41
]
SAEJ1939-21(5.10.3),定义了链接管理TP.CM(BAM为其中一种)的参数群编号为60416(00EC00),BAM的目标地址为全局目标地址。
【根据SAEJ1939-21(5.2.5): 若PDU 格式(PF)段的值小于240,特定PDU 段是目标地址。若PF 段的值在240 和255 之间,特定PDU 包含群扩展(GE)值。全局目标地址(255)要求所有设备作为消息响应者作出监听和响应。】
ref:452_J1939广播多帧报文的例程分析_小灰笔记-CSDN博客
这个流程图就是J1939的广播多帧报文的实现, 流程是先发送一帧TP.CM_BAM的报文,然后是一连串的数据包。
TP.CM_BAM采用的是一个特殊的PGN 60416。
如报文,8个字节: 0X18ECFF10: 20(控制字),A,0(字节长度),2(2包),FF(reserved),CA,FE (PGN:FECA),0
接下来,进行数据的传输。而传输所用到的功能是另一个特殊PGN 60160,也就是TP.DT。具体的信息如下:
由于是广播多帧报文,目标地址是全局地址。另外,里面包含了数据包的编号和数据。而帧间隔的最小时间为50ms。
收到的报文: 18EBFF10.
REf:在J1939中多帧数据如何发送,它是通过TP.CM_BAM和TP_DT报文发送_pvmsmfchcs的博客-CSDN博客
[这个时候就要用到TP.CM_BAM和TP_DT报文了
首先如果是单帧报文,那么他们用各自的ID直接发送到总线上
如果是多帧数据就需要用到TP_DT了,
例如:DM1多帧发送故障数据到总线,那么发送的过程是如下:
SA=0X10, 缓速器ID。 BAM报文ID为:0x18ECFF10
首先发送TP.CM_BAM,其中包含的信息有:
ID :18ECFF10 + Control byte (0X20 ) +故障信息的大小(0X00A,共10个),字节总数(2)+包的个数(0xFF,没有限制)+DM1的PGN(FECA)
SA:=0x10.
2 然后发送TP.DT多帧数据,其中包含的信息有:
多帧数据的序号+多帧数据
4,SAEJ1939-21(5.10.5)定义了数据传送TP.DT的参数群编号为60160(00EB00),对BAM数据传送使用全局地址。
所以0x18ECFF10 的TP.DT报文ID为:0x18EBFF10
3,如果发送的是单帧数据,那么则直接发送一条DM1就可以了,但是事实上这种TP.CM_BAM和TP_DT报文组合方式,发送多帧情况很多。
DM1多帧发送故障,两个故障一般就会出现多帧的情况因为一般灯的故障状态就需要占用四个字节,故障占用4个字节,两个故障共用灯故障的情况下占用10个字节,也就是两帧数据了]
18ECFF10里的SA=0X10, PGN=0xFECA。
上图接收了第1包数据(D0=1)字节1, 为什么后面不是00FF 开始呢?
贴了一个SA=0X41发送2个报文的例子,
@mengdeguodu_
ref: J1939广播DM1报文_mengdeguodu_的博客-CSDN博客
字节 00 AC F3 E1 01
30 F3 E3 01 FF
广播里的PGN :00FECA。 作用是啥(DM1,故障诊断)?用于说明接下来的多帧报文的具体的作用? 什么作用》
Ref:J1939 Diagnostics - Part 1 - Embedded Flakes
SAEJ1939-73(参考5.7.1)中定义了DM1的优先级为6,PGN(参数组数编号)为65226(00FECA)
DM1 message uses PGN 65226 (0xFECA). DM1 message is sent periodically only when there is an active DTC or in the response of the request.
DM1 message contains information of all active DTCs and diagnostic lamp status. The lamp status supports visual diagnostics and used by fault indicators on a vehicle dashboard.
For a DTC becoming active and inactive twice within the 1-second interval, only one DM1 message is sent in the one-second interval.
The following table shows the DM1 message format.
Default Priority | 6 |
PDU Format | 254 |
PDU Specific | 202 |
PGN | 65226 (0xFECA) |
Byte 1 – bits 8-7 | Malfunction Indicator Lamp status |
Byte 1 -bits 6-5 | Red Stop Lamp status |
Byte 1 -bits 4-3 | Amber Warning Lamp status |
Byte 1 -bits 2-1 | Protect Lamp status |
Byte 2 – bits 8-7 | Reserved |
Byte 2 -bits 6-5 | Reserved |
Byte 2 -bits 4-3 | Reserved |
Byte 2 -bits 2-1 | Reserved |
Byte 3 – bits 8-1 | SPN |
Byte 4 – bits 8-1 | SPN |
Byte 5 – bits 8-6 | SPN |
Byte 5 -bits 5-1 | FMI |
Byte 6 – bit 8 | SPN Conversion Method (CM) |
Byte 6 -bit 7-1 | Occurance Count (OC) |
该 FMI 定义了为SPN 所识别的子系统中发现的故障类型。注意,该故障可能不是电子故障,但相反可能是需要报告给设备技术员甚至操作员的子系统故障
或条件,这些条件包括需要报告的系统事件或状态。FMI、SPN 为预留的和发生次数域组合已知的诊断故障代码。如果另外的故障模式是必需的, FMI 将由
CATARC 来赋值。当前定义的FMI 列于附录A。
两个故障一般就会出现多帧的情况因为一般灯的故障状态就需要占用四个字节,故障占用4个字节
由于DCT 需要4个字节,2个故障就需要8个字节,加上 DM1 特定 起始字节00 FF, 因此需要传10个字节,2个报文
用NI板卡可以直接解析J1939。
找到了福伊特的定义,但与我用到的不一样。
18EBFF10h,是多帧数据。
DTC格式: 1011 1000 0000 0100 000 0 0011 0 000 1010
SPN(19位): 1208(d)=000 00000100 1011 1000(2)
FMI 3=00011(2)
OC 10=0001010
CM =0
就是小端模式,之前理解错了,一直没能正确解析DTC 报文。