关于RVC - 掌握RVC通讯协议预备新设备接入

Written by CC -- 2024-12-09

The Astro logo on a dark background with a pink glow.

protocol

RV-C

work

RV-C 协议技术文档

RV-C(Recreational Vehicle Communication Protocol)协议是为房车通信网络设计的标准通信协议,基于CAN(Controller Area Network)总线技术,定义了一套适用于各种房车设备的通信机制。以下是该协议的技术文档总结,涵盖其核心组成部分及应用层规范。

1. 协议概述

RV-C协议是一种用于房车内部设备间通信的协议,支持多种设备类型和数据交换。该协议的设计重点是设备之间的互操作性和数据可靠性,采用CAN总线的扩展帧格式来实现数据传输。协议层级包括物理层、数据链路层、网络层、传输层和应用层。RV-C协议规定所有消息必须使用CAN数据帧的扩展帧格式,数据长度为8字节。RV-C协议支持多种房车设备,定义了标准化的数据组和功能接口。当多个设备尝试声明同一地址时,RV-C协议提供了一套仲裁机制以确保地址分配唯一性及优先级分配。

2. 物理层规范

•	电缆类型:建议使用屏蔽双绞线以减少电磁干扰。
•	数据速率:支持标准CAN速率(如250 kbps)。
•	拓扑结构:总线拓扑,终端电阻要求为120欧姆。
•	连接器类型:符合诊断标准的接头,便于设备连接和维护。

3. 数据帧结构

•	优先级位(Priority Bits):用于决定当两个设备同时传输时,哪条消息优先通过总线。
•	数据组号(Data Group Number, DGN):唯一标识数据包类型。
•	源地址(Source Address, SA):标识数据包的发送节点,必须唯一。

4. 网络层与传输层

•	地址分配:每个设备需要唯一的源地址,可以通过静态分配或动态地址声明实现。
•	数据分组:通过17位的数据组号(DGN)标识参数组和设备类型。
•	多包消息支持:允许分片发送大于8字节的数据,支持多个包的组装与解析。
•	错误处理:协议支持基本的错误检测和消息确认机制。

5. 应用层功能

•	信息共享:设备定期广播其状态数据(如电池电量、空调状态)。
•	控制消息:用于发送控制命令(如启动发电机、调整温控设备)。
•	诊断消息:用于设备故障检测与状态查询。
•	设备标识:通过产品标识消息,提供设备的制造商和型号信息。

6. RV-C设备类型

•	电源设备:如逆变器、电池管理系统(BMS)。
•	传感器:如气体传感器、水箱液位传感器。
•	环境控制:如空调、暖气控制器。
•	导航与位置服务:如GPS模块。
•	安全系统:如门窗锁定状态传感器。

7. 数据类型与编码

•	RV-C协议采用小端序(Little-Endian)编码方式。
•	数据类型包括布尔值、整数、浮点数和字符串。
•	所有未使用的位或字段应填充为默认值0xFF,以避免解析错误。

8. 地址声明与冲突处理

1.	设备广播其地址声明消息。
2.	如果检测到冲突,设备根据优先级字段重新声明地址。
3.	地址声明过程确保每个设备获得唯一地址。

9. RV-C与SAE J1939兼容性

RV-C协议在某些方面与SAE J1939协议保持兼容,例如数据帧结构和优先级处理机制。这使得RV-C设备可以与基于J1939协议的系统共存,但也引入了部分协议间的差异,需要在设备实现时加以注意。

10. 常见数据组定义(DGN)

以下是一些常见的数据组及其用途:

•	GENERAL_RESET (17F00h):通用重置消息,用于设备复位或清除故障。
•	LEVELING_CONTROL_COMMAND (1FFEEh):用于控制房车水平调节系统。
•	GPS_POSITION (0xFEF3):提供GPS位置信息,包括纬度、经度和海拔。

11. 协议优势

•	实时性强:基于CAN总线的设计,使RV-C协议具有低延迟和高可靠性。
•	标准化接口:定义了丰富的设备类型和数据组,便于集成与扩展。
•	可扩展性:支持多包消息和动态地址声明,适应多种应用场景。

12. 部署与应用建议

•	在设备开发时,确保实现协议的全部强制性消息。
•	定期广播设备的状态消息(如DMRV),以确保网络内设备能够正确互操作。
•	在多设备系统中,合理规划地址分配和消息优先级,以避免冲突和延迟。

实战总结

1. 数据帧监听

RV-C是基于CAN总线通信,数据在网络上传输时以帧的形式发送(通信速率范围为125kbps~1Mbps)。一个CAN数据帧包含以下主要字段:

|字段|长度(位)|描述|
|Start of Frame (SOF)|1|帧开始标志,用于标识一帧的起始位置|
|Arbitration ID|29|扩展 ID,用于定义消息优先级、数据类型(PGN/DGN)和源地址(SA)|
|Control Field|6|包含数据长度代码(DLC)和保留位|
|Data Field|0-64 位|数据负载,最多 8 字节(64 位)。|
|CRC Field|15|循环冗余校验,用于检测数据传输中的错误|
|CRC Delimiter|1|CRC结束标志位,固定逻辑为1|
|ACK Field|2|确认字段,用于接收节点确认是否成功接收到消息|
|End of Frame (EOF)|7|帧结束标志,用于标识帧的结束位置|

标准的扩展帧格式(29位CAN ID)中,Arbitration ID按以下原则分配: | Priority (3 bits) | PGN/DGN (18 bits) | Source Address (8 bits) | 示例数据帧:

|SOF | Arbitration ID | Control Field | Data Field        | CRC | ACK | EOF|
--- | -------------- | ------------- | ----------------- | --- | --- | ---|
|0   | 0x18F00420     | 8 (DLC=8)     | 0x1C00000000000000| ... | ... | ...|

二进制为 0001 1000 1111 0000 0000 0100 0010 0000 数据帧各部分解析:

• SOF :长度1位,通常是固定的0,标志着帧的起始位置 ;
• Arbitration ID :长度29位(扩展帧、标准帧只有11位);
	• Priority :长度为3位,0b110代表优先级为6;
	• Reserved Bit : 长度为1位,保留位固定为0;
	• Data Page :长度为1位,0表示标准PGN页面;
	• Data Group Number :长度为18位,0xF004代表发动机转速;
	• Source Address :长度为8位,0x20代表来源设备地址为0x20,可能代表发动机控制器;
• Control Field :DLC=8,长度为6位+2位保留位,本帧中8代表接下来的数据段长度为8字节;
• Data Field : 0x1C00000000000000,CAN中使用小端模式,所以1C00代表7168,转速单位通常为1/8 RPM,因些数据解析最终结果为 7168 / 8 = 896 RPM;
• CRC :由协议生成多项式计算得出,长度15位(检验码)+1位(固定分隔符1);
• ACK :长度为2位,表示接收设备是否成功接收消息。如果所有设备都成功接收该帧,则会发送ACK信号;
• EOF :长度为7位,固定为逻辑1111111,标志帧的结束;

示例代码:

	import can
	# 初始化 CAN 总线
	bus = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=250000)

	def parse_arbitration_id(arbitration_id):
		"""
		解析 CAN Arbitration ID
		:param arbitration_id: 29 位的 Arbitration ID
		:return: 解析后的优先级、PGN/DGN 和 SA
		"""
		# 提取优先级(高 3 位)
		priority = (arbitration_id >> 26) & 0x07
		
		# 提取 PGN/DGN(中间 18 位)
		pgn = (arbitration_id >> 8) & 0x3FFFF
		
		# 提取 Source Address(低 8 位)
		source_address = arbitration_id & 0xFF
		
		return priority, pgn, source_address

	def process_message(msg):
		"""
		处理接收到的 CAN 消息
		:param msg: CAN 消息
		"""
		arbitration_id = msg.arbitration_id
		data = msg.data
		
		# 解析 Arbitration ID
		priority, pgn, source_address = parse_arbitration_id(arbitration_id)
		
		print(f"Received CAN Message:")
		print(f"  Arbitration ID: {hex(arbitration_id)}")
		print(f"  Priority: {priority}")
		print(f"  PGN/DGN: {hex(pgn)}")
		print(f"  Source Address: {hex(source_address)}")
		print(f"  Data: {data.hex()}")
		
		# 示例:处理特定 PGN 的消息
		if pgn == 0xF004:  # 假设 PGN 0xF004 表示发动机转速
			engine_speed = int.from_bytes(data[:2], byteorder='little') / 8.0  # 假设数据前 2 字节为转速
			print(f"  Engine Speed: {engine_speed} RPM")

	# 监听 CAN 消息
	print("Listening for CAN messages...")
	while True:
		msg = bus.recv()
		if msg is not None:
			process_message(msg)

2.知识扩展

• 小端模式:数据存储按内存低地址存储数据低字节方式开始存储
• 大端模式:数据存储按内存低地址存储数据高字节方式开始存储

例如,一个 16 位的整数 0x1234,在小端模式下的存储顺序为:

	|地址|数据|
	|0x00|0x34|(低字节)
	|0x01|0x12|(高字节)

大端模式则刚好相反:

	|地址|数据|
	|0x00|0x12|(高字节)
	|0x01|0x34|(低字节)

通过资料查找及学习,掌握RV-C通讯协议