【Diagnosis基础】Dcm模块详细介绍
1.?Introduction and functional overview
诊断通信管理(Diagnostic Communication Manager, DCM)模块作为AutoSar诊断模块的重要组成部分,主要负责诊断数据流和管理诊断状态,包括诊断会话、安全状态及诊断服务分配等。
主要功能贯穿汽车的开发生产及售后等过程,如开发过程中EMC、DV等实验均可使用诊断服务实现,生产过程中的软件下载更新、ECU产线EOL、汽车产线EOL等、售后过程中读取DTC、控制输出调试功能等。
DCM模块相关的标准主要包括三部分:ISO 14229(UDS,DCM遵循的主要标准)、ISO 15031(ISO 15031 (1-7))及SAEJ1939(OBD,与OBD相关的$01 -$0A服务)。
从网络分层角度看,DCM模块属于上层模块,主要位应用层提供服务。主要包括5-7层,包括会话层服务及应用层等,会话层包括服务定时及服务分配等,应用层为具体的服务功能实现。
在AUTOSAR架构中,Dcm(Diagnostic Communication Manager)模块位于通信服务层。Dcm模块是独立于具体的网络的(不依赖于具体的CAN,Lin,Eth,Flexray等网络来实现)。PduR模块为Dcm模块提供独立于具体网络的接口。Dcm模块从PduR模块接收诊断信息,Dcm模块在内部处理和检查诊断消息。作为处理所请求的诊断服务的一部分,Dcm将与其他BSW模块或SW-Components(通过RTE)交互,以获取所请求的数据或执行所请求的命令。诊断服务处理与特定的服务请求强绑定(不同的诊断请求依赖于不同的一个或几个模块来实现)。通常,Dcm将汇集收集到的信息,并通过PduR模块发送回消息。
2.Dependencies to other modules
Dcm和Dem的交互:DEM模块提供了检索与故障内存相关的所有信息的功能,以便Dcm模块能够通过从故障内存中读取数据重新响应测试人员的请求,通俗的讲就是Dcm能够读取Dem记录的DTC信息。
Dcm和PduR的交互:PduR模块接收和发送诊断数据。PduR为Dcm模块提供一个与具体通信协议无关的接口。
Dcm和ComM模块的交互:Dcm模块可以指示状态“活动”和“非活动”用于诊断通信。Dcm模块提供了处理通信需求“完全/静默/无通信”的功能。此外,Dcm模块提供了在ComM模块要求时启用和禁用诊断通信的功能。
SWC通过和RTE接口和Dcm交互:Dcm模块在完成诊断功能的时候需要通过RTE接口来读写/函数调用其他SWC的数据/服务。
BswM和Dcm模块的交互:如果Dcm的初始化是从引导加载程序跳转的结果,则Dcm通知BswM应用程序已更新。Dcm也向BswM指示通信模式的改变。
3.Functional specification
3.1 Dcm子模块功能概述
诊断通信管理(DCM)主要包括三个子模块:诊断服务层(Diagnostic Service Layer,DSL)、诊断服务调度(Diagnostic Service Dispatcher, DSD)、诊断服务处理(Diagnostic Service Processing, DSP)
Diagnostic Service Layer:确定诊断数据请求和响应的数据流;监控和确保诊断请求和响应的时序,管理诊断状态(特别是诊断会话和安全状态)
Diagnostic Service Dispatcher:接收到的诊断请求转发给数据处理器;当数据处理器触发时,通过PDUR传输诊断响应。
Diagnostic Service Processing:处理实际的诊断请求。
3.2 诊断会话层(DSL)
DSL模块主要用于诊断请求的处理及诊断时序的控制等,具体存在几个功能如下:
3.2.1 DSL功能概述
1)处理诊断请求:
收到请求时,PDUR会将数据诊断请求数据从下层的Buffer中Copy到诊断的接收Buffer中,DSD会从此Buffer中取出数据进行处理。
维持诊断功能在线(保活逻辑)。
2)处理诊断响应:
收到发送数据时,PDUR会将数据诊断请求数据从DSL的发送Buffer中Copy到PDUR的发送Buffer中,具体后续处理由CAN的协议栈进行处理。
保证诊断时序。
支持周期性传输数据。
支持事件型响应(ResponseOnEvent)。
支持分段响应(segmented response)。
支持由应用触发的挂起响应(ResponsePending)。
3)管理安全等级:
用于获取或者设置安全等级
4)会话状态处理:
管理会话状态(session state)。
非默认会话的激活状态跟踪。
允许修改时序(应用可以通过诊断命令动态修改时序,也就是修改时序参数)。
5)诊断协议处理:
处理不同的诊断协议。
管理资源。
6)通信模式处理;
处理通信请求(Full-/Silent-/No Communication)。
标识诊断功能是否激活(active/inactive)。
打开/关闭(Enabling/disabling)所有类型的诊断传输。
3.2.2 将请求从PduR模块转发到DSD子模块
带有诊断属性的PDU到达PduR模块后,PduR调用Dcm_StartOfReception,通知Dcm模块接收的数据大小,并提供第一帧或单帧的数据,如果数据规模溢出缓冲区大小,或者请求的服务不可用允许Dcm拒绝接收诊断数据。PduR模块之后调用Dcm_CopyRxData函数请求Dcm模块拷贝数据到Dcm buffer。
如果DCM模块接收诊断请求(Dcm_StartOfReception,函数返回成功),PduR模块就会调用Dcm_TpRxIndication通知到Dcm模块诊断请求接收完成。
3.2.3 维持诊断功能在线(保活逻辑)
DSL子模块需要实现诊断会话在线功能,测试者通过物理寻址方式发送0x3E 80诊断请求,DSL接收到0x3E 80的请求后需要维持当前的诊断会话不退出(通过重置超时计数器S3Server)。
3.2.4 将DSD子模块的响应转发到PduR模块
DSD模块准完成诊断响应后会向DSL模块请求发送诊断响应报文。PduR模块接收到请求后调用调用PduR_DcmTransmit()函数发送数据,数据发送后,PduR模块调用Dcm_TxConfirmation()函数通知Dcm模块数据发送结果。
3.2.5 通用连接处理
以CAN网络上的通用诊断连接处理为例。CAN网络上的每个ECU节点内部都会记忆两个诊断请求ID,物理寻址请求ID和功能寻址请求ID。
示例:Tester为连接到CAN网络上发送诊断请求的上位机,可发送任意诊断报文。ECU_A本地配置的物理寻址ID为0x728,功能寻址ID为0x7DF。ECU_B本地配置的物理寻址ID为0x72E,功能寻址ID为0x7DF。
物理寻址:1:1的单播诊断请求
Tester发送物理寻址ID为0x728的诊断请求时只有ECU_A会响应。
Tester发送物理寻址ID为0x72E的诊断请求时只有ECU_B会响应。
功能寻址:1:n的广播诊断请求
Tester发送功能寻址ID为0x7DF的诊断请求时ECU_A和ECU_B都会响应。
3.2.6 发送Busy响应来保证诊断时序
上位机发送诊断请求后会要求ECU在一个最大响应时间(一般是50ms)内发出响应报文,但是对于一些请求的处理,ECU内部会耗时比较长(比如0x2E写NVM的请求),来不及在规定时间发出响应。这个时候ECU可以发送0x78(Pending)的否定响应吗来通知上位机ECU内部繁忙(Busy),需要上位机等待(Pending,一版Pending时间可以设置为1秒)。上位机收到0x78(Pending)的否定响应码后就会等待,直到ECU发出积极响应或者Pending时间超时。这个发送Bussy响应来保证诊断时序的功能由DSL模块实现。
3.2.7 支持周期传输
UDS提供的“ReadDataByPeriodicIdentifier (0x2A)”服务,用于向由一个或多个periodicDataIdentifiers标识的ECU请求定期传输数据记录值。实际项目中没有用到过。
3.2.8 支持ROE传输。
通过UDS Service ResponseOnEvent (0x86),测试人员可以请求ECU启动或停止传输由指定事件发起的响应。当注册一个事件进行传输时,测试者也指定相应的服务来响应(例如:UDS service ReadDataByIdentifier 0x22)。实际项目中没有用到过。
3.2.9支持分段响应
如果启用(DcmPagedBufferEnabled=TRUE), Dcm module将提供一种机制来发送比配置的和allocated诊断缓冲区更大的响应。也就是分段响应机制。实际项目中没有用到过。
3.2.10 支持由应用程序触发的响应
在某些情况下,例如在例程执行的情况下,应用程序需要立即请求一个NRC 0x78(响应等待),该请求应立即发送,而不是仅仅在到达响应时间之前(P2ServerMax分别为P2*ServerMax)。
当Dcm模块调用一个操作并得到一个错误状态DCM_E_FORCE_RCRRP时,DSL子模块将触发NRC 0x78(响应等待)的负响应传输。这个响应需要从一个单独的缓冲区发送,以避免覆盖正在进行的请求处理。
3.2.11 管理安全等级
安全等级理解:DCM模块的每个诊断服务可以配置安全访问等级,一般有无需通过安全访问、需要通过安全等级1访问、需要通过安全等级2访问三种等级。比如对于0x2E下的服务都设定为需要过安全访问等级1后,我们在请求0x2E的服务时需要通过特定的安全校验后才能通过安全访问等级1,这样才能得到0x2E服务的积极响应。
DLS子模块应该保存当前激活的安全等级状态。DLS模块提供两个接口用来设置和获取当前安全等级:
获取当前激活的安全等级: Dcm_GetSecurityLevel
设置新的安全等级: DslInternal_SetSecurityLevel()
DCM模块初始化完后,安全等级设置为0x00(DCM_SEC_LEV_LOCKED,使能了安全访问功能)。
如果我们通过安全校验算法后后使得安全等级不为0,当发生以下任意事件后,安全等级状态将回到初始状态0x00(DCM_SEC_LEV_LOCKED):
1)诊断会话(session)从非缺省会话(0x0, default session)切换到非缺省会话,包括从当前非缺省会话切换到本身自己。
2)诊断会话(session)从非缺省会话(0x0, default session)切换到缺省会话。
3.2.12管理会话状态
会话:session,一般有三种,缺省会话(0x00, Default session)、编程会话(0x01, Programming session)、扩展会话(0x02Extended session)。每种会话下可以进行的诊断服务不同,根据实际需求由OEM自己定义。一般来说诊断(UDS)刷写功能需要在编程会话下进行,涉及到NVM关键存储数据的写功能需要在扩展会话下进行。根据实际需求可以自己定义会话,比如定义0x60(EOL session)专门用于EOL工厂下线处理(关于EOL下线,后面将会由文章具体接收,请关注本公众号后续文章)。
DLS子模块应该保存当前激活的会话状态。DLS子模块应该提供两个接口用于获取/设置会话状态:
1)获取当前会话状态: Dcm_GetSesCtrlType()
2)设置会话状态:DslInternal_SetSesCtrlType()
DCM模块初始化完成后,诊断会话进入缺省会话。
3.2.13 跟踪激活的非缺省会话
从缺省会话进入非缺省会话后,S3Server定时器就会开始计时(只要收到诊断请求报文就会清零),如果定时器超时(S3Server),DLS模块就会将会话状态切换到缺省会话状态。
3.2.14 允许修改时序
P2ServerMin, P2ServerMax, P2*ServerMin, P2*ServerMax, S3Server这些参数值将会影响DCM模块的诊断响应时序。
P2ServerMin=0, P2*ServerMin=0, S3Server = 5为固定值。协议参数影响诊断会话层的时序,不会影响到传输层时序。当协议激活时,可以通过以下方法修改其中一些定时参数:
??UDS Service diagnostics sessioncontrol (0x10)
??UDS服务AccessTimingParameter (0x83)
DSL子模块提供了以下功能来修改定时参数:
?提供活动定时参数,
?设置新的定时参数。只允许在发送响应之后激活新的计时值
3.2.15 处理不同的诊断协议
DSL子模块需要处理不同的诊断协议。实际应用中一般都是使用DCM_UDS_ON_CAN协议。
3.2.16 管理资源
由于资源有限,DSL应该考虑以下几点作为设计提示:
1)在Dcm模块中只允许使用和分配一个诊断缓冲区,这个缓冲区随后用于处理诊断请求和响应
2)NRC 0x78 (Response pending)响应的输出是通过一个单独的缓冲区完成的
3)支持分页缓冲处理
3.2.17 通信模式处理
DCM模块和ComM模块的交互有DSL子模块完成。ComM模块把每个通信通道(channel)的当前通信状态(No-com, Full-com, Silent-com)通知给Dcm模块。Dcm模块的诊断功能将会调用ComM模块的接口功能可能会阻止Ecu进入shutdown模式(ActiveDiagnostic ==’DCM_COMM_ACTIVE’时ECU必须保持唤醒状态,也就是不允许 进入shutdown/sleep)。
应用程序可以调用Xxx_SetActiveDiagnostic()接口通知Dcm模块ActiveDiagnostic的当前状态。
No Communication:
ComM模块调用 Dcm_ComM_NoComModeEntered接口通知Dcm模块通信关闭。Dcm模块收到通知后就会Disable所有的诊断接收/传输。
Silent Communication:
ComM模块调用 Dcm_ComM_SilentComModeEntered接口通知Dcm模块通信静默。Dcm模块收到通知后就会Disable所有的诊断传输。
Full Communication:
ComM模块调用 ?Dcm_ComM_FullComModeEntered接口通知Dcm模块通信静默。Dcm模块收到通知后就会Enable所有的诊断接收/传输。
Diagnostic Activation State:
Dcm将所有网络的内部诊断状态通知ComM模块。网络上的诊断状态有两种选择。在“活动”诊断状态下,Dcm正在处理来自该网络的一个或多个诊断请求,或者Dcm处于非默认会话中。在“非活动”诊断状态下,Dcm处于默认会话,并且没有在该网络上处理诊断请求。
当一个网络没有正在进行的通信时,Dcm会将诊断ac激活状态设置为' inactive '。当网络上有诊断通信时,Dcm将诊断状态设置为“活动”。在任何非默认会话中,诊断状态保持为“活动”状态。通信状态也可以通过API Xxx_SetActiveDiagnostic来控制。
3.3 诊断服务调度层(DSD)
3.3.1 DSD功能概述
DSD模块主要用于诊断服务的分配、服务执行环境及条件,会从接收的数据识别请求的服务类型(0x10、0x27、0x22),主要功能:
1)检查诊断服务:用于检查诊断服务执行的条件,如当前会话模式、诊断服务是否支持、安全访问等级。当判断条件不支持是会相应0x7F和具体的NRC否定响应码,通过后会由上一层处理服务(具体处理也可以给出否定响应)
2)汇总响应数据:将判断得到的响应数据或者由DSP发送的响应数据发送给DSL,由DSL向外发送数据
3.3.2 使用场景
1)接收诊断请求信息传输积极响应信息
DSD模块接收到诊断请求信息后会校验其有效性(session, security)。这种场景下,数据都是有效的,同时会反馈积极响应。DSD模块会将数据传递给DSP子模块下对于的服务处理器。当DSP子模块下的服务处理器完成了数据处理后会触发DSD模块传输积极响应信息。
如果数据处理器将服务作为请求指示函数的一部分立即处理,则数据处理器可以在此指示函数(“同步”)中触发传输。如果处理需要较长的时间(例如等待EEPROM驱动程序),则数据处理器将延迟某些处理(“异步”)。DSL子模块包含响应挂起机制。数据处理器显式地触发传输,但是从数据处理器的上下文中触发的。
一旦接收到请求消息,相应的DcmPduId就会被DSL子模块阻塞。在此请求的处理过程中,不能再接收其他相同协议类型的请求(例如,增强的会话可以通过OBD会话结束),直到发送相应的响应消息,并再次释放DcmPduId。
2)接收诊断请求信息抑制积极响应
这是前一个用例的子用例。在UDS协议中,可以通过在请求消息中设置一个特殊的位来抑制正响应。这种特殊的抑制处理完全在DSD子模块中执行。
3)接收诊断请求信息抑制否定响应
功能寻址的场景下,DSD模块将抑制否定响应码为0x11,0x12,0x31,0x7E的否定响应。
4)接收诊断请求信息传输否定响应信息
拒绝请求消息并发送否定响应有许多不同的原因。如果诊断请求无效,或者请求在当前会话中不能执行,DSD子模块将拒绝处理,并返回一个否定响应。
但是,甚至有许多理由拒绝执行一个格式符合的请求message,例如,如果ECU或系统状态不允许执行。在这种情况下,DSP子模块将触发一个消极的响应,包括NRC提供额外的信息,为什么这个请求被拒绝
对于由多个参数组成的请求(例如,一个UDS Service ReadDataByIdentifier (0x22)请求有多个需要读取的标识符),每个参数被单独处理。每个参数都可能返回一个错误。如果至少一个参数被成功处理,这种请求将返回一个正响应。
5)没有接收诊断请求发送积极响应
UDS协议中包含两个服务,一个请求发送多个响应。通常,一个服务用于启用(和禁用)另一个服务的事件或时间触发传输,ECU在没有相应请求的情况下再次发送该服务。这些服务包括:
. 0x2A服务,周期传输诊断响应服务。
. 0x86服务,基于事件触发的响应服务。
6)分段响应
在诊断协议中,一些服务允许交换大量的数据,例如UDS Service ReadDTCInformation (0x19)和UDS Service TransferData (0x36)。
在传统的方法中,ECU内部缓冲区必须足够大,以保存最长的数据消息要交换(最坏的情况),并在传输开始之前填充完整的缓冲区。
ECU中的RAM内存通常是一个关键的资源,特别是在较小的微型计算机中。在一种更节省内存的方法中,只填充部分缓冲区,传输部分缓冲区,然后再填充部分缓冲区,以此类推。这种分页机制只需要大幅减少的内存量,但需要定义良好的缓冲填充反应时间。
用户可以决定是否使用“线性缓冲区”或页面缓冲区进行诊断。
3.3.3 DSD模块和其他模块的交互
DSL模块接收到诊断数据后,DSD模块的服务就会被调用,DSD模块将会执行以下的操作:
1)委托DSP子模块或Dcm 外的外部模块处理请求。
2)跟踪请求处理。
3)将应用程序的响应发送给DSL子模块。
3.3.4 DSD模块功能描述
3.3.4.1 检查诊断服务标识符
DSL接收到诊断信息后触发DSD模块去校验诊断信息ID的有效性。DCM模块可以配置当前ECU支持多个诊断ID,不过一般情况下,一个ECU仅支持一个物理寻址ID和一个功能寻址ID,如果收到的诊断信息中的ID信息不是ECU配置好的物理/功能寻址ID,则DCM返回否定响应码NRC:0x11。
3.3.4.2 处理正响应抑制响应位
诊断报文的第二个字节的bit7如果置位1(suppressPosRspMsgIndicationBit = TRUE),DSD模块不用发送积极正响应(抑制正响应)。
3.3.4.3 校验功能
DSD模块将会对一个诊断请求做一下6个方面的校验,如果全都通过了才会继续处理诊断请求,否则返回对应的否定响应码。
1)制造商许可的校验。实际项目中基本没有这个校验。
2)SID的校验。服务ID的校验,也就是是否支持当前接收到的诊断ID。
3)诊断会话校验。在诊断配置阶段,会预先定义每个诊断请求在什么会话下才支持。测试时,只有在支持的诊断会话下才会积极响应对应的诊断请求,否则返回NRC:0x7E的否定响应码。所以在诊断请求前,可以先通过0x10服务将诊断会话切换到需要的会话状态,同时通过0x3E服务维持诊断会话。
4)安全访问等级的校验。在诊断配置阶段,会预先定义每个诊断请求在安全等级下才支持。测试时,只有在支持的安全等级下才会积极响应对应的诊断请求,否则返回NRC:0x33的否定响应码。所以在诊断请求前,可以先通过0x27服务将安全等级切换到需要的安全等级。
5)供应商许可的校验。实际项目中基本没有这个校验。
6)服务ID的模式规则状态校验。如果DcmDSD模块引用的DcmDsdSidTabModeRuleRef模式规则不支持当前诊断ID服务或其子服务,则返回否定响应码。
3.3.4.4 检查格式及是否支持子服务
DSD模块将会检查接收到的诊断信息的长度是否大于配置的最小长度,不满足则返回否定响应码NRC:0x13。DSD模块将会检查诊断信息的子服务是否支持,如果不支持则返回否定响应码NRC:0x12。
3.3.4.5 将诊断消息分发到DSP子模块
DSD子模块应为新接收的诊断服务标识符搜索DSP子模块的可执行功能,并调用相应的DSP服务解释器。
3.3.4.6 组装积极或者消极响应
当DSP子模块完成了重新请求的诊断服务的执行时,DSD子模块将组装响应消息。
3.3.4.7 开始传输诊断响应
DCM模块完成诊断操作后,DSD模块通过调用PduR模块的信息发送接口将诊断响应(积极响应或者否定响应)发送出去。
DSL子模块应将收到的来自PduR模块的确认转发给DSD子模块。
DSD子模块应通过内部函数DspInternal_DcmConfirmation()将确认转发给DSP子模块。
在没有发送诊断(响应)消息(抑制响应)的情况下,DSL子模块不发送任何响应。在这种情况下,没有数据确认从DSL子模块发送到DSD子模块,但DSD子模块仍将调用内部函数DspInternal_DcmConfirmation()。
如果Dcm已经完全处理了请求,DSD子模块应该通过调用DspInternal_DcmConfirmation()来完成诊断tic服务调度程序的一条诊断消息的处理。
DSP子模块正在等待DspInternal_DcmConfirmation()功能的执行。所以它必须被发送,也是在没有数据确认提供。总之,这意味着在下列任何情况下:
.积极响应
.否定响应
.抑制积极响应
.抑制否定响应
DSD子模块将通过调用DspInternal_DcmConfirmation()来完成。
3.4 诊断服务处理层(DSP)
3.4.1 DSP功能概述
DSP为诊断服务的处理,当接收到DSD请求处理诊断服务,服务处理过程:
. 分析收到的请求消息
. 检查格式和是否支持寻址子功能
. 在DEM、SWC或其他BSW模块上获取数据或执行所需的函数调用
. 组装响应
3.4.1.1 检查格式及是否支持其子功能
DSP对请求消息的分析导致格式错误或长度错误时,DSP子模块将触发NRC 0x13 (Incorrect message length or invalid format)的负响应。
3.4.1.2 组装消息
DSP子模块通过对包含响应服务标识符的响应消息进行组装,确定响应消息长度。
3.4.1.3 否定响应码的处理
除非另一个特定的NRC被指定,否则当API调用执行服务没有返回OK时,DSP子模块应该触发NRC 0x10 (generalReject)的负响应。
3.4.1.4 诊断模式声明组
Dcm作为诊断模式的模式管理员,管理以下7类模式切换:
1). DcmDiagnosticSessionControl (service 0x10)
2). DcmEcuReset (partly service 0x11)
3). DcmSecurityAccess (service 0x27)
4). DcmModeRapidPowerShutDown (partly service 0x11)
5). DcmCommunicationControl_<symbolic name of ComMChannelId>. (service
0x28)
6). DcmControlDTCSetting (service 0x85)
7). DcmResponseOnEvent_<RoeEventID> (service 0x86)
以DcmSecurityAccess为例,DCM声明安全访问相关的模式组:
ModeDeclarationGroup DcmSecurityAccess
{
{
? DCM_SEC_LEV_LOCKED
DCM_SEC_LEV_1
? ...
DCM_SEC_LEV_63
}
?initialMode = DCM_SEC_LEV_LOCKED
};
ModeSwitchInterface ?SchM_Switch_<bsnp>_DcmSecurityAccess
{
? isService = true;
? SecLevel currentMode;
};
3.4.1.5 模式相关的请求执行
可以根据模式条件限制请求的执行。这使得Dcm能够格式化的进行环境检查。
3.4.1.6 Sender/Receiver通信
如果配置容器DcmDspData的参数DcmDspDataUsePort配置为USE_DATA_SENDER_RECEIVER或者USE_DATA_SENDER_RECEIVER_AS_SERVICE则DcmDspDataUsePort为一个R-Port,需要为这个R-Port顶一个Interface(一个参数,参数的实现数据类型为 DcmDspDataType)。
如果配置容器DcmDspData的参数DcmDspDataUsePort配置为USE_DATA_SENDER_RECEIVER或者USE_DATA_SENDER_RECEIVER_AS_SERVICE则DcmDspDataUsePort为一个P-Port,需要为这个P-Port顶一个Interface(一个参数,参数的实现数据类型为 DcmDspDataType)。
3.4.1.7 将SwDataDefProps属性从DEXT文件传递到Dcm Service SW-C
用例:将SwDataDefProps细节如CompuMethod、DataContraints和Units传递给Dcm Service SW-C,并使它们在每个DID DataElement / RoutineControl信号中可用。有两个可选的工作流程。
3.4.1.8 异步调用行为
如果一个Dem函数返回DEM_PENDING, Dcm将在稍后的时间点再次调用该函数。
如果一个诊断任务请求的负面响应数量达到配置参数eter DcmDslDiagRespMaxNumRespPend中定义的值,Dcm模块将停止处理活动的诊断请求,通知应用程序或BSW(如果这个诊断任务意味着调用一个SW-C接口或BSW接口),通过设置OpStatus参数,active端口接口,DCM_CANCEL,并发送一个NRC 0x10的否定响应(一般拒绝)。
如果之前的返回状态是E_PENDING,那么Dcm_SetProgConditions API将在下一个Dcm主函数循环中被再次调用。
DCM_E_PENDING的返回应该做一个重新触发(例如在下一个MainFunction循环中)。
调用OpStatus为DCM_CANCEL的接口的返回值将被忽略。
3.4.2 UDS服务
Dcm模块需要支持以下UDS服务
4.关键API
4.1Function definitions
4.1.1Dcm_Init
函数原型:void Dcm_Init(const Dcm_ConfigType* ConfigPtr)
参数:
ConfigPtr:指向Dcm配置集合的指针(指向const数组的指针)
返回值:无
功能描述:根据动态配置初始化Dcm模块
4.1.2 Dcm_DemTriggerOnDTCStatus
函数原型:
Std_ReturnType Dcm_DemTriggerOnDTCStatus(uint32 DTC, Dem_UdsStatusByteType DTCStatusOld, Dem_UdsStatusByteType DTCStatusNew)
参数:
DTC:DTC标识符(代表某个具体的DTC)
DTCStatusOld:DTC改变前的状态
DTCStatusNew:DTC改变后的状态
返回值:总是返回E_OK
功能描述:UDS状态字改变后就会调用这个接口,改变DTC状态。
4.1.3?Dcm_GetVin
函数原型:
Std_ReturnType Dcm_GetVin(uint8* Data)
参数:
Data:存放VIN码地址的指针
返回值:
E_OK:成功获取VIN到Data指向的地址空间
E_NOT_OK:在DoIP中将使用默认VIN
功能描述:获取VIN码
4.1.4 Dcm_GetSecurityLevel
函数原型:
Std_ReturnType??Dcm_GetSecurityLevel(Dcm_SecLevelType* SecLevel)
参数:
SecLevel:获取的安全等级值存放到SecLevel指针指向的内存。
返回值:总是返回E_OK
功能描述:获取安全等级值。
4.1.5 Dcm_GetSesCtrlType
函数原型:
Std_ReturnType Dcm_GetSesCtrlType(Dcm_SesCtrlType* SesCtrlType)
参数:
SesCtrlType:获取的会话状态值存放到SesCtrlType指针指向的内存。
返回值:总是返回E_OK
功能描述:获取会话状态值。
4.1.6 Dcm_ResetToDefaultSession
函数原型:
Std_ReturnType Dcm_ResetToDefaultSession(void)参数:
返回值:总是返回E_OK
功能描述:将当前会话状态切换到default默认状态。
4.1.7 Dcm_ SetActiveDiagnostic
函数原型:
Std_ReturnType Dcm_SetActiveDiagnostic(boolean active)
参数:
Active:是否激活诊断功能的标志。
返回值:总是返回E_OK
功能描述:如果active == true,DCM就会调用ComM_DCM_ActiveDiagnostic(),否则不调用。
4.2 Call-back notifications
介绍底层BSW模块提供的功能。回调函数的函数原型将在Dcm_Cbk.h文件中提供。也就是Dcm模块实现这些回调函数,其他模块(ComM, PduR等)使用这些回调函数。
4.2.1 Dcm_StartOfReception
BufReq_ReturnType Dcm_StartOfReception(
PduIdType id,
const PduInfoType* info,
PduLengthType TpSduLength,
PduLengthType* bufferSizePtr
)
功能描述:PduR模块接收到诊断报文的第一帧(单针SF, 或者多帧的首帧FF)时调用,通知Dcm模块开始接收诊断报文。
4.2.2 Dcm_CopyRxData
BufReq_ReturnType Dcm_CopyRxData(
PduIdType id,
const PduInfoType* info,
PduLengthType* bufferSizePtr
)
功能描述:PduR模块接收到多帧的连续帧(CF)时调用,将诊断数据传递到DCM模块。
4.2.3 Dcm_TpRxIndication
void Dcm_TpRxIndication(
PduIdType id,
Std_ReturnType result
)
功能描述:在通过TP API接收到I-PDU后调用。
4.2.4 Dcm_CopyTxData
BufReq_ReturnType Dcm_CopyTxData(
PduIdType id,
const PduInfoType* info,
const RetryInfoType* retry,
PduLengthType* availableDataPtr
)
功能描述:调用该函数获取I-PDU段(N-PDU)的传输数据。
4.2.5 Dcm_TpTxConfirmation
void Dcm_TpTxConfirmation(
PduIdType id,
Std_ReturnType result
)
功能描述:这个函数是在I-PDU在其网络上传输后调用的,结果表明传输是否成功。
4.2.6 Dcm_TxConfirmation
void Dcm_TxConfirmation(
PduIdType TxPduId,
Std_ReturnType result
)
功能描述:下层通信接口模块确认PDU发送,或者PDU发送失败。
4.2.7 Dcm_ComM_NoComModeEntered
void Dcm_ComM_NoComModeEntered(
uint8 NetworkId
)
功能描述:ComM模块通知Dcm模块NetworkId标识的网络进入了COMM_NO_COMMUNICATION状态。
4.2.8 Dcm_ComM_SilentComModeEntered
void Dcm_ComM_SilentComModeEntered(
uint8 NetworkId
)
功能描述:ComM模块通知Dcm模块NetworkId标识的网络进入了COMM_SILENT_COMMUNICATION状态。
4.2.9?Dcm_ComM_FullComModeEntered
void Dcm_ComM_FullComModeEntered(
uint8 NetworkId
)
功能描述:ComM模块通知Dcm模块NetworkId标识的网络进入了COMM_FULL_COMMUNICATION状态。
4.3 Callout Definitions
Callouts是在ECU集成过程中必须添加到Dcm的代码片段。大多数Callouts的内容是手写的代码,对于一些Callouts,Dcm配置工具会生成一个默认实现,由集成器手动编辑。从概念上讲,这些Callouts属于ECU固件。
由于Callouts不是Dcm的服务,它们没有分配的服务ID。注意:Autosar架构不提供使用物理地址访问ECU内存的可能性。这是使用标识内存块的BlockId实现的。
根据这一点,Dcm不能完全支持ISO14229- 1服务的实现,这些服务要求物理内存访问。因此,Dcm定义了callout来实现这种内存访问。通过定义BlockId和物理内存地址之间的映射,可以简单地实现这个调出实现。
4.4Scheduled functions
4.4.1 Dcm_MainFunction
void Dcm_MainFunction(void)
4.5 Expected interfaces
4.5.1 Mandatory interfaces
实现模块核心功能所需的所有接口
4.5.2 Optional interfaces
实现模块的一个可选功能所必需的接口
4.5.3 Configurable interfaces
Dcm配置中定义Dcm将使用的实际函数的接口。根据配置的不同,这些功能的实现可以由其他bsw模块(通常是DEM)或软件组件(通过RTE)提供。
5.时序图
5.1DCM诊断处理流程示例
为了获得安全访问,DSD子模块必须调用DSP子模块来从应用程序获得种子值。如果没有检测到错误,则以积极响应的方式发送种子值。
在第二步中,DSP子模块得到测试器计算的密钥,并请求应用程序将该密钥与内部计算的密钥进行比较。如果没有发生错误,则在DSL子模块中设置新的访问类型,并发送一个正响应。
从上述过程可以看出,我们在实际开发过程中需要做的是根据实际需求配置DCM模块(DSL, DSD, DSP),同时还需要设计一个Dcm_User模块来真正处理(processor)诊断请求。
6.配置
6.1 DCM
DCM模块包括DcmConfigSet和DcmGeneral两个配置容器。
DcmGeneral:Dcm模块的通用配置项。
DcmConfigSet:这个容器包含配置参数和支持多个配置集的DCM模块的子容器。
6.1.1 DcmGeneral
DcmDDDIDStorage:这个配置开关定义了DDDID定义是否存储为非易失性。
DcmDevErrorDetect:打开或关闭开发错误检测和通知。
DcmRespondAllRequest:如果设置为FALSE, Dcm将不会响应响应ID范围为0x40到0x7F或0xC0到0xFF(响应ID)的诊断请求。
DcmTaskTime:允许配置周期周期任务的时间。
DcmVersionInfoAp:配置是否是使用版本检测API。
6.1.2 DcmConfigSet
DcmDsd:DSD诊断调度子模块配置容器。
DcmDsl:DLS诊断会话层子模块配置容器。
DcmDsp:DSP诊断服务处理子模块配置容器。
DcmPageBufferCfg:也缓冲配置容器。
DcmProcessingConditions:模式仲裁配置容器。
6.1.2.1?DcmDsd
DcmDsdRequestManufacturerNotificationEnabled:对制造商允许启用或禁用请求通知机制。
DcmDsdRequestSupplierNotificationEnabled:对供应商允许启用或禁用请求通知机制。
以上两个参数一般都配置位fasle。也就没有DcmDsdServiceRequestManufacturerNotification,
DcmDsdServiceRequestSupplierNotification这两个配置容器的配置。
DcmDsdServiceTable:这个容器包含每个具体诊断服务(0x10, 0x11等)的配置(DSD参数)。
6.1.2.2 DcmDsdServiceTable
DcmDsdSidTabId:可能有多个DcmDsdServiceTable,DcmDsdSidTabId用来标识一个DcmDsdServiceTable。
DcmDsdService:一个具体诊断服务的配置容器。
6.1.2.3 DcmDsdService
DcmDsdServiceUsed:配置是否使用该服务。
DcmDsdSidTabFnc:ECU Supplier特定组件针对特定服务的回调函数。该函数的原型如<Module>_< diagnostics service >所述。如果未配置此参数,则服务在dcm内部处理。
DcmDsdSidTabServiceId:诊断服务ID。
DcmDsdSidTabSubfuncAvail:该服务是否有子服务。
DcmDsdSidTabModeRuleRef:对控制服务执行的DcmDspModeRule的引用。如果没有配置引用,则不进行模式规则检查。
DcmDsdSidTabSecurityLevelRef:引用允许在其中执行服务的安全级别。一个服务允许多个引用。
DcmDsdSidTabSessionLevelRef:对允许执行服务的会话级别的引用。一个服务允许多个引用。
DcmDsdSubService:这个容器包含服务的子服务的配置(DSD参数)。只有那些服务可以有子服务,这些子服务将DcmDsdSidTabSubfuncAvail配置为TRUE。
6.1.2.4 DcmDsdSubService
DcmDsdSubServiceFnc:ECU Supplier特定组件针对特定服务的回调函数。ISOLAR工具没有提供这个配置项。
DcmDsdSubServiceId:子服务ID。
DcmDsdSubServiceUsed:是否使用该子服务。ISOLAR工具没有提供这个配置项。
DcmDsdSidTabModeRuleRef:对控制服务执行的DcmDspModeRule的引用。如果没有配置引用,则不进行模式规则检查。
DcmDsdSidTabSecurityLevelRef:引用允许在其中执行服务的安全级别。一个服务允许多个引用。
DcmDsdSidTabSessionLevelRef:对允许执行服务的会话级别的引用。一个服务允许多个引用。
6.1.2.5 DcmDsl
DcmDslBuffer:此容器包含诊断缓冲区的配置。
DcmDslCallbackDCMRequestService:每个DcmDslCallbackDCMRequestService容器使用CallbackDCMRequestServices接口定义一个R-Port, 应用使用使用接口向Dcm模块请求协议更改的权限。
DcmDslDiagResp:此容器包含Dcm中自动 requestCorrectlyReceivedResponsePending响应管理的配置。
DcmDslProtocol:这个容器包含Dcm中使用的诊断协议的配置。
6.1.2.6 DcmDslBuffer
DcmDslBufferSize:诊断缓冲区大小(以字节为单位)。 对于线性缓冲区,大小应该和最长的诊断消息(请求或响应)一样大。对于分页缓冲区,大小会影响应用程序性能。
6.1.2.7 DcmDslCallbackDCMRequestService
一般实际应用中不使用这个配置。
6.1.2.8 DcmDslDiagResp
DcmDslDiagRespMaxNumRespPend:一个请求允许的带有响应码0x78 (requestCorrectlyReceivedResponsePending)的最大否定响应数。如果Dcm达到此限制,将自动发送0x10 (generalReject)最终响应,并取消服务处理。
6.1.2.9 DcmDslProtocol
DcmDslProtocolRow:该容器包含Dcm中使用的一种特定诊断协议的配置。
6.1.2.10 DcmDslProtocolRow
DcmDslProtocolID:正在配置的DCM DSL协议的诊断协议类型。一般都是基于UDS的CAN诊断。
DcmDslProtocolMaximumResponseSize:定义响应消息的最大长度。
DcmDslProtocolPriority:协议抢占时使用的协议优先级。高优先级的协议可能会抢占低优先级的协议。数值越低表示协议优先级越高。
DcmDslProtocolTransType:仅当协议类型为DCM_ROE_ON_xxx时,此参数有效。
DcmSendRespPendOnTransToBoot:参数指定ECU在转换到引导加载程序之前是否应该发送NRC 0x78(响应等待)(参数设置为TRUE),或者是否应该启动转换而不发送NRC 0x78(参数设置为FALSE)。
DcmTimStrP2ServerAdjust:该参数用于确保在总线上的诊断响应在到达P2之前可用,通过调整当前的DcmDspSessionP2ServerMax。该参数主要表示由DCM发起传输到消息实际传输到总线的时间之间依赖于软件架构的通信延迟。
DcmTimStrP2StarServerAdjust:该参数用于保证在到达P2Star之前,总线上的诊断响应是可用的,通过调整当前的DcmDspSessionP2StarServerMax。该参数主要表示由DCM发起传输到消息实际传输到总线的时间之间依赖于软件架构的通信延迟。
DcmDemClientRef:在Dem配置中引用DemClient。由Dem用于区分不同的客户端调用。
DcmDslProtocolRxBufferRef:引用已配置的诊断缓冲区,该缓冲区用于接收协议的诊断请求。
DcmDslProtocolSIDTable:对用于此协议的诊断请求处理的服务表的引用。
DcmDslProtocolTxBufferRef:引用已配置的诊断缓冲区,用于传输协议的诊断响应。
DcmDslConnection:这个容器包含一个特定协议的通信通道配置。注意,它允许与多个Tester通信,因此可以为一个协议配置多个连接。
6.1.2.11 DcmDslConnection
DcmDslMainConnection:这个容器包含诊断协议的主连接的配置。
DcmDslPeriodicTransmission:这个容器包含定期传输连接的配置。实际应用中一般使用不到。
DcmDslResponseOnEvent:该容器包含ResponseOnEvent连接的配置。
6.1.2.12 DcmDslMainConnection
DcmDslProtocolRxTesterSourceAddr:测试器源地址唯一地描述了一个客户端,并将在跳转到Bootloader接口中使用。对于通用连接(MetaDataLength >= 1的DcmPdus),不需要此参数。
DcmDslPeriodicTransmissionConRef:对用于处理周期性传输事件的周期性传输连接的引用。实际应用中一般很少使用。
DcmDslProtocolComMChannelRef:引用接收DcmDslProtocolRxPdu和发送DcmDslProtocolTxPdu的ComMChannel。
DcmDslROEConnectionRef:引用一个用于处理ResponseOnEvent事件的ResponseOnEvent连接。实际应用中一般很少使用。
DcmDslProtocolRx:此容器包含诊断连接中接收通道的配置参数。
DcmDslProtocolTx:此容器包含诊断连接中传输通道的配置参数。
6.1.2.13 DcmDslProtocolRx
DcmDslProtocolRxAddrType :选择接收信道的寻址类型。1:1通信采用物理寻址,1:1通信采用功能寻址。
DcmDslProtocolRxPduRef:参考EcuC中用于此接收通道的Pdu。
6.1.2.14 DcmDslProtocolTx
DcmDslProtocolTxPduRef:参考EcuC中用于此传输通道的Pdu。
6.1.2.15 DcmDsp
DcmDspDDDIDcheckPerSourceDID: 使用ReadDataByIdentifier (0x22)定义对每个源DIDs的会话、安全性和模式依赖项的检查。
true: Dcm模块应该用一个ReadDataByIdentifier (0x22)检查每个源DIDs的会话、安全性和模式依赖关系,DID的范围是0xF200到0xF3FF。
false: Dcm模块不检查每个源DIDs的会话、安全性和模式依赖关系,每个源DIDs的ReadDataByIdentifier (0x22)的DID范围是0xF200到0xF3FF。
DcmDspMaxDidToRead: 指示在单个“ReadDataByIdentifier”请求中允许的最大DIDs。
DcmDspMaxPeriodicDidToRead: 允许在单个“ReadDataByPeriodicIdentifier”请求中读取的最大periodicDIDs。
DcmDspPowerDownTime: 此参数向客户端指示服务器将保持下电顺序的备用顺序的最小时间。
DcmDspClearDTC: 该容器包含Clear DTC服务的配置。
DcmDspComControl: 提供CommunicationControl机制的配置。
DcmDspCommonAuthorization: 该容器包含多个服务/子服务相同的公共授权的配置(参数)。
DcmDspControlDTCSetting: 提供ControlDTCSetting机制的配置。
DcmDspData: 该容器包含属于DID的Data的配置(参数)。
DcmDspDataInfo: 这个容器包含一个Data的配置(参数)。
DcmDspDid: 这个容器包含DID的配置(参数)。
DcmDspDidInfo: 这个容器包含DID的Info的配置(参数)。
DcmDspDidRange: 这个容器定义DID范围。
DcmDspEcuReset: 该容器包含DcmDspEcuReset服务的配置。
DcmDspMemory: 这个容器包含内存访问的配置。
DcmDspPeriodicTransmission: 此容器包含定期传输调度程序的配置(参数)。
DcmDspPid: 该容器定义了PID对DCM的可用性。
DcmDspRequestControl: 此容器包含“请求控制机载系统、测试或组件”服务(服务$08)的配置(参数)。
DcmDspRequestFileTransfer: 该容器包含RequestFileTransfer的配置。该容器仅在配置了RequestFileTransfer时才存在。
DcmDspRoe: 提供ResponseOnEvent机制的配置。
DcmDspRoutine: 这个容器包含例程的配置(参数)>
DcmDspSecurity: 该容器包含安全级别配置(DSP参数)(每个安全级别)描述该容器包含DcmDspSecurityRow的行。
DcmDspSession: 父容器保存单行来配置特定的会话。
6.1.2.16 DcmDspComControlAllChannel
6.1.2.17 DcmDspCommonAuthorization
DcmDspCommonAuthorizationSecurityLevelRef: 引用DcmDspSecurityRow允许控制此服务/子服务的安全级别。如果没有引用,则不进行安全级别检查。
DcmDspCommonAuthorizationSessionRef: 引用DcmDspSessionRow允许控制此服务/子服务的会话。如果没有引用,则不应检查会话级别。
6.1.2.18 DcmDspControlDTCSetting
DcmDspControlDTCSettingReEnableModeRuleRef:引用DcmModeRule。控制DCM重新启用controlDTCsetting的模式规则。DCM模块应执行一个ControlDTCSetting。关闭(调用Dem_EnableDTCSetting()),以便不再满足所引用的模式规则。
6.1.2.19 DcmDspData
DcmDspDataByteSize: 以字节为单位定义数组长度或变量的最大数组长度。
DcmDspDataConditionCheckReadFnc: 这是函数名字(函数指针)。如果读取这个DID的时候需要应用去检查一些系统状态,就可以定义这个函数去实现这个功能。
DcmDspDataConditionCheckReadFncUsed: 状态检查函数是否被使用。
DcmDspDataEndianness: 定义诊断请求或响应消息中属于DID的数据的字节顺序
DcmDspDataFreezeCurrentStateFnc: 函数名(函数指针),请求应用程序冻结IOControl的当前状态。(FreezeCurrentState-function)。
DcmDspDataGetScalingInfoFnc: 函数名(函数指针),向应用程序请求DID的伸缩信息。(GetScalingInformation-function)。该参数与接口Xxxx_GetScalingInformation有关。
DcmDspDataReadDataLengthFnc: 函数名(函数指针),向应用程序请求DID的数据长度。(ReadDataLength-function)。该参数与接口Xxx_ReadDataLength有关。
DcmDspDataReadEcuSignal: 由DCM读访问某个ECU信号的函数名称。(IoHwAb_Dcm_Read < EcuSignalName >function)。仅当DcmDspDataUsePort==USE_ECU_SIGNAL有效。
DcmDspDataReadFnc: 函数名向应用程序请求DID的数据值。(ReadData-function)。该参数与接口Xxx_ReadData有关。
DcmDspDataUsePort: 定义要访问数据的接口应使用。
6.1.2.20 DcmDspDidInfo
6.1.2.21 DcmDspDidRead
6.1.2.23 DcmDspDid
6.1.2.24 DcmDspDidSignal
6.1.2.25 DcmDspRouting
6.1.2.27 DcmDspStartRoutine
6.1.2.28 DcmDspStopRoutine
6.1.2.29 DcmDspSecurity
6.1.2.30 DcmDspSecurityRow
6.1.2.31 DcmDspSessionRow
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!