OBD_集成手册¶
目标¶
本集成手册用于指导客户进行OBD诊断栈集成,文档主要包括的内容为:OBD诊断栈集成指导、基于特定应用的集成示例讲解。
由于各项目的需求不同,集成示例不会针对于特定的项目做详细讲解。
缩写词和术语¶
缩写词/术语 |
描述 |
MCAL |
Microcontroller Abstraction Layer微控制器抽象层 |
CanIf |
CAN Interface module CAN接口 |
ComM |
Communication Manager module 通信管理 |
PduR |
PDU Router module PDU路由 |
Dcm |
Diagnostic Communication Manager 诊断通信管理 |
Dem |
Diagnostic Event Manager 诊断事件管理 |
CanTp |
CAN Transport Layer CAN传输层 |
参考文档¶
[1] UDSonCAN
[2] 参考手册_Dem.pdf
[3] 参考手册_DCM.pdf
[4] 参考手册_DCM.pdf
协议栈集成¶
项目交付的内容为:协议栈源码和ORIENTAIS Configurator配置工具。协议栈细分为协议栈的各模块及其对应的配置工具模块。
OBD诊断栈各配置模块的功能介绍,参见表 4‑1诊断栈各配置模块介绍。
使用协议栈源码和配置工具,进行协议栈的集成的步骤,参见表 4‑2 协议栈集成的步骤。
模块名 |
功能 |
Can |
CAN驱动配置。(由MCAL具导入) |
CanIf |
CanIf 模块主要处理上层模块与底层驱动的之间PDU 的传递,为上层模块提供统一的接口来管理不同的CAN 硬件模块 |
EcuC |
用于辅助配置工具完成配置的模块。主 要提供Pdu的定义,其它模块通过关联EcuC中Pdu,相互关联起来。 |
PduR |
PDU Router主要为相关模块提供基于I-PDU 的路由服务。在诊断栈中,主要是提供CANTP与DCM之间的路由服务 |
CanTp |
CANTP 模块实现依据ISO15765-2 标准规范中定义的CAN 总线数据在传输层的数据接收发送功能 |
DCM |
依据IS O15765-3和ISO15031-5标准描述,实现诊断请求报文的解析,响应 (正响应和负响应)与执行。主要功能有:实现UDS、OBD诊断服务。 |
DEM |
实现诊断故障的存储与管理功能,提供API 接口供其他模块读取 DTC 和对应的冻结帧数据和扩展数据 |
步骤 |
操作 |
说明 |
1 |
ORIENTAIS Configurator配置工具 工程搭建和协议栈模块加载 |
若配置工具已经搭建 ,则仅需进行协议栈模块的加载操作。 |
2 |
模块配置及配置文件生成 |
NA |
3 |
代码集成 |
现有工程、 协议栈源代码和配置生成文件的集成。 |
4 |
验证测试 |
NA |
注意:协议栈集成之前,用户须确保已经有基础工程,且本协议栈相关的其他协议栈能正常工作。
新建ORIENTAIS Configurator配置工程及模块加载¶
安装ORIENTAIS Configurator软件后,双击软件图标打开软件。

图 4‑1 新建工程
菜单栏File🡪New🡪Project,新建工程。

图 4‑2 新建工程
在弹出的新建窗口中选择Autosar下的 [BSW Project],选择Next。

图 4‑3 新建工程
在弹出的窗口中输入工程名,选择Finish。

图 4‑4 新建工程
选择[Bsw_Builder],右键单击,选择New ECU Configuration。

图 4‑5 新建工程
在弹出的窗口中输入ECU名,然后选择Next。

图 4‑6 选择芯片平台
在弹出的窗口中勾选需添加的模块,点击Finish。

图 4‑7 选择模块
新建工程如下所示,步骤0中添加的模块已经被加入到工程中。

图 4‑8 工程结构示例
模块配置及生产代码¶
模块配置¶
模块的具体配置,取决于具体的项目需求。OBD诊断栈各模块配置项的详细介绍,参见表 4‑3协议栈各模块配置参考文档。
模块 |
参考文档及其章节 |
Can |
MCAL对应的Can配置手册 |
CanIf |
参考手册_CanTp.pdf |
PduR |
参考手册_PduR.pdf |
NvM |
参考手册_NvM.pdf |
CanTp |
参考手册_CanTp.pdf |
Dcm |
参考手册_Dcm.pdf |
Dem |
参考手册_Dem.pdf |
配置代码生成¶
在ORIENTAIS Configurator主界面左方,选择对应的协议栈,单击右键弹出Validate All和Generate All菜单。

图 4‑9 生成配置
选择Validate All对本协议栈各配置选项进行校验,没有错误提示信息即校验通过。若有错误信息,请按照错误提示修改。
选择Generate All,生成配置文件。右下角的Console窗口输出生成的配置文件信息。

图 4‑10 生成配置结果
将ORIENTAIS Configurator切换到Resource模式,即可查看生成的配置文件。

图 4‑11 生成配置工程结构
功能集成¶
代码集成¶
诊断栈代码包括两部分:项目提供的诊断栈源码和ORIENTAIS Configurator配置生成代码。诊断栈集成包括诊断栈源码(CANIF,CANSM,PDUR,CANTP,COMM,DCM,DEM等)、定时器源码和部分其他模块源码。
用户须将诊断栈源码和4.2.2章节生成的源代码添加到集成开发工具的对应文件夹。
注意:诊断栈集成之前,用户须确保已经有通信基础工程,且本诊断栈相关的其他功能栈能正常工作。
集成注意事项¶
对于集成过程中,协议栈特殊要求和用户经常出现的问题,归类总结形成表 4‑4协议栈协议栈集成约束清单。用户需逐一排查表中的约束项,以避免集成问题出现。
编号 |
类别 |
约束限制 |
1 |
堆栈 |
用户需确保为任务堆栈和中断堆栈分配足够的堆栈空间。 |
2 |
头文件 |
添加协议 栈代码之后,用户需更新集成开发工具中的头文件路径。 调用协议栈API的源文件,需要包含协议栈的头文件。 |
3 |
初始化 |
OBD诊断栈的初始化顺序为:Dem_PreInit,CanTp_Init, Dcm_Init,Dem_Init。 |
4 |
周 期函数 |
CanTp_MainFunction,Dcm_MainF unction和Dem_MainFunction需要被周期性任务函数调用。 |
集成示例¶
本章节通过OBD诊断栈为例,向用户展示OBD诊断栈的集成过程。用户可以据此熟悉OBD诊断栈配置工具的配置过程,以及如何应用配置工具生成的配置文件。示例是基于具有正常工作的CAN通信工程之上。
本章节先完成基本OBD配置,使得工程可以编译通过,并实现基础OBD诊断通讯,然后根据具体需求服务进行添加或修改。
注意:本示例不代表用户的实际配置情况,用户需要根据自己的实际需求,决定各个参数的配置。
集成目标¶
通过搭建基础工程,实现OBD诊断基本请求应答功能。使用标准帧CAN0x7df作为请求,标准帧0x7E8作为响应,同时实现OBD服务01,02,03,07,09的功能。示例网络层时间参数如表 5‑1 网络层定时参数(仅 OBD 排放相关诊断要求)
定时参数 |
描述 |
超时时间(ms) |
性能要求时间(ms) |
N_As |
发送方 CAN 报文确认超时 |
25 |
|
N_Ar |
接收方 CAN 报文确认超时 |
25 |
|
N_Bs |
流控帧传输超时 |
75 |
|
N_Br |
流控帧接收端发送等待时间 |
<10 |
|
N_Cs |
连续帧发送时间间隔 |
ST*min |
|
N_Cr |
连续帧传输超时 |
150 ms |
模块的配置¶
新建配置工程及模块加载操作,请参考本文档4.1章节。生成代码过程请参考章节4.2。
Can模块与CanIf模块配置¶
在CAN模块与CANIF模块中实现用于OBD通信的CAN报文,具体配置方法请参考文档《CAN通信栈》。
报文ID |
发送/接收 |
报文长度 |
0x7df |
接收 |
8字节 |
0x7E0 |
接收 |
8字节 |
0x7E8 |
发送 |
8字节 |
EcuC模块配置¶
双击EcuC模块,打开EcuC模块配置界面。

图 5‑1 ECUC配置界面
在EcucConfigSets栏目上右键,选择EcucConfigSet。再在EcucConfigSet上右键,选择New🡪EcucPduCollection。

图 5‑2 新建EcucPduCollection
·PduIdTypeEnum 选择UINT16(这个参数是定义PDU个数的时用的。)
·PduLengthTypeEnum 选择UINT16(这个参数是定义存储数据长度时使用的变量的长度)
在EcucPduCollection上右键新建Pdu,分别用于CanIf、CanTp、Dcm。

图 5‑3 新建PDU
建议不要使用默认生成的Pdu名字(如:Pdu_0),将Pdu名字改成有意义的名字。这里按照发送和接收,可以将Pdu名字改为报文的名字。

图 5‑4 OBD所需配置的PDU
配置各个PduLength,

图 5‑5 OBDPDU配置:CANIFRX
CANTP,CANIF PDU的length配置为8;Dcm Pdu 长度必须与/Dcm/DcmConfigSet/DcmDsl/DcmDslBuffer 里面配置的Dcm Tx、RxBuffer 长度一致。
ECUC模块到此配置结束。可以在模块上右键,然后选择校验,查看是否配置有错误。校验后提示窗口没有错误信息,即校验通过。
CANTp模块配置¶
CANTp属于通用网络配置,没有针对OBD的特异性配置。
CanTpGeneral配置¶
配置CanTpGeneral
图 5‑6 CanTpGeneral
CANTpConfig配置¶
配置CanTpChannelMode为全双工(根据实际需要选择)。根据需求的通道配置CanTpMaxChannelCnt,如需要一个通道给UDS,一个通道给OBD,则配置为2。

图 5-7 CANTpConfig
配置CanTpChannelMode为全双工(根据实际需要选择)。
图 5‑8 CanTpChannel
配置一个CanTpRxNSdu。根据需求设定各个网络层参数,关联OBD使用的CANTp的RxPDU。
图 5‑9 CanTpRxNSdu配置
配置一个CanTpRxNSdu。根据需求设定各个网络层参数,关联OBD使用的CANTp的RxPDU。
在CanTpRxNSdu下CanTpRxNPdu关联CANIF的PDU。
图 5‑10 CanTpRxNSdu配置
配置一个CanTpTxNSdu。根据需求设定各个网络层参数,关联OBD使用的CANTp的TxPDU。
图 5‑11 CanTpTxNSdu
在CanTpTxNSdu下CanTpRxFcNPdu关联CANIF的RxPDU。
图 5‑12 CanTpTxNSdu
在CanTpTxNSdu下CanTpTxNPdu关联CANIF的TxPDU。
图 5‑13 CanTpTxNSdu
PduR模块配置¶
双击PduR模块,打开PduR模块配置界面。
图 5‑14 PduR
PduRGeneral配置。
若不使用PDUR功能,则勾选PduRZeroCostOperation,一般不勾选,使用PDUR实现CANTP与DCM之间的路由。
PduRBswModuler配置。
PduR模块的目的是实现上层模块到下层模块的路由。PduRBswModuler对象用来描述上层模块和下层模块属性。本示例中上层模块为DCM,下层模块为CANTp。所以需要新建2个PduRBswModuler对象,分别对应DCM和CANTp。
图 5‑15 PduRBswModuler-CanTp
图 5‑16 PduRBswModuler-DCM
添加2个PduRRoutingPath,PduRRouteType配置为TP
PDUR_ROUTING_DiagOBDReq_RX:接收OBD请求
PDU配置CANTP_DiagOBDReq->DCM_DiagOBDReq
PDUR_ROUTING_DiagOBDResp_TX:发送OBD响应
PDU配置DCM_DiagOBDResp ->CANTP_DiagOBDResp

图 5-17 PduRRoutingPath
DCM模块配置¶
双击DCM模块,打开DCM模块配置界面。
图 5‑18 DCMGeneral
DCMGeneral标签页中的参数保持默认即可。
DSD配置¶
新建DcmDsdSidTab,配置DcmDsdSidTabId需与其他服务列表(如UDS)不一同的值
图 5‑19 DcmDsdSidTab
勾选DcmDsdServiceUsed使能服务;
配置需要的OBD服务DcmDsdSidTabServiceId
图 5‑20 DsdService
DSL配置¶
DcmDslBuffer中配置两个buffer分别用于发送和接收,配置Dcm Tx、RxBuffer及其length,需要与EcuC中Dcm对应的Pdu Length的值保持一致。
图 5‑21 DcmDslBuffer
配置OBD的DSLProtocol,实现CANTp与DCM之间的PDU关联。需要修改项如下,若项目无特殊需求,未提到的配置保持默认值即可。
DcmDslProtocolID选择DCM_OBD_ON_CAN;
DcmDslProtocolSIDTable选择DcmDsdServiceTable中的OBD服务表;
DcmDslProtocolRxBufferRef和DcmDslProtocolTxBufferRef关联接收和发送的buffer配置。
图 5‑22 DSLProtocol
在上步的DcmDslProtocolRow_OBD中新建配置DcmDslMainConnection,选择Dcm通信的ComMChannel,并新建1个DcmDslProtocolRx,1个DcmDslProtocolTx。
图 5‑23 DcmDslMainConnection
为每个DcmDslProtocolRx、DcmDslProtocolTx添加Dcm对应的PDU及寻址类型。
图 5‑24 DcmDslProtocolRx
图 5‑25 DcmDslProtocolTx
右键新建DcmDslCallbackDCMRequestService。
图 5‑26 DcmDslCallbackDCMRequestService
DSP配置¶
本小节配置目的是完成基本OBD诊断通讯和编译通过,具体服务的功能请见本章节后续小节具体服务的描述。此小节目的是建立最小系统配置,未提到的配置保持默认即可,服务的配置将在本章节具体服务小节中介绍。
图 5‑27 DSP
添加一个DcmDspPid。选择服务后暂不修改其它内容,内容修改将在5.2.7章节进行。
图 5‑28 DcmDspPid
图 5‑29 DcmDspPidService
DEM模块配置¶
DEMGeneral配置¶
如图 5‑30所示添加配置集。添加Dataelement,GeneralOBD,Indicator
图 5‑30 DEMGeneral
在DemGeneral->DemOBDSupport配置为DEM_OBD_MASTER。同时关联一个的DemIndicator。
DemGeneral->DemTypeOfDTCSupported选择15031-6
DemClearDTCLimitation选择DEM_ALL_SUPPORTED_DTCS
若无明确需求,其它配置可保持默认即可。
图 5‑31 DemGeneral
新建CSDataElement在DemGeneralOBD中关联。
图 5‑32 DemGeneralOBD
DEMConfig配置¶
配置DemDTCAttributes,关联DemMemoryDestinationRef到DemPrimaryMemory。关联DemFreezeFrameRecNumClassRef。其它配置先保持默认配置。
新建DTCAttribute用于OBD的DTC。
图 5-33 DTCAttribute
添加一个DemDTC,设置DemDtcValue,关联DemDTCAttributesRef。
图 5-34 DemDTC
配置DemEventParameter:
a)勾选DemEventAvailable;
b)关联DemOperationCycleRef
c)DemEventKind选择SWC
d)DemDTCRef关联步骤②配置的DTC
e)修改DemEventKind为DEM_EVENT_KIND_SWC
图 5‑35 DemEventParameter
Service 0x01¶
在DcmDsp中添加DcmDspPid,根据需求确定PID。在PidIdentifier填写PID,在DcmDspPidService选择01服务,在DcmDspPidSize中填写其数据长度:
DcmDspPidIdentifier:配置PID
DcmDspPidService:选择使用此PID的服务
DcmDspPidSize:设置数据大小
DcmDspPidUsed:使能此PID

图 5‑36 DcmDspPid
配置DcmDspPidData建立service1的配置

图 5-37 DcmDspPidService
DcmDspPidDataUsePort一般选择USE_DATA_SYNCH_FNC,协议栈会从DcmDspPidDataReadFnc中获取数据,并设置DcmDspPidDataType。

图 5‑38 DcmDspPidDataUsePort
根据DcmDspPidDataReadFnc配置构造获取PID数据的函数。示例如下:
Std_ReturnType Rte_DcmDspPidDataRead_01(
/* PRQA S 3432++ */ /* MISRA Rule 20.7 */
P2VAR(uint8,AUTOMATIC,DCM_VAR)Data
/* PRQA S 3432– */ /* MISRA Rule 20.7 */)
{
Data[0] = 1;
Data[1] = 2;
Data[2] = 3;
Data[3] = 4;
return E_OK;
}
Service 0x02¶
添加DemExternalCSDataElementClass用于获取PID数据

图 5‑39 DemExternalCSDataElementClass
配置DemPidClass中DemPidIdentifier,并关联步骤1中DemExternalCSDataElementClass

图 5-40 DemPidClass

图 5‑41 DemPidClass
DCM新建配置一个用于Service02的DcmDspPidData

图 5‑42 DcmDspPidData
DcmDspPidData关联步骤2中DemPidClass。

图 5‑43 DcmDspPidData
DemDTCAttributes_OBD中不能有其它协议的FreezeFrame。

图 5‑44 DemDTCAttributes
Service 0x03 / 07¶
在DcmDsdServiceTable中添加03和07服务;
(0x0A服务选用)在DemGeneral中添加DemPermanentMemory用于0x0A服务。根据需求将DemGeneral中DemMaxNumberEventEntryPermanent配置为非0值。

图 5‑45 DcmDsdServiceTable

图 5‑46 DemGeneral
添加DemObdDTC并配置DemDtcValue

图 5‑47 DemObdDTC
(0x0A服务选用)DemMemoryDestinationRef选择DemPermanentMemory

图 5‑48 DemDTCAttributes
添加DemDTC_P014300并配置,根据需求选择DemDTCAttributes。

图 5‑49 DemDTC_P014300
添加DemEventParameter,勾选DemEventAvailable;关联DemDTCRef;选择DemOperationCycleRef。

图 5‑50 DemEventParameter
在初始化和开启操作循环后通过DEM函数Dem_SetEventStatus报告故障发生。如下:
void Task_Init(void)
{
EcuM_StartupTwo();
Dem_Init(&DemPbCfg);
Dem_SetOperationCycleState(DemOperationCycle_ID,DEM_CYCLE_STATE_START);
Dem_SetEventStatus(DemEventParameter_P0143, DEM_EVENT_STATUS_FAILED);
}
Service 0x09¶
在DcmDsdServiceTable中添加0x09的OBD服务列表。

图 5‑51 DcmDsdServiceTable
在DSP中添加DcmDspVehInfo,配置DcmDspVehInfoInfoType,此处以INFOTYPE 0x02 (VIN)为例,填写为0x02。

图 5‑52 DcmDspVehInfo
在DcmDspVehInfo中添加DcmDspVehInfoData,配置获取Vehicle information的函数名称 DcmDspVehInfoDataReadFnc,并根据需求配置数据的大小DcmDspVehInfoDataSize为17字节。

图 5‑53 DcmDspVehInfoData
在Rte_Dcm.c中将数据传入 DcmDspVehInfoDataReadFnc配置的函数.

图 5‑54 测试示例程序
源代码集成¶
诊断栈源代码集成步骤如下:
在MCAL工程的基础上,同步5.2.1章添加的Can模块配置文件。
从基线中取出4.3.1章中相关的源代码添加到工程中。
将在4.2.2章中ORIENTAS配置生成的诊断相关配置文件添加到工程中。
添加相关头文件目录。
协议栈调度集成¶
OBD诊断栈调度集成步骤如下:
协议栈调度集成,需要逐一排查并实现表 4‑4协议栈协议栈集成约束清单所罗列的问题,以避免集成出现差错。
集成CanTp_Callout.c 中CanTp_ResetTime、CanTp_GetTimeSpan 函数。

集成Dcm_Callout.c 中Dcm_ResetTime、Dcm_GetTimeSpan 函数。


编译链接代码,将软件烧写进芯片。
OBD诊断栈有关的代码,在下方的main.c文件中给出重点标注。
注意 : 本示例中,OBD诊断栈初始化的代码置于main.c文件,并不代表其他项目同样适用于将其置于main.c文件中。




验证结果¶
验证Service 0x01¶
通过CAN工具向ECU发送01服务请求报文:
CANID:0x7df
请求内容:02 01 00 00 00 00 00 00
期望结果:收到CANID0x7E8报文06 41 00 80 00 00 00 00
通过CAN工具向ECU发送01服务请求报文:
CANID:0x7df
请求内容:02 01 01 00 00 00 00 00
期望结果:收到CANID0x7E8响应,内容与章节5.2.7接口填写的数据内容一致,报文为06 41 01 01 02 03 04 00

图 5‑55 验证结果01
验证Service 0x02¶
通过CAN工具向ECU发送02服务请求报文:
CANID:0x7df
请求内容:03 02 00 00 00 00 00 00
期望结果:收到CANID0x7E8返回报文内容07 42 00 00 00 10 00 00
通过CAN工具向ECU发送02服务请求报文:
CANID:0x7df
请求内容:03 02 0C 00 00 00 00 00
期望结果:收到CANID0x7E8返回报文内容05 42 0C 00 11 22 00 00

图 5‑56 验证02服务功能
验证0x03 / 07¶
通过CAN工具向ECU发送03服务请求报文:
CANID:0x7df
请求内容:01 03 00 00 00 00 00 00
期望结果:收到CANID0x7E8返回DTC,报文内容04 43 01 01 43 00 00 00
通过CAN工具向ECU发送07服务请求报文:
CANID:0x7df
请求内容:01 07 00 00 00 00 00 00
期望结果:收到CANID0x7E8响应返回DTC,报文为04 47 01 43 00 00 00 00

图 5‑57 03&07验证结果
验证Service 0x09¶
通过CAN工具向ECU发送09服务请求报文:
CANID:0x7df
请求内容:02 09 00 00 00 00 00 00
期望结果:收到CANID0x7E8返回报文内容06 49 00 40 00 00 00 00
通过CAN工具向ECU发送09服务请求报文:
CANID:0x7df
请求内容:02 09 02 00 00 00 00 00
期望结果:收到CANID0x7E8响应,内容与5.2.10章节填写的数据内容一致。

图 5‑58 验证结果09