Com
模块为汽车控制单元中的应用软件提供了一个统一的通信环境, 为内部和外部通信定义了公共的软件通信接口, 增强了汽车控制单元中应用软件模块的可移植性。
Com
模块控制 I-Pdu
数据的接收和发送, 在系统网络状态激活以后可由 BswM
或 CDD
模块调用 Com
提供的 Com_IpduGroupControl
服务函数控制 I-PduGroup
是否需要激活, 只有在 I-PduGroup
的状态为激活 状态时, 对应的 I-Pdu
才能进行数据的接收和发送。
通信传输控制主要实现以下功能点:
I-Pdu
按照不同的功能或者不同的通道划分到不同的 I-PduGroup
中, 在启动 I-PduGroup
时对应该组内的所有 I-Pdu
才能进行数据的接收和发送。Com_IpduGroupControl
服务函数将信号缓存数据设置为初始值。Com_SetIpduGroup
服务函数控制单个 I-PduGroup
的激活状态。Com_ClearIpduGroupVector
服务函数将所有的 I-PduGroup
状态设置为未激活状态, 停止报文的接收和发送处理。communication
自上到下,数据的传递过程是:
ASW
–>RTE
–>COM
–>PDUR
–>CANTP
–>CAN Interface
–>CAN Driver
–>CAN controller
–>CAN transceiver
–>CAN BUS Line
Com
模块获取应用层的信号(Signal
),经一定处理封装为 IPDU
(Interaction Layer Protocol Data Unit
)发送到 PduR
模块;
PduR
根据路由协议中所指定的 I-PDU
目标接收模块,将接收到的 I-PDU
经一定处理后发送给 CanIf
;PduR
也可以将部分I-PDU
发送给 CAN TP
模块,处理之后再发送给 CANIf
;
CanIf
将信号以 L-PDU
(Data Link Layer Protocol Data Unit
)的形式发送给 CAN
驱动模块;
CAN
驱动模块将 Message
报文发送给 CAN controller
;
CAN controller
与外部硬件的 CAN transceiver
(CAN
收发器) 进行 CAN
报文的收发;
外部硬件 CAN
收发器– CAN Transceiver Hardware
主要工作内容为,接收 CAN bus
上的网络信息(通常叫做 CAN Frame
)相关的信号电平并将其转化为逻辑信息电平转发给CAN Controller
, 接收从CAN Controller
传输过来的逻辑电平信息并将其转化为信号电平传从到 CAN bus
上。CAN Transceiver
有两条线,一条连CAN
总线的高电平,一条低电平;
以 NeuSar
为例,梳理 signal
更新发送流程:
NeuSar
中,每一个 signal
都有一个 buffer
用来存储数据Rte_Write_XXX_XXX
更新 RTE
Signal
的全局变量,并调用 Com
层接口Com_SendSignal(SignalId, SignalDataPtr)
-> Com_SendSignal_Process(SignalId, SignalDataPtr)
; 将需要发送的信号值,保存到相应 signal
的 buffer
中task
中周期调用 Com_MainFunctionTx(void)
-> Com_PduTxProcess(com_astPdu)
,在 Com_PduTxProcess
中根据 PDU
的发送触发方式,进行相应处理Com_PduPeriodicTxProcess(PduInfo, PduCycle)
-> Com_PduCycleSend(PduInfo, PduCycle)
-> Com_OnePduSend(PduInfo)
-> Com_PduTxSetVal(PduInfo)
,调用 Com_PduTxSetVal ( PduInfo )
把信号值放入 PDU
中(Com_TxPduInfo[txSigInfoPtr->acPduId].dataraw
这个指针指向存储 PDU
数据的地址)PduR_ComTransmit(PduId, PduInfo)
-> PduR_UpTransmit(PduId, PduInfo)
-> PduR_Route_LoTransmit(dstPduPtr, pduInfoPtr)
,在调用 PduR_Route_LoTransmit
中,根据路由通道不同,可以选择 CanIf
或者 CanTp
两种方式。CanTp
为例:CanTp_Transmit(CanTpTxSduId, CanTpTxInfoPtr)
-> CanTp_Transmit_WithData(CanTpTxSduId, CanTpTxInfoPtr, ErrorId)
, 在 CanTp_Transmit_WithData
函数中,将 I-PDU
数据封装成 N-PDU
数据(增加 帧类型、长度、目的地址等信息)CanTp_TxStateTask(CanTpTxSduId, TRUE:代表使用数据)
, 调用 CanTp_TxStateTask
发送数据,根据 CAN
类型不同,选择 Can 2.0
或者 CanFd
,继续封装 N-PDU
信息CanIf_Transmit(CanIfTxSduId, CanIfTxInfoPtr)
-> CanIf_Transmit_Process(txPduPtr, pduInfoPtr)
-> CanIf_TxQueueFilling(txPduPtr, pduInfoPtr, sduLen, canId)
,在 CanIf_TxQueueFilling
中将待发送的数据写入 Can Driver
的数据缓冲区内Can Driver
成功发送报文,通过 CanIf_TxConfirmation
函数回调通知 CanIf
CanIf
通过调用 PduR_CanIfTxConfirmation -> PduR_LoTxConfirmation
回调通知 PduR
发送成功PduR
调用 PduR_Route_UpTxConfirmation -> Com_TxConfirmation
通知 Com
层发送成功Com
通过发送消息确认来调用 Com_TxPduClearUb_Process
清除更新位。如果该 signal
绑定了回调函数,则执行回调函数,执行相关操作Update Bit
为 Com
信号或信号组数据更新位, 在通信矩阵中以一个信号形式存在, 占用 1 个 bit
, 当信号数据发送时将 Update Bit
值设置为 1, 发送完成后将 Update Bit
设置为 0。
UpdateBit
作为判断信号或信号组数据是否被更新的标志,可通过配置项 ComUpdateBitPosition
进行配置 UpdateBit
在该 I-Pdu
所在的位置,用户在调用 Com
提供的发送服务接口函数时将信号对应的 Update Bit
设置为更新状态。
信号对应 UpdateBit
的清除, 根据该信号所在的 I-Pdu 配置项 ComTxIPduClearUpdateBit
配置的清除方式进行清除。
UpdateBit
的清除方式如下:
Confirmation
: 在 Com
模块调用 PduR
提供的 I-Pdu
发送服务接口函数 PduR_ComTransmit
时, 且收到发送完成确认(Com_TxConfirmation
) 后进行清除。Transmit
: 在 Com
模块调用 PduR
提供的 I-Pdu
发送服务接口函数 PduR_ComTransmit 时, 且发送成功后进行清除。TriggerTransmit
: PduR
模块调用 Com
提供的回调函数 Com_TriggerTransmit, 在调用成功后进行清除。Com
发送信号的超时监控, 用于监控信号是否在配置的超时时间内发送完成。 在一个 I-Pdu
内的所有信号如果配置不同的超时监控时间, 则根据该 I-Pdu
内信号配置的最小超时时间进行计算。
I-Pdu
的超时监控在调用 PduR
发送数据服务接口函数时启动, 在接收到发送完成确认后该周期的 I-Pdu
发送超时监控结束, 如果 Com
监控到 I-Pdu
发送超时, 可根据信号配置的 ComTimeoutNotification
回调函数将超时状态通知给 Rte
层。
Com
模块可通过 ComTransferProperty
配置项配置发送模式, 详细模式配置如下:
发送模块 | PERIODIC(周期) | DIRECT(触发) | MIXED |
---|---|---|---|
PENDING | 当用户请求信号的发送时, 不会立即触发对应的 I-Pdu 发送, 只能根据 I-Pdu 配置的发送周期进行周期性发送。 | ||
TRIGGERED | I-Pdu 进 行 周 期发送 | 在信号有发送请求时, I-Pdu 会触发发送一次。 如果ComTxModeNumberOfRepetitions配置了重复发送次数, 且配置ComTxModeRepetitionPerio 重复发送周期, 则进行周期触发发送 | I-Pdu 进行周期和触发发送 |
TRIGGERED_WITHOUT_REPETITION | I-Pdu 进 行 周 期发送 | I-Pdu 只会触发发送一次 | I-Pdu 触发发送一次,然后继续按照周期进行发送 |
TRIGGERED_ON_CHANGE | I-Pdu 进 行 周 期发送 | 当信号数据与上次发送的信号数据的值或长度不同时, 触发发送一次。 如果 ComTxModeNumberOfRepetitions 配置了重复发送次数, 且配置ComTxModeRepetitionPerio 重复发送周期, 则进行周期触发发送 | I-Pdu 进行周期和触发发送 |
TRIGGERED_ON_CHANGE_WITHOUT_REPETITION | I-Pdu 进 行 周 期发送 | 当信号数据与上次发送的信号值或长度不同时, 触发发送一次 | I-Pdu 进行周期和触发发送 |
时序图较大,查看时可以在图片上右键选择 “在新标签页中打开图片”
以 NeuSar
为例,梳理 signal
接收流程:
Can
驱动模块接收到报文会调用接口 CanIf_RxIndication
通知 CanIf
模块CanIf
的 CAN Rx LPDU
,调用 CanIf_RxIndication_Process
对 PDU
进行解析CanIf
调用 PduR_CanIfRxIndication
-> PduR_LoRxIndication
回调函数,将数据上传到 PduR
PduR_Route_UpRxIndication
,表示收到下层通信接口模块的 I-PDU
。即,当 PduR_RxIndication
被调用时,PDU Router
模块将为每个目的上层模块调用 _RxIndication
Com_RxIndication
,通知 Com
,表示收到下层通信接口模块的 I-PDU
。Com_RxIndicationProcess
处理 I-PDU
数据Com_RxSignalAnalysis_Process
解析信号,调用 Com_RxSigRead_Normal
获取解析出来的 Signal
值,再根据数据类型调用 Com_RxSigUbInvFilterProcessI8
或其他对应函数将接收到的数据存储在 Com_RxSignalInfo[sigIdx].sigRTEValue
中Com_RxSigNotification_Handle
回调函数,通知 RTE
接收完成,更新 RTE 层的 全局变量RTE
接口调用 Rte_Read_XXX_XXX
函数,内部再调用 Com_ReceiveSignal
-> Com_ReceiveSignal_Process
,将存储在 RX Buff
中 Signal
值赋给 RTE
中的全局变量如果接收的信号或者信号组配置有对应的 UpdateBit
数据更新位, Com
先解析对应 UpdedateBit
对应的信号数据, 如果 UpdedateBit
为 1, 代表对应的信号数据有更新并进行解析。
配置 COM
模块,需要导入 DBC
文件
一般来说,一个 DBC
文件中含有多个 Node
;一个 PDU
相当于一个 message
,而 COM
模块由多少个 PDU
,与导入 DBC
时选择的 Main Node
有关。
该 Node Tx Messages
有10个,Rx Messages
有2个,所以
extern CONST(COM_TxPduInfo_st, COM_CONFIG_DATA) Com_TxPduInfo[COM_TXPDU_NUM]; // COM_TXPDU_NUM = 10
extern CONST(COM_RxPduInfo_st, COM_CONFIG_DATA) Com_RxPduInfo[COM_RXPDU_NUM]; // COM_RXPDU_NUM = 10
在 Node
下,Tx Messages
共有 29 个 signal
,Rx Messages
共有 4 个 signal
,所以
extern CONST(COM_TxSignalInfo_st, COM_CONFIG_DATA) Com_TxSignalInfo[COM_TXSIG_NUM]; // COM_TXSIG_NUM = 29
extern CONST(COM_RxSignalInfo_st, COM_CONFIG_DATA) Com_RxSignalInfo[COM_RXSIG_NUM]; // COM_RXSIG_NUM = 4
Com
模块控制 I-Pdu
数据的接收和发送, 在系统网络状态激活以后可由 BswM
或 CDD
模块调用 Com
提供的 Com_IpduGroupControl
服务函数控制 I-PduGroup
是否需要激活, 只有在 I-PduGroup
的状态为激活状态时, 对应的 I-Pdu
才能进行数据的接收和发送。
多个 Signal
可以组成一个 Signal Group
。一个 Signal Group
中只能包含同一消息中的 Signal
。
从下面可以看出,信号组和普通信号的图标不同
下面问答参考:https://www.elecfans.com/d/1936426.html
AUTOSAR
概念,AUTOSAR COM
提供了信号组的解决方案。AUTOSAR COM
模块一致地发送和接收信号组,为复杂数据类型提供必要的一致性。通俗的来讲,Signal Group
就是一个IPDU
里面的几个Signal
的集合,这几个Signal
的操作需要保持一致性(也就是如果外部发送方有对这几个数据中一个或多个数据有改动,那么接收方也需要同时更新,比如车道线的一阶参数、二阶参数、三阶参数、常数项是4个不同的Signal
,这4个Signal
就需要保持一致性,不然到最后仪表上画出来的车道线就会偶发的和实际不一样)。COM
模块为每个Rx Signal
和Rx Signal
都设有一个Signal Buffer
的,Signal
数据的收发都通过这个Signal
来实现。如果Signal Group
,COM
模块为每个Signal Group
又额外设置了一片Signal Group Buffer
,这片Buffer
就是所谓的Shadow buffer
。在发送Signal Group
的时候,将Signal Group
拷贝到IPDU Buffer
的时候是原子操作(也就是拷贝前关闭全局中断,拷贝后打开全局中断,保证拷贝过程不被中断干扰)保证了Signal Group
数据的一致性。Shadow buffer
中获取。COM_TXGRP_NUM
、COM_RXGRP_NUM
分别表示发送和接收信号组的个数
extern CONST(COM_TxSigGrpInfo_st, COM_CONFIG_DATA) Com_TxSigGrpInfo[COM_TXGRP_NUM + 1U];
extern CONST(COM_RxSigGrpInfo_st, COM_CONFIG_DATA) Com_RxSigGrpInfo[COM_RXGRP_NUM + 1U];
更多参考:https://blog.csdn.net/initiallizer/article/details/130040286
L-PDU
:对应链路层的PDU
,一般来说,我们称接口层(Interface,XX_If)为链路层,比如:CanIf、FlexrayIf等。更确切地说是 Driver和Interface
构成链路层。
N-PDU
:网络层对应的 PDU
,一般来说,我们称传输层(Transport,XX_Tp)为网络层,比如:CanTp、FlexrayTp等。
I-PDU
:交互层(表示层)对应的 PDU
。
XX_If
以上模块的信息交互依赖 I-PDU
,XX_If
与 XX_Tp
模块的交互依赖 N-PDU
。
一般来说,小数据传输时,用XX_If
;大数据传输时,用XX_Tp
。所以,在诊断的多帧传输时,XX_Tp
层会将多个N-PDU
缓存,直到一个完整的I-PDU
接收完,之后通过 PduR
送给DCM
,即:I-PDU = n * N-PDU
(n是大于1的正整数)。