简介:德国工业标准DIN 70121中英版本文档是一份面向电动汽车充电领域从业者的标准参考资料,由德国标准化研究所于2014年12月发布,共212页。该标准规定了电动汽车与直流充电站之间的数字通信协议,用于调节组合充电系统(CCS)中的直流充电,内容涵盖数据交换格式、充电状态传输、认证授权机制、错误处理以及诊断维护等关键环节,适合充电桩开发、整车通信测试、标准合规研究等场景。资源包内含1个docx文件,整体大小6.96MB,以中英对照形式呈现标准原文,便于读者在阅读英文条款时快速对照中文理解。已有2347人学习下载。对于需要开展DIN 70121协议适配或直流充电互操作验证的工程师,该标准能提供完整的协议框架和条款细节,帮助减少查阅原版标准的时间成本。
1. 一次充电失败让我盯上 DIN70121:这个协议名到底值不值得较真
一台刚做完出厂测试的直流桩,和某款欧洲车型握手,前三次都正常,第四次开始报“车辆超时无响应”,桩侧日志没有任何应用层报文,物理链路又是通的。排查了两天,最后定位到是 SLAC 阶段的车端探测报文在桩侧被当成了噪声丢弃。真正让我重新翻标准原文的,是这个结论背后牵出的整个协议栈:DIN70121 定义的不只是一套报文格式,它是车与桩之间从物理层到应用层的完整通信约定,名字里的 70121 指向的是“车辆与充电站之间用于电动汽车充电的数字通信”。
很多人被这串编号劝退,以为它只跟欧洲认证相关。实际上它定义了充电过程中谁先说话、每一句怎么编码、TLS 要不要、超时算谁的锅。对做桩端协议栈、做车端充电机、做测试平台的人来说,这套协议是绕不开的入口。中英版本的问题恰好又在这里暴露得最明显:翻译稿里“应”和“可”差一个字,代码里可能就是报错和静默的差别。这篇笔记就围绕这套协议的中英文对照,把它是什么、怎么实现、哪里容易翻车一次讲清。
2. 先分清关系:DIN70121 与 ISO15118、GB/T 27930 的边界和选型理由
2.1 DIN70121 在充电协议家族里的位置
DIN 是德国标准化学会的缩写,70121 这个编号在充电领域特指直流充电场景下车辆与充电桩之间的数字通信协议。它最早是为解决一个很具体的痛点:此前直流充电靠模拟电平(CP/PP 信号)传递有限信息,车型和桩之间无法交换电池参数、不能动态调节电流,也无法判断线缆连接是否可靠。数字通信引入后,车和桩可以在充电前完成参数协商,在充电中实时请求电流变化,在充电结束前做焊接检测。
产业界常说的“欧标直流充电”早期指的就是 DIN70121,后来由 ISO15118 接管并扩展成同时覆盖交流与直流的完整体系,但 DIN70121 仍以“直流充电数字通信的先行者”身份存在于大量存量桩和测试规范里。从内容上看,DIN70121 与 ISO15118-2 的直流部分高度重合——我看过的几个版本中,许多消息结构、状态机流转、EXI 编码规则都能对应上,但又不完全相等,差异往往集中在少数几个字段和错误码定义上。
2.2 与 GB/T 27930、ISO15118 的对比
国内从业者最熟的是 GB/T 27930,它走 CAN 总线,用 BMS 与充电机一问一答的方式协商充电参数。DIN70121 则走以太网物理层,承载 TCP/IP,用 EXI 压缩后的 XML 文档交换信息。两者不是简单换个编码的问题,而是整条链路从物理层到应用层都不同。
| 对比项 | DIN70121 / ISO15118 | GB/T 27930 |
|---|---|---|
| 物理层 | 以太网(HomePlug Green PHY) | CAN 总线 |
| 传输层 | TCP/IP,固定端口 | 自定义帧,无 TCP/IP |
| 应用层编码 | EXI 编码的 XML 文档 | 结构化 CAN 报文 |
| 充电前协商 | 含线缆检测、预充、参数协商 | 以 BMS 请求为主 |
| 动态调流 | 充电中可多次请求调整 | 以阶段式电流为主 |
选型上没有对错,只有场景。如果你在做的是一款面向欧盟市场的直流桩或车端充电控制器,DIN70121 或其后续 ISO15118 是认证绕不开的;如果你只做国标市场,那么 GB/T 27930 才是主线。很多团队做出口桩时,会同时保留两套协议栈,用配置文件切换“国标模式”和“欧标模式”,这在实际项目里很常见。
2.3 为什么中英版本对照是踩坑重灾区
DIN70121 的官方文本是德语和英语混排的,标准原文以德语为准,英语版是同等效力的配套文本。市面上能见到的中文版本,来源多是组织或个人的翻译稿,不是标准机构发布的官方中文版。这一点直接决定了它的使用方式:中文版适合用来快速理解流程和状态机,但涉及具体字段取值、条件语义、错误码时,必须以英文版为准。
我做协议测试时吃过一次亏:中文翻译稿里把“shall”统一译成“应该”,而标准语境里“should”表示建议、“shall”表示强制要求。开发按中文版实现,把强制要求当成了可选建议,充电中少发了一个状态更新报文。桩端等不到报文,按超时处理终止了充电。那之后我定了一条规矩:中文版只进人不进代码,所有字段定义和条件分支必须以英文原版核对。后面章节会详细展开这类差异的具体表现。
3. 把协议栈拆开看:从 TCP 端口到 V2GTP 再到 EXI 编码的最小链路
3.1 一条充电消息从车端发到桩端经历什么
DIN70121 的通信模型并不复杂,但每一层都有自己独立的规范。我习惯按这样的顺序去理解:应用层构造一份语义文档,这份文档被 EXI 压缩编码,打包进 V2GTP 报文头,再交给 TCP 传输,TCP 下面是可选的 TLS 加密层,最后落到以太网帧上。调试时最容易出问题的恰恰不是最上层的业务逻辑,而是 EXI 编解码和 V2GTP 报文头这两个容易被忽略的环节。
V2GTP 报文头一般 8 个字节左右,包含协议版本号、报文类型标识和 payload 长度。报文类型里要区分“用 TLS 保护”和“不使用 TLS”,这个标志位错了,接收方会直接丢弃,连业务解析都到不了。抓包时如果看到 TCP 连接是通的、对端也回了 ACK,但应用层没有任何响应,第一件事就是检查 V2GTP 头部的类型字段和长度字段。
3.2 用抓包工具验证 V2GTP 层的最小命令
在桩端网口抓包,过滤条件我一般直接写端口号加 SLAC 的特定 MAC 地址。SLAC 是信道探测阶段使用的机制,车和桩在一个相对短的时间内完成信号衰减测定,之后锁定通信对。抓包时最常见的现象是:SLAC 过程中车不断发探测帧,桩没有回应,导致后续 TCP 会话根本起不来。
# 抓 V2GTP 通信端口的数据包,保留完整 payload tcpdump -i eth0 -w v2g.pcap port 8404 # 同时抓 SLAC 探测帧(基于 HomePlug 的特定目的 MAC) tcpdump -i eth0 -e -nn ether dst 00:de:70:00:00:01 # 从抓包文件里只看 TCP 端口为 8404 的会话 tshark -r v2g.pcap -Y "tcp.port == 8404"第一段命令把应用层通信保存下来,第二段抓 SLAC 阶段的 L2 帧。这两类流量不在同一个筛选条件下,分开抓更容易定位问题层级。第三段命令是用 tshark 从保存的文件里过滤 V2GTP 会话,避免现场反复抓包。实际联调时我一般同时开两个终端跑前两条命令,SLAC 和 TCP 流量分开存,排查时各看各的。
3.3 EXI 编码为什么让很多人翻车
EXI 是 W3C 推的高压缩率 XML 编码方式,DIN70121 选择它是因为充电报文要从原生的 XML 文本压到很小,以适应电力线通信的窄带宽。问题在于 EXI 编码不是简单的压缩算法,它需要基于一份 Schema 生成编码规则,发送方和接收方必须使用同一套 schema 上下文,否则解码结果完全错乱。
我见过一个典型的坑:某团队用开源 EXI 库做编解码,库默认的 schema 配置和标准要求的 schema 不完全一致。结果是车端发出的报文在桩端解码后字段错位,桩端按错位后的值去判断电池容量,给出了一个离谱的充电电流请求。当时排查时抓包看到的是可读的 XML 文本,怀疑对象全集中在业务逻辑上,后来对比了双方 schema 文件才发现编解码上下文根本不是同一份。这个教训说明:EXI 相关报错,优先核对双方的 schema 版本和编码选项,而不是急着改业务代码。
4. 把充电流程跑通:握手、SLAC、TLS 与关键参数怎么配
4.1 一次完整充电会话的状态流转
DIN70121 定义的状态流可以简写为:物理连接建立 -> SLAC 信道探测 -> TCP 连接 -> TLS 握手(若启用)-> 应用层 Session 建立 -> 参数协商 -> 充电控制 -> 结束与断开。其中应用层的核心消息序列比较固定,车端发起或者桩端发起取决于具体版本和角色定义,但整体上包含线缆检测、预充、充电参数发现、充电状态上报、电流需求调整、焊接检测等环节。
调试时我习惯把这条链路分成三段来看:第一段是物理和信道层,SLAC 能不能完成;第二段是传输层,TCP 和 TLS 能不能起来;第三段才是应用层,业务报文逻辑对不对。每一段的失败现象都不同:第一段失败表现为抓不到任何 TCP SYN;第二段失败表现为 TCP 通但 TLS 握手报错;第三段失败表现为报文都发出来了,但状态机走不下去。按这个思路分段,能省掉一半排查时间。
4.2 SLAC 阶段的常用参数与观察点
SLAC 本身不是 DIN70121 定义的,它来自 HomePlug Green PHY 规范,但 DIN70121 的应用层会话建立依赖 SLAC 的结果。现场联调时,车端和桩端需要对上 MAC 地址、网络标识符和信号衰减阈值。我在台架上见过的最多问题,就是桩端没开启 SLAC 监听,或者车端固定了某一个网络标识符,而桩端在另一个标识符上侦听。
| 参数 | 常见配置参考 | 排查观察点 |
|---|---|---|
| 网络标识符(NID) | 桩、车保持一致 | 两端配置是否不同 |
| 探测超时 | 30~60 秒量级 | 超时后是否重试 |
| 衰减阈值 | 按现场环境设定 | 阈值过严会选不上 |
| 目的 MAC | 固定为 SLAC 广播地址 | 抓 L2 帧是否匹配 |
这些参数在不同产品上名称略有差异,桩端叫“SLAC 使能”,车端叫“HomePlug 网络配置”。如果出现“桩收不到任何 SLAC 请求”,优先检查桩端网络接口是否被配置成了非 HomePlug 模式,而不是怀疑协议栈。物理层没起来,上层再正确也没用。
4.3 TLS 与 TCP 的配置边界
DIN70121 对 TLS 的要求在不同版本里有差异,有的阶段要求强制 TLS,有的允许协商。实际产品里常见做法是:优先尝试 TLS,失败后降级到无 TLS,并记录一条告警。这种“先加密后降级”的策略在测试场方便联调,但在正式产品里我建议关掉降级路径,避免中间人攻击风险。
调试 TLS 阶段时,桩端需要准备好证书链,车端需要验证服务器证书。常见问题集中在证书有效期、证书链不完整、时间不同步三个方面。桩端设备常年掉电,RTC 时间不准,证书验签直接失败,这种案例我处理过不止一次。自测时可以用下面的命令快速验证桩端证书链是否完整:
# 查看桩端证书链(假设端口 8404 上启用了 TLS) openssl s_client -connect 192.168.1.100:8404 -showcerts # 单独验证桩端证书是否过期 openssl x509 -in evse.pem -noout -dates第一段命令会打印出服务器发送的整条证书链,重点看返回的证书数量和顺序,正常情况下应该是叶子证书在前、根证书在后。第二段命令用于检查设备内置证书的有效期,排除时间不同步以外的硬件问题。如果证书链不完整,openssl 会明确报错;如果时间不同步,报错往往指向“证书尚未生效”或“证书已过期”,这时候去改设备时间就能解决,而不是重新签发证书。
5. 中英版本对照使用的避坑记录:翻译偏差背后的实施差异
5.1 术语对照:同一字段多种译法
中英版本最直接的问题是术语不统一。同一个概念在中文版里可能被译成多个词,读起来是中文,对应回代码却找不到唯一字段。我整理过一份内部对照表,下面的例子是项目里真正用到过的:
| 英文原文 | 常见中文译法 | 对应代码字段 |
|---|---|---|
| CableCheck | 线缆检查 / 电缆检测 / 线缆校验 | CableCheck 消息类型 |
| PreCharge | 预充 / 预充电 | PreCharge 状态 |
| CurrentDemand | 电流需求 / 电流请求 | CurrentDemand 消息 |
| WeldingDetection | 焊接检测 / 粘连检测 | WeldingDetection 消息 |
| EVSE | 充电设施 / 供电设备 / 充电桩 | EVSE 角色标识 |
这个表不是标准给出的,是我从多个中文版资料里汇总出来的。你会发现中文版读起来并不难懂,难的是团队内部统一口径。同一套代码里,有人把线缆检查写成 cable_check,有人写成 cableCheck,还有人直接叫 cable_test,代码评审时看着都是对的,对接第三方测试平台时就乱了。建议团队里固守一份术语表,所有消息名、状态名、字段名都从英文原版直接搬运,中文只做注释,不进代码标识符。
5.2 五条血泪排查记录
第一,现象:中文版描述“当检测到断开时,应停止充电”,程序按“收到 WeldingDetection 后立即停止输出”实现,结果在充电过程中偶发误停。原因:英文原版对“断开检测”有条件限定,需同时满足电流和电压阈值,中文版简化成了单一事件。解决:回到原版,把条件分支完整实现,并加一组合位测试用例覆盖阈值边界。
第二,现象:车端发送的 ChargeParameterDiscovery 响应,桩端报 schema 校验失败。原因:中文版附录给出的 XML 示例缺了命名空间前缀,开发按示例写的报文,命名空间解析失败。解决:schema 校验失败时,先比对报文的命名空间声明和字段顺序,不要只看字段内容。XML 在 EXI 编码后命名空间错误会被静默放大,表现成整包不可解。
第三,现象:桩端联调时一直等不到车端的 SessionStop,最后按超时断开,车端那边却说已经正常发过了。原因:中英版本对“会话结束”的触发条件描述不一致,车端实现的是“收到停止充电指令后发 SessionStop”,桩端预期的是“充电电流降到零后等 SessionStop”。解决:以英文原版状态机为依据,明确 SessionStop 的触发点在哪个消息之后,并和对方以报文时序图对齐。
第四,现象:TLS 握手阶段车端报证书链不完整,桩端工程师坚持说证书没问题。原因:桩端配置文件里写的是证书文件的相对路径,服务进程工作目录不同,根证书没加载进来。这个和标准版本无关,但排查时最容易在中英文资料的 TLS 章节里绕圈子。解决:先看桩端日志里证书文件路径是否真实存在、进程是否有权限读取,再谈协议问题。
第五,现象:中文版对错误码解释过于简短,比如“EVSE 内部错误”,导致现场人员反复重启设备。原因:英文原版错误码对应的是内部子状态码,中文版没有翻译子码表,只保留了顶层描述。解决:给现场人员配英文原版错误码表,所有错误上报按“顶层码 + 子码”格式打印,避免只看一句话描述。
5.3 中英版本的使用策略:原版为准,中文为辅
我不建议团队买一堆中文版打印出来供开发翻阅,但也不建议完全丢掉中文版。合理的做法是:流程级理解,用中文版快速过一遍,建立整体印象;字段级实现,必须对照英文原版逐句核对;测试用例设计,按英文原版的动词级别提取测试项。标准原文里的“应”和“建议”对应完全不同的测试等级,前者必须验证,后者可做可不做。
版本管理上还要注意编号差异。DIN70121 存在带“-1”后缀的版本,完整标题指向的是同一个通信协议族,但不同年份版次的内容和 ISO15118 的引用关系有变化。对接第三方测试平台前,先确认双方参照的是同一版次,否则会出现“字都对得上,细节对不上”的情况。这种问题在联调前发现成本最低,到现场了就只能互相扯皮。
6. 验证与进阶:用抓包、日志和状态机三件套把协议问题钉死
协议栈调试到最后,真正管用的不是某种高深工具,而是把三方证据对齐:抓包文件、桩端日志、车端日志。同一个时间点,三方各说各话,对齐时间戳后才知道是哪一方先断了链路。
# 从抓包文件提取整个会话的所有消息类型和状态码 tshark -r v2g.pcap -Y "v2gtp" -T fields -e v2gtp.messageType # 按时间顺序输出消息号,快速还原状态流是否完整 tshark -r v2g.pcap -Y "tcp.port == 8404" -T fields -e frame.time_epoch -e v2gtp.messageType第一段命令把应用层消息类型全部列出来,一眼就能看到状态流是否按预期走完。第二段命令带了时间戳,用于对比车桩两侧日志,确认哪一步开始出现时间差。遇到“双方都说自己发了”的情况,用这两条命令把消息序列和桩端日志逐条对齐,通常十分钟内能找到真凶。
再进阶一点的是做回归脚本。我习惯把标准里的主干流程写成一套场景编号,每次协议栈改动后,跑一遍全场景,生成一份消息序列摘要,人工比对差异。为此抓包时优先保存 pcap 文件,不要只看实时窗口,事后分析的价值远大于实时观察。这段逻辑相当牢固。
最后说一个习惯:改协议栈代码前,先确认问题在哪一层。物理层问题改应用层代码是白费力气,类似用错 EXI schema 这类问题,真正可复现的定位路径永远是先看抓包,再对日志,最后才动代码。这套流程帮我省下了大量“看着像协议问题,实际是配置问题”的时间,也希望帮到你。
本文还有配套的精品资源,点击获取