聊一聊UDS
今天有个朋友问了我0x28 怎么操控多路CAN。也没解释好,就看了看,写了一下,记录一下
DCM 0x28
sub_function 对应的communication type
这里说一下具体的过程。
其实0x28 服务,就是 :动作 + 对象
动作:
- 打开通讯
- 关闭通讯
对象:
- 普通报文
- 网络报文
抽象成枚举 就是下面列出来的。
/**
* @ingroup DCMCORE_DSLDSD_AUTOSAR
* Dcm_CommunicationModeType:\n
* DCM_ENABLE_RX_TX_NORM 0x00 Enable the Rx and Tx for normal communication\n
* DCM_ENABLE_RX_DISABLE_TX_NORM 0x01 Enable the Rx and disable the Tx for normal communication\n
* DCM_DISABLE_RX_ENABLE_TX_NORM 0x02 Disable the Rx and enable the Tx for normal communication\n
* DCM_DISABLE_RX_TX_NORMAL 0x03 Disable Rx and Tx for normal communication\n
* DCM_ENABLE_RX_TX_NM 0x04 Enable the Rx and Tx for network management communication\n
* DCM_ENABLE_RX_DISABLE_TX_NM 0x05 Enable Rx and disable the Tx for network management communication\n
* DCM_DISABLE_RX_ENABLE_TX_NM 0x06 Disable the Rx and enable the Tx for network management communication\n
* DCM_DISABLE_RX_TX_NM 0x07 Diable Rx and Tx for network management communication\n
* DCM_ENABLE_RX_TX_NORM_NM 0x08 Enable Rx and Tx for normal and network management communication\n
* DCM_ENABLE_RX_DISABLE_TX_NORM_NM 0x09 Enable the Rx and disable the Tx for normal and network management communication\n
* DCM_DISABLE_RX_ENABLE_TX_NORM_NM 0x0A Disable the Rx and enable the Tx for normal and network management communication\n
* DCM_DISABLE_RX_TX_NORM_NM 0x0B Disable Rx and Tx for normal and network management communication.
*/
DCM 如何把用户的输入收进来
dcm本身和硬件通讯没有关系,这里为了方便,就以CAN 为例子来说明。
autosar的通讯和传统互联网类似,也是分层结构。这里DCM 属于我们的最上乘 presentation layer. 和com 是一样的。
从更直观点的链路如下,硬件接受用户通过 设备,或者是 上游控制器发送的 报文。
通过Autosar 协议栈 一路抽象,提取,到DCM 模块。
废话不多说,dcm收到了数据,然后呢?
DCM 怎么处理的呢
我们直接从配置代码入手。
Dcm_Lcfg_DslDsd.c
{
0x6uL, /* Allowed sessions */
0xffffffffuL, /* Allowed in all security levels */
&Dcm_DcmCommunicationControl, /* Service handler */
NULL_PTR, /* Init function of service */
0x28, /* Service id */
TRUE, /* SubFunction Exists */
TRUE, /* Service is located within Dcm */
Dcm_SrvTab0_SubSrv9_acs, /* Pointer to subservice table */
2, /* Number of subservices */
&DcmAppl_UserServiceModeRuleService, /* No User specific mode rule function configured */
&Dcm_Prv_DspCommCntrlConfirmation /* Reference Service confirmation Apis */
},
所以在检查,调试的时候,在实现 开关对应的报文时候,只需要关注最下面这个Api. 即:
/**
*******************************************************************************
* Dcm_Prv_DspCommCntrlConfirmation : API used for confirmation of response sent
* for CommunicationControl (0x28) service.
* \param dataIdContext_u8 Service Id
* \param dataRxPduId_u8 PDU Id on which request is Received
* \param dataSourceAddress_u16 Tester Source address id
* \param status_u8 Status of Tx confirmation function
*
* \retval None
* \seealso
*
*******************************************************************************
*/
当然前提条件要满足也就是。
我们知道在控制软件相关的模式,其实是BswM 来统一管理的。
先说一下对应的函数,后面看一下怎么和配置相互对应。
/**
**************************************************************************************************
* Dcm_DspCommunicationControlSwitchMode : The function will inform the BswM and the SchM/ application
* regarding the change of mode for CommunicationControl Modes owned by Dcm
*
* \param None
*
* \retval None
* \seealso
* \usedresources
**************************************************************************************************
*/
void Dcm_Prv_DspCommunicationControlSwitchMode(void);
在这里面要对哪些channel 进行操作呢?
其实这里面配置了记录channel。就会处理几路, 所以当系统有很多路CAN 的时候,这里和处理。
通过下面这个for 和 宏 逐一传递给BswM
for(idxIndex_u8=0;idxIndex_u8 < DCM_CFG_NUM_ALLCHANNELS_MODE_INFO;idxIndex_u8++)
{
#if (DCM_CFG_DSP_BSWMDCM_ENABLED != DCM_CFG_OFF)
BswM_Dcm_CommunicationMode_CurrentState(Dcm_AllChannels_ForModeInfo[idxIndex_u8].AllComMChannelId,
Dcm_stCommunicationMode_u8);
#endif
#if(DCM_CFG_RTESUPPORT_ENABLED!=DCM_CFG_OFF)
(void)((*(Dcm_AllChannels_ForModeInfo[idxIndex_u8].switch_fp))(Dcm_stCommunicationMode_u8));
#endif
DcmAppl_DcmSwitchCommunicationControl(Dcm_AllChannels_ForModeInfo[idxIndex_u8].AllComMChannelId,
Dcm_stCommunicationMode_u8);
}
在这下面BswM 就需要介入了。
也就是函数
/*****************************************************************************************
* Function name : BswM_Dcm_CommunicationMode_CurrentState(NetworkHandleType Network, Dcm_CommunicationModeType RequestedMode)
* Description : Function called by DCM to inform the BswM about the current state of the communication mode.
* Parameter : Network, RequestedMode
* Return value : void
* Remarks : The corresponding configuration container for this API is BswMDcmComModeRequest.
*****************************************************************************************/
void BswM_Dcm_CommunicationMode_CurrentState
(
NetworkHandleType Network,
Dcm_CommunicationModeType RequestedMode
)
那么这个函数是搞什么的呢?先有个处理的了解。
回归配置。
前面DCM 收到了 user 的命令。这个命令可以传入BswM。 也就是说 BswM 会经过一系列的处理来到达我们熟知的 action.
上面配置了两个channel在dcm 里面。对应的可能就是bswm的输入port. 也就是
在这里后面,就是对单一channel 进行处理了。for 循环处理 所有dcm输入的channel.
这个port 对应的是?
就是看dcm传入的参数是什么了。对应的bswm是
也就是说 dcm 的port 传入了 形参 来找bswm 配置的action list 以及 action
举个例子dcm 传入的是enable tx 那么 到了 bswm 的action 就是
很清晰,这里连接的是com 的 pdu group. 很熟悉是吧。在com 里面可以配置group。所以从这里可以区分 nm 报文 还是 普通报文。
好捋顺了,我们回头看一下上面的UML 图。从代码的角度再看一下。
BswM_Dcm_CommunicationMode_CurrentState --> BswM_Prv_RuleEval(dataDcmCom_st.dataReqProcessing_en, BSWM_MRP_DCM_COM_MODE_REQST, Network, dataDcmCom_st.adrRulesRef_pu16, dataDcmCom_st.nrAssociatedRules_u16);
BswM_Prv_RuleEval 干什么了呢?
这里终于到了action.
void BswM_Prv_CalcPduGrpSwt
(
void
)
一目了然,通过下面函数来控制pdu group
/*
**********************************************************************************************************************
Function name : Com_IpduGroupControl
Description : Service for controlling the Ipdu groups
Parameter : ipduGroupVector_au8 - I-PDU group vector containing the activation state (stopped = 0/started = 1)
for all I-PDU groups.
: initialize_b - flag to request initialization of the I-PDUs which are newly started
Return value : None
**********************************************************************************************************************
*/
#define COM_START_SEC_CODE
#include "Com_MemMap.h"
void Com_IpduGroupControl(Com_IpduGroupVector ipduGroupVector_au8, boolean initialize_b)
逻辑如下
至此 BswM 的处理结束。
总结
上位机 发送0x28 来干活,下班!
文章转载自公众号:汽车与基础软件