请选择 进入手机版 | 继续访问电脑版

硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4082|回复: 31
收起左侧

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

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
发表于 2024-1-8 01:20:54 | 显示全部楼层 |阅读模式
继前面CANopen专题视频教程后,再推出CAN总线的又一个重要协议栈J1939专题视频

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

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

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



视频提纲












案例下载
Open SAE J1939.pdf (318.83KB)
V7-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

评分

参与人数 2金币 +40 收起 理由
812126060 + 20 赞一个!
missfox + 20 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-8 01:55:54 | 显示全部楼层
更新完毕,
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2024-1-8 09:09:04 | 显示全部楼层

下载 (1).png

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-8 09:38:49 | 显示全部楼层
hekaidi 发表于 2024-1-8 09:09
请教一下,TP_CM报文中,TP_RTS发送到TP_CTS应答,这个超时时间在代码哪个位置,以及TP DATA的超时

这个协议栈是直接做了固定的延迟接口处理的。

[C] 纯文本查看 复制代码
/*
 * 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[8];
	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[0] = i; 																	/* Number of package */
		for(j = 0; j < 7; j++){
			if(bytes_sent < j1939->this_ecu_tp_cm.total_message_size){
				package[j+1] = j1939->this_ecu_tp_dt.data[bytes_sent++];					/* Data that we have collected */
			}else{
				package[j+1] = 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;
}

回复

使用道具 举报

23

主题

1403

回帖

1472

积分

至尊会员

积分
1472
发表于 2024-1-8 10:43:41 | 显示全部楼层
给力,更新很及时
代码不规范,亲人两行泪!
回复

使用道具 举报

3

主题

48

回帖

57

积分

初级会员

积分
57
发表于 2024-1-8 11:14:52 | 显示全部楼层
牛逼
回复

使用道具 举报

8

主题

133

回帖

167

积分

初级会员

积分
167
发表于 2024-1-9 08:23:46 | 显示全部楼层
回复

使用道具 举报

8

主题

133

回帖

167

积分

初级会员

积分
167
发表于 2024-1-9 08:28:27 | 显示全部楼层
兄弟,你们承接外包项目吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-9 09:04:15 | 显示全部楼层
litin326 发表于 2024-1-9 08:28
兄弟,你们承接外包项目吗?

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

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

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-1-9 23:19:12 | 显示全部楼层
咨询一个问题,比如说Message iD 写的是14ef23 'SA'   但是您发送的却是 18EA80'SA'
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 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'


124.png

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


[C] 纯文本查看 复制代码
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[8];
		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;
	}
}





回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 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截图是对应的,上面的是不是搞错啦,
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-1-10 11:19:13 | 显示全部楼层
eric2013 发表于 2024-1-10 00:53
18EA80'SA' 是发送14ef23 'SA'的PNG请求,此时如果参数j1939->this_proprietary.proprietary_A.total_byt ...

这个截图中的是不是错的
Snipaste_2024-01-10_11-18-35.jpg
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-1-10 11:43:29 | 显示全部楼层
还有一个问题我一直没搞懂,PGN不是在PDU中,怎么PGN却在data中体现了,是因为帧id 0X18EA'DA''SA'是发起请求的id是吗,data中跟的就是PGN,然后再等待对应设备返回,此时对应的设备返回的帧id就是PGN,data中的数据就是实际的数据,通过SPN去查找换成出实际值,是我理解的这样吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-10 12:17:56 | 显示全部楼层
zhongwenhua 发表于 2024-1-10 11:43
还有一个问题我一直没搞懂,PGN不是在PDU中,怎么PGN却在data中体现了,是因为帧id 0X18EA'DA''SA'是发起请 ...

这个是PGN请求,他这个请求的数据里面是跟的PNG值,就是这个截图:


123456.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 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楼的截图了。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2024-1-10 13:04:39 | 显示全部楼层
大佬牛逼,如获至宝
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-1-10 13:37:43 | 显示全部楼层
eric2013 发表于 2024-1-10 12:17
这个是PGN请求,他这个请求的数据里面是跟的PNG值,就是这个截图:

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

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2024-1-15 16:44:26 | 显示全部楼层
CAN还有UDS,可以搞个这个专题,通过CAN接口进行IAP升级可以使用UDS协议
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-15 17:28:53 | 显示全部楼层
xmcxsta 发表于 2024-1-15 16:44
CAN还有UDS,可以搞个这个专题,通过CAN接口进行IAP升级可以使用UDS协议

下一个专题就是UDS
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2024-1-16 18:53:20 | 显示全部楼层



多包发送的时候:
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[0];
        j1939->from_other_ecu_tp_cm.total_message_size = (data[2] << 8) | data[1];
        j1939->from_other_ecu_tp_cm.number_of_packages = data[3];
        j1939->from_other_ecu_tp_cm.PGN_of_the_packeted_message = (data[7] << 16) | (data[6] << 8) | data[5];
        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[0] = 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这个超时处理在哪里实现吧,方便告诉一下吗

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 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的两条消息间隔,这个更是没问题了。我提供的程序底层是一条消息完毕,紧接着就行下一条消息。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-1-17 16:16:59 | 显示全部楼层
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2024-1-24 15:27:49 | 显示全部楼层
J1939中文文档有吗,我只找到了几篇

SAE_1939培训笔记.pdf

2.1 MB, 下载次数: 20

SAE_J1939培应用培训.pdf

1.02 MB, 下载次数: 15

SAE1939-81.pdf

428.4 KB, 下载次数: 17

SAE-J1939-21.pdf

578.03 KB, 下载次数: 19

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-1-25 00:34:59 | 显示全部楼层
xmcxsta 发表于 2024-1-24 15:27
J1939中文文档有吗,我只找到了几篇

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

使用道具 举报

0

主题

44

回帖

44

积分

新手上路

积分
44
发表于 2024-1-25 08:34:51 | 显示全部楼层
硬汉非常给力,mark
回复

使用道具 举报

0

主题

44

回帖

44

积分

新手上路

积分
44
发表于 2024-2-2 20:19:09 | 显示全部楼层
J1939协议栈CAN总线专题,UDS协议关注。
回复

使用道具 举报

3

主题

12

回帖

21

积分

新手上路

积分
21
发表于 2024-2-26 22:15:16 | 显示全部楼层
硬汉哥给力plus。坐等USD。
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
发表于 2024-2-27 17:56:21 | 显示全部楼层
有比较的15765的协议栈吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-2-28 01:07:22 | 显示全部楼层
ambitious 发表于 2024-2-27 17:56
有比较的15765的协议栈吗

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

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-4-1 09:57:14 | 显示全部楼层
移植明白了,但还是有点不会用,我想向指定的地址发送单帧和多帧的消息
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106274
QQ
 楼主| 发表于 2024-4-2 08:08:08 | 显示全部楼层
vuxtvg 发表于 2024-4-1 09:57
移植明白了,但还是有点不会用,我想向指定的地址发送单帧和多帧的消息

直接调用API操作就行。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-15 02:34 , Processed in 0.283773 second(s), 34 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表