eric2013 发表于 2024-1-8 01:20:54

BSP视频教程第29期:J1939协议栈CAN总线专题,源码框架,执行流程和应用实战解析,面向车通讯,充电桩,模组通信等(2024-01-08)

继前面CANopen专题视频教程后,再推出CAN总线的又一个重要协议栈J1939专题视频

J1939在车通讯上应用比较多,现在电动车充电桩还有各种模组的通信也非常多基于1939协议实现的。

掌握一个协议栈,主要就是研究明白程序框架和协议栈执行流程,这样将这款协议栈应用的各种应用会得心应手。

视频:
https://www.bilibili.com/video/BV1GC4y1v72P

https://www.bilibili.com/video/BV1GC4y1v72P

视频提纲

https://img.alicdn.com/imgextra/i2/299314119/O1CN01IC7FCk1gIYJNtn1dc_!!299314119.png

https://img.alicdn.com/imgextra/i2/299314119/O1CN01n9tXIR1gIYJB9UD2d_!!299314119.png

https://img.alicdn.com/imgextra/i1/299314119/O1CN016pdxEb1gIYJGoDVVx_!!299314119.png

https://img.alicdn.com/imgextra/i2/299314119/O1CN01vLqWii1gIYJOZURJd_!!299314119.png

https://img.alicdn.com/imgextra/i1/299314119/O1CN01Q6N8fv1gIYJLnM8lH_!!299314119.png


案例下载
https://www.armbbs.cn/static/image/filetype/pdf.gifOpen SAE J1939.pdf (318.83KB)
https://www.armbbs.cn/static/image/filetype/zip.gifV7-091_J1939协议栈(250Kbps).7z (25.87MB)

参考资料
1、OpenSAEJ1939开源地址
https://github.com/DanielMartensson/Open-SAE-J1939

2、SAE J1939官方文档
https://www.sae.org/standards/de ... llection-on-the-web

3、Microchip的J1939 C库应用笔记和源码
https://www.armbbs.cn/forum.php?mod=viewthread&tid=122047

4、Matlab的J1939支持
https://ww2.mathworks.cn/help/vnt/j1939-communication.html

5、客户分享H7-TOOL CAN助手的GBT27930-2015电动汽车充电桩车通信和英飞凌电源模组解析
https://www.armbbs.cn/forum.php?mod=viewthread&tid=122150

6、客户分享的H7-TOOL车辆J1939协议解析
https://www.armbbs.cn/forum.php?mod=viewthread&tid=112882

7、H7-TOOL的通用J1939解析器
https://www.armbbs.cn/forum.php?mod=viewthread&tid=122456

eric2013 发表于 2024-1-8 01:55:54

更新完毕,

hekaidi 发表于 2024-1-8 09:09:04




请教一下,TP_CM报文中,TP_RTS发送到TP_CTS应答,这个超时时间在代码哪个位置,以及TP DATA的超时

eric2013 发表于 2024-1-8 09:38:49

hekaidi 发表于 2024-1-8 09:09
请教一下,TP_CM报文中,TP_RTS发送到TP_CTS应答,这个超时时间在代码哪个位置,以及TP DATA的超时
这个协议栈是直接做了固定的延迟接口处理的。

/*
* Send sequence data packages to other ECU that we have loaded
* PGN: 0x00EB00 (60160)
*/
ENUM_J1939_STATUS_CODES SAE_J1939_Send_Transport_Protocol_Data_Transfer(J1939 *j1939, uint8_t DA){
        uint32_t ID = (0x1CEB << 16) | (DA << 8) | j1939->information_this_ECU.this_ECU_address;
        uint8_t i, j, package;
        uint16_t bytes_sent = 0;
        ENUM_J1939_STATUS_CODES status = STATUS_SEND_OK;
        for(i = 1; i <= j1939->this_ecu_tp_cm.number_of_packages; i++) {
                package = i;                                                                                                                                         /* Number of package */
                for(j = 0; j < 7; j++){
                        if(bytes_sent < j1939->this_ecu_tp_cm.total_message_size){
                                package = j1939->this_ecu_tp_dt.data;                                        /* Data that we have collected */
                        }else{
                                package = 0xFF;                                                                                                                 /* Reserved */
                        }
                }
                status = CAN_Send_Message(ID, package);
                CAN_Delay(100);                                                                                                                                                /* Important CAN delay according to standard */
                if(status != STATUS_SEND_OK){
                        return status;
                }
        }
        return status;
}

missfox 发表于 2024-1-8 10:43:41

给力,更新很及时{:8:}

bigbigcong 发表于 2024-1-8 11:14:52

牛逼

litin326 发表于 2024-1-9 08:23:46

{:8:}{:8:}{:8:}

litin326 发表于 2024-1-9 08:28:27

兄弟,你们承接外包项目吗?

eric2013 发表于 2024-1-9 09:04:15

litin326 发表于 2024-1-9 08:28
兄弟,你们承接外包项目吗?

工作量太大了,基本不怎么接项目了。:handshake

可以连接我们旺旺,公司那边可能接项目

zhongwenhua 发表于 2024-1-9 23:19:12

咨询一个问题,比如说Message iD 写的是14ef23 'SA'   但是您发送的却是 18EA80'SA'

eric2013 发表于 2024-1-10 00:53:54

zhongwenhua 发表于 2024-1-9 23:19
咨询一个问题,比如说Message iD 写的是14ef23 'SA'   但是您发送的却是 18EA80'SA'
18EA80'SA' 是发送14ef23 'SA'的PNG请求,此时如果参数j1939->this_proprietary.proprietary_A.total_bytes小于等于8,那么反馈的Message iD就是14ef23 'SA'




如果参数j1939->this_proprietary.proprietary_A.total_bytes大于8的话,就会反馈Multiple messages,通过TP_CM和TP_DT反馈


ENUM_J1939_STATUS_CODES SAE_J1939_Response_Request_Proprietary_A(J1939* j1939, uint8_t DA) {
        /* Find the length of the array fields */
        uint16_t length_of_each_field = j1939->this_proprietary.proprietary_A.total_bytes;
        if (length_of_each_field < 9) {
                /* If each field have the length 8 or less, then we can send Proprietary A as it was a normal message */
                uint32_t ID = (0x14EF23 << 8) | j1939->information_this_ECU.this_ECU_address;
                uint8_t data;
                memcpy(data, j1939->this_proprietary.proprietary_A.data, length_of_each_field);
                return CAN_Send_Message(ID, data);
        }
        else {
                /* Multiple messages - Load data */
                j1939->this_ecu_tp_cm.total_message_size = length_of_each_field;
                memcpy(j1939->this_ecu_tp_dt.data, j1939->this_proprietary.proprietary_A.data, length_of_each_field);
               
                /* Send TP CM */
                j1939->this_ecu_tp_cm.number_of_packages = j1939->this_ecu_tp_cm.total_message_size % 8 > 0 ? j1939->this_ecu_tp_cm.total_message_size / 8 + 1 : j1939->this_ecu_tp_cm.total_message_size / 8; /* Rounding up */
                j1939->this_ecu_tp_cm.PGN_of_the_packeted_message = PGN_PROPRIETARY_A;
                j1939->this_ecu_tp_cm.control_byte = DA == 0xFF ? CONTROL_BYTE_TP_CM_BAM : CONTROL_BYTE_TP_CM_RTS; /* If broadcast, then use BAM control byte */
                ENUM_J1939_STATUS_CODES status = SAE_J1939_Send_Transport_Protocol_Connection_Management(j1939, DA);
                if (status != STATUS_SEND_OK) {
                        return status;
                }

                /* Check if we are going to send it directly (BAM) - Else, the TP CM will send a RTS control byte to the other ECU and the ECU will answer with control byte CTS */
                if (j1939->this_ecu_tp_cm.control_byte == CONTROL_BYTE_TP_CM_BAM) {
                        return SAE_J1939_Send_Transport_Protocol_Data_Transfer(j1939, DA);
                }
                return status;
        }
}




zhongwenhua 发表于 2024-1-10 11:17:39

eric2013 发表于 2024-1-10 00:53
18EA80'SA' 是发送14ef23 'SA'的PNG请求,此时如果参数j1939->this_proprietary.proprietary_A.total_byt ...

Proprietary_A在您上面的tool截图中,小于等于8字节数据传输中,返回的帧id应该是uint32_t ID = (0x14EF23 << 8) | j1939->information_this_ECU.this_ECU_address;
但是你截图中却是uint32_t ID = (0x1CEC << 16) | (DA << 8) | j1939->information_this_ECU.this_ECU_address;数据中第二第三字节是数据大小,截图中却是0F,您这条tool截图是对应的,上面的是不是搞错啦,

zhongwenhua 发表于 2024-1-10 11:19:13

eric2013 发表于 2024-1-10 00:53
18EA80'SA' 是发送14ef23 'SA'的PNG请求,此时如果参数j1939->this_proprietary.proprietary_A.total_byt ...

这个截图中的是不是错的

zhongwenhua 发表于 2024-1-10 11:43:29

还有一个问题我一直没搞懂,PGN不是在PDU中,怎么PGN却在data中体现了,是因为帧id 0X18EA'DA''SA'是发起请求的id是吗,data中跟的就是PGN,然后再等待对应设备返回,此时对应的设备返回的帧id就是PGN,data中的数据就是实际的数据,通过SPN去查找换成出实际值,是我理解的这样吗

eric2013 发表于 2024-1-10 12:17:56

zhongwenhua 发表于 2024-1-10 11:43
还有一个问题我一直没搞懂,PGN不是在PDU中,怎么PGN却在data中体现了,是因为帧id 0X18EA'DA''SA'是发起请 ...
这个是PGN请求,他这个请求的数据里面是跟的PNG值,就是这个截图:



eric2013 发表于 2024-1-10 12:24:37

zhongwenhua 发表于 2024-1-10 11:19
这个截图中的是不是错的
这个得修改下,小于等于8,得是12楼的图。

在Startup_ECU.c文件这里,他配置了一个大于8的值。
#define MAX_PROPRIETARY 15
j1939->this_proprietary.proprietary_A.total_bytes = MAX_PROPRIETARY;

导致返回是执行的TP_CM和TP_DT消息。如果小于等于8就是12楼的截图了。

haoyang877 发表于 2024-1-10 13:04:39

大佬牛逼,如获至宝

zhongwenhua 发表于 2024-1-10 13:37:43

eric2013 发表于 2024-1-10 12:17
这个是PGN请求,他这个请求的数据里面是跟的PNG值,就是这个截图:

感谢回复,谢谢您的耐心解答

xmcxsta 发表于 2024-1-15 16:44:26

CAN还有UDS,可以搞个这个专题,通过CAN接口进行IAP升级可以使用UDS协议

eric2013 发表于 2024-1-15 17:28:53

xmcxsta 发表于 2024-1-15 16:44
CAN还有UDS,可以搞个这个专题,通过CAN接口进行IAP升级可以使用UDS协议

下一个专题就是UDS

hekaidi 发表于 2024-1-16 18:53:20



https://img.anfulai.cn/dz/attachment/forum/202401/08/093813bbt4vtbqyz9u1pnt.png
多包发送的时候:
void SAE_J1939_Read_Transport_Protocol_Connection_Management(J1939 *j1939, uint8_t SA, uint8_t data[]) {
        j1939->from_other_ecu_tp_cm.control_byte = data;
        j1939->from_other_ecu_tp_cm.total_message_size = (data << 8) | data;
        j1939->from_other_ecu_tp_cm.number_of_packages = data;
        j1939->from_other_ecu_tp_cm.PGN_of_the_packeted_message = (data << 16) | (data << 8) | data;
        j1939->from_other_ecu_tp_cm.from_ecu_address = SA;

        /* Check if we got the Request To Send control byte - We need to answer with CTS - Clear To Send */
        if(j1939->from_other_ecu_tp_cm.control_byte == CONTROL_BYTE_TP_CM_RTS){
                j1939->this_ecu_tp_cm = j1939->from_other_ecu_tp_cm;                         /* Copy - We need to have the same data */
                j1939->this_ecu_tp_cm.control_byte = CONTROL_BYTE_TP_CM_CTS;        /* We only need to change the control byte from RTS to CTS */
                SAE_J1939_Send_Transport_Protocol_Connection_Management(j1939, SA);
        }

        /* When we answer with CTS, it means we are going to send the Transport Protocol Data Transfer package */
        if(j1939->from_other_ecu_tp_cm.control_byte == CONTROL_BYTE_TP_CM_CTS){
                SAE_J1939_Send_Transport_Protocol_Data_Transfer(j1939, SA);
        }
}

发送节点(TP.CM_RTS):CANID:0x1CEC 'DS' 'SA ',Data = 0x10 ,
接收节点(TP.CM_CTS):Open_SAE_J1939_Listen_For_Messages--->SAE_J1939_Read_Transport_Protocol_Connection_Management--->SAE_J1939_Send_Transport_Protocol_Connection_Management;这个T2=1250ms这个超时处理在哪里实现吧,方便告诉一下吗


发送节点(TP.DT):CANID:0x1CEB 'DS' 'SA' ,
接收方:Open_SAE_J1939_Listen_For_Messages--->SAE_J1939_Read_Transport_Protocol_Data_Transfer;第n个数据包和第n+1个数据包的时间间隔T1=750ms这个超时处理在哪里实现吧,方便告诉一下吗

eric2013 发表于 2024-1-17 08:18:32

hekaidi 发表于 2024-1-16 18:53
多包发送的时候:
void SAE_J1939_Read_Transport_Protocol_Connection_Management(J1939 *j1939, u ...
我认为这个不处理没关系的。比如这个1250ms是消息往返中的超时时间。这种时间足够处理的过来。

还有750ms的两条消息间隔,这个更是没问题了。我提供的程序底层是一条消息完毕,紧接着就行下一条消息。

qy0957 发表于 2024-1-17 16:16:59

{:8:}{:8:}{:8:}

xmcxsta 发表于 2024-1-24 15:27:49

J1939中文文档有吗,我只找到了几篇

eric2013 发表于 2024-1-25 00:34:59

xmcxsta 发表于 2024-1-24 15:27
J1939中文文档有吗,我只找到了几篇

下载国标的,那个是中文的。

jackem 发表于 2024-1-25 08:34:51

硬汉非常给力,mark

jackem 发表于 2024-2-2 20:19:09

J1939协议栈CAN总线专题,UDS协议关注。

812126060 发表于 2024-2-26 22:15:16

:lol硬汉哥给力plus。坐等USD。

ambitious 发表于 2024-2-27 17:56:21

有比较的15765的协议栈吗

eric2013 发表于 2024-2-28 01:07:22

ambitious 发表于 2024-2-27 17:56
有比较的15765的协议栈吗

要发布的UDS专题视频里面带ISO15762

vuxtvg 发表于 2024-4-1 09:57:14

移植明白了,但还是有点不会用,我想向指定的地址发送单帧和多帧的消息

eric2013 发表于 2024-4-2 08:08:08

vuxtvg 发表于 2024-4-1 09:57
移植明白了,但还是有点不会用,我想向指定的地址发送单帧和多帧的消息

直接调用API操作就行。

xmcxsta 发表于 2024-4-17 15:55:53

发送TP_DT多帧,每帧之间之间来个delay?那逻辑不之间死了?根据标准多包周期50 -200ms
还有连接管理,“无论发送者还是响应者,由于某一原因(包括超时)决定要关闭连接,它都应该发出一条放弃连接消息”这个也没有

eric2013 发表于 2024-4-17 16:06:58

xmcxsta 发表于 2024-4-17 15:55
发送TP_DT多帧,每帧之间之间来个delay?那逻辑不之间死了?根据标准多包周期50 -200ms
还有连接管理,“ ...

这个协议栈,时间处理的地方不够专业,大家可以魔改下。

xmcxsta 发表于 2024-4-17 16:22:22

eric2013 发表于 2024-4-17 16:06
这个协议栈,时间处理的地方不够专业,大家可以魔改下。

国标目前在编,潍柴集团参与了,和潍柴发动机打交道任何不满足的地方都可能出问题,导致被潍柴判刑(罚款):'(

eric2013 发表于 2024-4-18 08:48:42

xmcxsta 发表于 2024-4-17 16:22
国标目前在编,潍柴集团参与了,和潍柴发动机打交道任何不满足的地方都可能出问题,导致被潍柴判刑(罚款 ...

车机场合,必须严格按照要求来。
页: [1]
查看完整版本: BSP视频教程第29期:J1939协议栈CAN总线专题,源码框架,执行流程和应用实战解析,面向车通讯,充电桩,模组通信等(2024-01-08)