UDS协议(车辆控制单元诊断系统开发架构及DID读取数据流程)

本文探讨了汽车控制单元诊断系统的开发,包括控制端与诊断仪端的软件架构,涉及KWP2000, UDS, J1939等通讯协议。深入分析了UDS协议的网络层、应用层及数据链路层,讨论了诊断数据与策略管理的模块化设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近由于工作的缘故,需要对控制单元的诊断系统进行开发,故利用业余时间查阅相关论文及标准协议,以此能够对控制端以及诊断仪端的软件开发能够有整体的概念,以及评估开发所需要做的工作。 特利用周末时间对自己的学习进行总结,供大家相互探讨。

诊断系统,顾名思义对控制系统的传感器与执行器进行故障的诊断,以便维修人员能够准确的解决故障。目前随着车辆控制单元的增加,诊断系统越加复杂,但其根本的设计架构及遵循的协议几乎完全一致,也就是说无论是TCU,ECU,BMS,HCU,还是EPS,ABS,MCU,Display,软件中的诊断协议几乎一致,诊断仪的功能仅仅是数量的增加,功能上大致一致。

目前诊断系统的通讯协议多种多样 ,含有 KWP2000,UDS,J1939,OBD 等等,KWP2000 与UDS是欧洲人主导,KWP2000 有基于CAN的,也有基于K线的,UDS在设计之初就是基于CAN线。目前UDS是各个厂家应用的趋势。J1939,OBD的一些协议是美国人主导的。J1939即可以通讯,也有关于诊断的相关协议,OBD主要应用在国五以上,与排放相关,国四虽说有标注,但不强制使用。下面的几张抠图,显示这些协议的构成。

 

相关的诊断协议大多都定义 物理层,数据链路层,网络层,应用层。其它几层暂时没有相关定义。

以下文章 以UDS开发为例,将从开发的角度陈述几个开发问题,供大家学习,包含开发架构,模块分析,代码结构进行阐述。

诊断系统的开发架构

诊断系统包含控制端的软件与诊断仪端的软件,这两者的软件架构基本一致。如下图所示。

因此只要明白一端的软件架构即可,下面以控制端的软件为例子进行描述。

模块分析--- 诊断数据,策略管理层

诊断数据与策略管理层是独立于标准协议之外,根据不同的控制单元,策略及数据管理不尽相同,但归根到底就两个功能 数据的读取与写入,读取包含,系统运行变量的读取,故障代码读取,写入包含,清除故障代码命令写入,相关标定变量写入,数据刷写写入。相关命令写入。相关诊断功能的实现是隶属于应用层软件的开发,在此不做描述。本文以读取控制系统中某个变量为例进行细节描述,如下图所示:

模块分析--- UDS 协议应用层

UDS 的协议应用层为定义各个诊断命令的含义与指令,建立A-PDU,进行命令的解析。具体设计可以参考标准的ISO14229协议。

模块分析 --- UDS 网络层

UDS 的网络层为核心,可以理解为信息交互的路由器,或者火车的编组站,对各个信息进行编组。一组为一个数据单元,一个数据单元为8个byte,命名为N-PDU

N-PDU=N_AI+N_PCI+N_DATA.

在对数据编组的过程中,分为单帧与连续帧。传输方式如下图所示:

 

N-AI 包含的为地址信息与寻址信息。

N-PCI 为在传输数据的时候的控制信息,详细如下图所示。

N-Data 为传输的数据。具体为数据域后面的7个数据域。

模块分析 ---- 数据链路层与物理层。

数据链路层的各个功能基本都有具体的CAN传输芯片完成,而物理层表述的为传输过程中的线束及传输信号要求。代码结构分析

在进行软件设计的过程中,数据链路层与物理层描述的为硬件描述层隶属于硬件范围,网络层为服务描述层处于RTE下方与BSW上方,而诊断数据库与诊断策略都包含在ASW层。网络层,数据链路层,物理层在Autosar都含有标准模块,均可以找到标准进行更改应用,诊断策略及诊断数据库包需要根据具体的应用进行设计。

### Autosar DID 数据读取方法及示例代码 在 AutoSAR 架构中,DID(Data Identifier)是一种用于访问特定车辆数据的服务。以下是关于如何实现 DID 数据读取的方法及其示例代码。 #### 配置 Dcm 模块支持 DID 功能 为了使 ECU 支持 DID 的读取操作,需完成以下配置: 1. **定义 DID 标识符** 在 `DcmDsp` 配置部分,通过 `DcmDspDidIdentifier` 定义具体的 DID 编号以及其关联的数据结构[^4]。例如: ```xml <DcmDspDid> <SHORT-NAME>DID_EngineSpeed</SHORT-NAME> <DcmDspDidIdentifier>0x010C</DcmDspDidIdentifier> <!-- 关联信号 --> <DcmDspDidSignalRefs> <DcmDspDidSignalRef>DID_Signal_EngineSpeed</DcmDspDidSignalRef> </DcmDspDidSignalRefs> </DcmDspDid> ``` 2. **映射信号到实际变量** 使用 `DcmRbAtomicSenderReceiverCommunication` 将 DID 映射至具体的应用层信号或变量。这一步确保了底层通信与应用逻辑之间的绑定关系。 3. **提供回调函数处理复杂需求** 如果某些 DID 需要特殊处理,则可通过设置条件检查函数 (`DcmDspDataConditionCheckReadFnc`) 或自定义读写接口来满足业务需求[^4]。 #### 示例代码:启动并执行 DID 读取流程 下面展示了一个简单的 C 函数调用序列,模拟从外部请求触发直到最终返回所需数据的过程。 ```c #include "Dcm.h" #include "Rte_DcmSwc.h" // 假设这是由诊断工具发起的一个标准 UDS 请求 (Service ID: 0x22) void HandleUDSServiceRequest(uint8 serviceId, uint8* didBuffer, uint8 bufferSize) { Std_ReturnType result; if (serviceId == SID_READ_DATA_BY_IDENTIFIER && bufferSize >= 2) { uint16 requestedDID = ((uint16)didBuffer[0] << 8) | didBuffer[1]; switch(requestedDID){ case 0x010C: { // 发动机转速 uint16 engineSpeed; // 调用 Rte 接口获取当前 RPM 值 Rte_Read_PortName(&engineSpeed); // 返回给客户端 memcpy(didBuffer, &engineSpeed, sizeof(engineSpeed)); break; } default: // 处理未知 DID result = E_NOT_OK; } } else { // 不支持的服务或者参数错误 result = E_NOT_OK; } // 反馈响应状态 SendDiagnosticResponse(result); } // 主循环或其他上下文中可能存在的入口点 extern void MainLoop(void) { static uint8 rxBuffer[8]; uint8 txBuffer[8]; while(ReceiveFromDiagTool(rxBuffer)) { HandleUDSServiceRequest(rxBuffer[0], &rxBuffer[1], GetRxBufferSize()-1); TransmitToDiagTool(txBuffer, CalculateTxSize()); } } ``` 此代码片段展示了当接收到一个针对特定 DID (如发动机速度)的有效查询时,程序应采取的动作路径,并假设存在某种机制能够实时采集这些动态变化的信息源作为回应依据之一[^1]^。 以上即为基于 AutoSAR 实现基本的 DID 数据读取功能的大致框架说明和技术要点解析。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值