AUTOSAR入门-Dcm模块

原创 thatway 那路谈OS与SoC嵌入式软件 2022-04-13 18:03

AUTOSAR入门-Dcm模块

先复习下**AS代码**  

之前做过的试验:AUTOSAR入门-基于以太网诊断

。我们通过网络发送DoIP报文
,实现了对汽车EcuReset的功能,报文通过的模块依次为:
网卡驱动-》网络接口-》LWIP网络协议栈-》SoAd模块-》DoIP模块-》PduR模块-》Dcm模块

我们**倒着**  

从功能角度入手,结合AUTOSAR规范从Dcm模块
开始讲解下AS里面里面的处理过程,Dcm模块是我们第一个讲的AUTOSAR的模块,其他模块的所有套路在AUTOSAR框架里面都是相通的,这里我希望能做到
抛砖引玉的效果

0. 准备工作

研究AUTOSAR规范,首先要知道官网:
https://www.autosar.org

官网资料是其他资料的源头,最权威的内容, 通常工作中会像字典一样反复查阅。
首先打开:

https://www.autosar.org/nc/document-search/

按下图下载规范:

AUTOSAR_SWS_DiagnosticCommunicationManager.pdf

或者直接输入如下网址查看:

https://www.autosar.org/fileadmin/user_upload/standards/classic/19-11/AUTOSAR_SWS_DiagnosticCommunicationManager.pdf

首先说下这个文档该怎么看,从这文件的名字上有**SWS**  

,这个意思是软件规范,也是我们作为开发人员主要看的内容。其他的前缀解释如下:

EXP: 即Explaination"解释",详细介绍论题
MMOD: 即MetaModel"元模型",介绍 AUTOSAR元模型
MOD: 即Model"建模",介绍建模的原理
RS: 即RequirementSpecification"需求规范", 详细介绍需求
SRS: 即SoftewareRequirement Specification"软件需求规范", 描述所有软件模块的规范
SWS: 即SoftewareSpecification"软件规范", 介绍软件模块设计和实现的规范
TPS: 即TemplateSpecification"模板规范", 详细介绍元模型
TR: 即TechnicalSpecification"技术规范",详细介绍技术规范

然后SWS后面的

DiagnosticCommunicationManager就是功能模块的命名,首字母可以看出来就是DCM

上图中红色
标识出来的就是我们需要重点关注的,本文也是按照这个顺序进行展开,下面带着大家按这个文档
来看一遍来,了解Dcm。

1. 简介和功能介绍

打开这个pdf文档,第一部分如下:

重点看下这个图,通过诊断工具
连接到汽车上的板卡
上,可以跟板卡里面的Dcm模块
通信。
那么通信干什么呢?
接着往下看:

这段英语翻译过来为:

Dcm
模块确保诊断数据流并管理诊断状态
,特别是诊断会话和安全状态。此外,
Dcm
模块根据诊断状态检查是否支持
诊断服务请求
,以及服务是否可以在当前会话中执行。

那么提供什么服务
呢?答案就是UDS和OBD服务,这是两种应用协议,这里我们以UDS为例说明,UDS

Unified Diagnostic Services)里面有什么服务呢?

查看ISO14229 手册(公众号回复ISO
获取):

从第9章开始,有这么多服务,用到哪个就去查这个手册。

下面这个图更加直观一点:

诊断可以提供什么服务是不是一目了然,比如车坏了,要知道怎么坏的,可以去**读数据**  

。可以设置参数写数据
,可以控制设备
比如重启,总之跟车交互的功能基本都在里面。

下面继续以之前做的以太网诊断为例进行说明,我们发的DoIP报文如下:

报文里面的11 01
就是包装的UDS报文
的内容,通过查询上面的SID
,我们知道11是复位
,继续查01是硬件复位
的意思:

上面说了挺多的介绍,业务方面介绍差不多了,大家应该知道Dcm是干什么的了,就是实现**UDS里面规定的服务**  

。但是只讲概念是没有灵魂的,对于程序员来说:

Talk is cheap,show me the code!

打开AS**代码**
,先找到Dcm代码的位置:

Dcm_Dsd.c中selectServiceFunction()函数里面就是对于UDS报文id
的处理,

例如我们上面的0x11
如下:

然后01按照ISO14229
标准是硬重启,查看
DspUdsEcuReset()
函数:

处理完毕,也是按照**ISO14229**  

的标准对外部诊断程序进行报文回应。
其他的服务执行逻辑根据switch自己查看代码。可以自己加log
打印,做实验看看代码是不是跑到这里了,应该是挺有意思
的事情。跟打游戏一样,体验下代码被你控制的感觉。

在1简介和功能介绍中,有一个Dcm在AUTOSAR位置的图:

可以参考:汽车电子构架演进(二)AUTOSAR的组成和演进
,了解Dcm的位置。

2. 缩略词:
看看拓展下知识面就可以,这里不说明。

3. 相关文档
: 可以了解下

4 假定和约束
: 这里不研究了。

5. 依赖模块

依赖模块这个列举出了,**跟Dcm模块交互**  

的其他模块,可以了解到Dcm在ATUOSAR中的位置:

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指示通信模式的改变。  


上面的这些交互都是以**函数**  

为基础的,具体到代码里面,还是以:AUTOSAR入门-基于以太网诊断
为例子说明。

当报文到达**PduR模块**  

的时候,PduR模块需要调用Dcm模块
的代码,把报文传递给Dcm模块:PduR模块-》Dcm模块

在AS代码上需要处理PduR模块调用过来的两个函数,在Dcm.c中:

Dcm_ProvideRxBuffer
()//开始传输报文

Dcm_RxIndication
()//传输报文完毕

6. 需求跟踪暂时不关注

7. 功能规格

功能规格规定了Dcm的软件组成

这里先打个比方,比如到医院看病,首先有接待的部门,导医台
。然后知道去哪个科室看不了就
挂号
。最后到你了就去科室找医生看病
。Dcm主要由三部分组成:Dsl(导医台)、Dsd(挂号系统)、Dsp(科室看病)
,如下图所示:

查看官网文档解释如下:

翻译如下:

为了定义Dcm模块的功能,Dcm SWS将Dcm模块建模为以下子模块:

1)Diagnostic Session Layer
诊断会话层(DSL
)子模块:

DSL子模块负责保证与诊断请求和响应相关的数据流,监督和保证诊断协议定时,管理诊断状态(特别是诊断会话和安全)。

2)Diagnostic Service Dispatcher
诊断服务调度程序(DSD
) 子模块:

DSD子模块处理诊断数据流。子模块:

-通过网络接收新的诊断请求并将其转发给数据处理器

-当数据处理器(如DSP子模块)触发时,通过网络传输诊断响应

3)Diagnostic Service Processing
诊断服务处理 (DSP
)子模块:

DSP子模块处理实际的诊断服务请求(分别为子服务请求)。

下面还是以PduR发来的报文为例,进行说明

1)Dsl(导医台)负责接待

例如接收到PduR模块过来的消息后,如何处理,代码:

Dcm_ProvideRxBuffer函数

Dcm_ProvideRxBuffer
DslProvideRxBufferToPdur(dcmRxPduId, tpSduLength, (constPduInfoType**)pduI    nfoPtr);
  if (findRxPduIdParentConfigurationLeafs(dcmRxPduId,&protocolRx, &mainConnection, &conn     ection, &protocolRow, &runtime)) {
    if (externalRxBuffer->pduInfo.SduLength >=tpSduLength) { /** @req DCM443 */
      if ((runtime->externalRxBufferStatus == NOT_IN_USE)&& (externalRxBuffer->externalBufferRuntimeData->status ==BUFFER_AVAILABLE)) {
           externalRxBuffer->externalBufferRuntimeData->status = BUFFER_BUSY;
           runtime->diagnosticRequestFromTester.SduDataPtr =externalRxBuffer->pduInfo.SduDataPtr;
           runtime->diagnosticRequestFromTester.SduLength = tpSduLength;
           *pduInfoPtr = &(runtime->diagnosticRequestFromTester);
           runtime->externalRxBufferStatus = PROVIDED_TO_PDUR;
            ret= BUFREQ_OK;
}

根据dcmRxPduId在Dcm的配置文件(scons studio生成,10中会说明
)中找到对应的配置,
如果
externalRxBuffer没被使用,有空间,那
么runtime就指向这个externalRxBuffer
最后返回OK。
整个处理过程在DSL,会话层面就处理完毕了。

Dcm_RxIndication函数

Dcm_RxIndication
DslRxIndicationFromPduR(dcmRxPduId, result);
  runtime->externalRxBufferStatus = PROVIDED_TO_DSD; /**@req DCM241 */
      if (runtime->externalTxBufferStatus == NOT_IN_USE) {
          ASLOG( DCM, ("ExternalTx buffer available, we can pass it to DSD.\n"));
      }
      DsdDslDataIndication( // qqq: We are inside a critical section.
          &(runtime->diagnosticRequestFromTester),
          rotocolRow->DslProtocolSIDTable,   /** @req DCM035 */
          protocolRx->DslProtocolAddrType,
          mainConnection->DslProtocolTx->DcmDslProtocolTxPduId,
          &(runtime->diagnosticResponseFromDsd),
          dcmRxPduId);
}

2)Dsd(挂号系统)负责排队分配医生

下面进入Dsd模块进行分发处理

DsdDslDataIndication
  传入参数操作
  dsdDslDataIndication = TRUE; //挂号成功,等待排队

把全局变量
dsdDslDataIndication 置位了,在Dcm模块的轮询函数,
Dcm_MainFunction(
void
)中

Dcm_MainFunction(void)
if (dsdDslDataIndication) {
       dsdDslDataIndication = FALSE;
      DsdHandleRequest(); //排队到了
}

进行任务分发,

DsdHandleRequest
currentSid = msgData.pduRxData->SduDataPtr[0];
if (lookupSid(currentSid, &sidConfPtr)) {
  result =askApplicationForServicePermission(msgData.pduRxData->SduDataPtr,msgData.pduRxData->SduLength);
if (result == E_OK) {
  selectServiceFunction(currentSid);//看病
}

SduDataPtr
就是UDS报文
11 01:02 fd 80 01 00 00 00 06 0e 80 00 22
1101

currentSid
就是报文中的11

selectServiceFunction(uint8 sid)
switch (sid){
case SID_ECU_RESET:
DspUdsEcuReset(msgData.pduRxData, msgData.txPduId, msgData.pduTxData);//给出治疗方案
}

到这里DSD完成了分发,接下来由DSP模块进行处理

3)Dsd(科室医生)负责看病干活

DspUdsEcuReset
reqResetType = pduRxData->SduDataPtr[1];
switch (reqResetType)
  {
    caseDCM_HARD_RESET:
    dspUdsEcuResetData.resetType = reqResetType;
    switch( DcmE_EcuReset(dspUdsEcuResetData.resetType) )
        {
          case E_OK:
            pduTxData->SduDataPtr[1] = reqResetType;
           pduTxData->SduLength = 2;
            DsdDspProcessingDone(DCM_E_POSITIVE_RESPONSE);
           break;
}

reqResetType
就是
11 01中的01,对应DCM_HARD_RESET

DcmE_EcuReset为功能实现函数,实现Ecu的重置,如果执行成功,则填充pduTxData信息,

DsdDspProcessingDone
函数,按照收报顺序的逆序再发给客户端。上面按照收诊断报文的逻辑对Dcm模块的框架
进行了说明。

8. API说明

对代码的实现进行了规范,主要分为两部分:类型定义
函数定义

类型定义,下面看一个例子:

这对代码的规范,简直到了限定死
了的地步,命名,取值范围,在那个文件中定义都规定好了。可以自己在AS代码里面Dcm.h
里面看看有这个定义没。

函数定义,看一个例子:

返回Dcm模块的版本号。对函数的写法,参数的写法,返回值,在那个文件中声明都规定的
明明白白

查看代码,在Dcm.c里面,实现的函数比较少(AS代码中的arccore代码比较旧实现的比较少,最新的
基本都实现了,见

https://github.com/openAUTOSAR/classic-platform
,可以进行移植到AS平台),我们可以对照着研究下。

下面说下AUTOSAR模块代码运行的套路:

1)首先就是初始化
:Dcm_Init(void)

2)然后就是轮询
执行一个函数:Dcm_MainFunction(void)

3)如果有其他模块进行交互,先接待,挂到队列
上,2中轮询到了进行处理。

例如医院看病挂号Dsl成功后,Dsd里面就是轮询一个一个的处理排队的病人,就靠的这个Dcm_MainFunction。  

9. 时序图

规定了各个模块交互时候,函数按时间的调用情况,这里以收取PduR模块发来的包的情况说明:

各个模块间报文传递都需要调用三个函数

AAA_BBBTpStartOfReception
:BBB发给AAA,准备接收报文

AAA_BBBTpCopyRxData
:BBB发给AAA,拷贝报文

AAA_BBBTpRxIndication
:BBB发给AAA,接收成功
确认

10. 配置相关

规定了配置工具也就是工具链如何实现,**AS平台**  

有自己的工具链
。下面介绍下:首先看下代码里面配置相关的部分,在初始化的时候,需要用到配置DCM_Config

DCM_Config在build/posix/x86/ascore/config/Dcm_LCfg.c
中定义,

这个文件里面有一个大的全局结构体变量,结构体的子项还是结构体,一时无法看懂,不急,这个变量可以通过工具配置和生成,参考:

AUTOSAR入门-AS平台工具命令和目录介绍

AS平台输入命令
scons studio启动
工具链,如下:

配置完毕,点击File-》Generate就可以生成c代码了。

AUTOSAR的方法论就是,工具链生成配置代码
+固定的BSW代码
一块参与编译,最后在板子上运行。

后记:

再强调一遍,做下之前的实验:[AUTOSAR入门-基于以太网诊断](http://mp.weixin.qq.com/s?__biz=MzUzMDMwNTg2Nw==&mid=2247483815&idx=1&sn=8603d2994641cbbb02d48ac0313d074b&chksm=fa528783cd250e9524080071c93ed2d7db49a074824f264587bd317f3fda28e746657c7161de&scene=21#wechat_redirect)  

,然后自己动手打log调试
,结合代码来看AUTOSAR的各个模块。另外多看几遍AUTOSAR官网文档
,AUTOSAR的所有模块的文档都是按照这个格式
写的,所以看完一个其他的模块就容易多了,后续就不吃力了。

满满的**干货**  

,看到这里,想学AUTOSAR又不知道怎么学,或者没动力的朋友,可以抽点时间操作下了,
师傅领进门,修行靠个人

Talk is cheap,show methe code!  

后续会继续更新,纯
干货分享,无广告,不打赏,欢迎
转载,欢迎
评论交流!

往期
见话题标签:
AUTOSAR入门

results matching ""

    No results matching ""