AUTOSAR COM 模块详解
目录
- 概述
1.1 基本功能
1.2 架构位置 - COM模块架构
2.1 架构概览
2.2 层次结构
2.3 主要组件 - 配置结构
3.1 配置类图
3.2 配置参数详解 - 状态管理
4.1 状态转换图
4.2 传输模式
4.3 超时监控 - 交互流程
5.1 初始化流程
5.2 信号传输流程
5.3 信号接收流程
5.4 周期性处理 - 总结
1. 概述
AUTOSAR COM(COMmunication)模块是AUTOSAR通信堆栈的核心组件,负责提供信号导向的通信服务。该模块在AUTOSAR分层架构中处于通信服务层,连接运行时环境(RTE)与PDU Router,为软件组件之间的通信提供标准化接口。
1.1 基本功能
COM模块提供以下主要功能:
- 信号封装与提取:将来自RTE的信号打包到I-PDU中,并从接收的I-PDU中提取信号
- 传输模式管理:支持直接、周期和混合等不同的传输模式
- 信号路由:支持信号网关功能,可以将接收的信号路由到待发送的I-PDU中
- 超时监控:监控接收信号是否在预期时间内到达
- 过滤机制:对接收的信号应用过滤条件
- 通知机制:提供不同的通知机制,如更新位和回调函数
- 字节序转换:在不同平台之间进行字节序转换
1.2 架构位置
在AUTOSAR分层架构中,COM模块位于通信服务层,上连接RTE,下连接PDU Router。COM模块为软件组件提供了标准化的通信接口,隐藏了底层通信的复杂性。
2. COM模块架构
2.1 架构概览
COM模块的整体架构设计遵循AUTOSAR分层原则,为应用层和底层通信提供中间抽象。
2.2 层次结构
COM模块架构图中显示了三个主要层次:
-
应用层:
- 包含RTE(运行时环境),作为软件组件与基础软件间的接口
- RTE通过信号接口与COM模块交互,发送和接收信号数据
-
通信服务层:
- 包含COM模块和PDU Router
- COM模块负责信号处理、PDU打包/解包等功能
- PDU Router负责PDU的路由和转发
-
通信抽象层:
- 提供通信硬件抽象,屏蔽底层通信技术细节
- 实现与具体通信总线(如CAN、FlexRay、以太网等)的适配
2.3 主要组件
COM模块内部包含以下主要功能组件:
-
信号管理:
- 功能:管理信号定义、处理信号数据
- 提供接口:接收RTE信号请求,提供信号值
-
I-PDU打包/解包:
- 功能:将信号数据打包成I-PDU,或从I-PDU中解包出信号数据
- 处理信号位置、大小、字节序等属性
-
传输模式管理:
- 支持直接传输、周期传输和混合传输三种模式
- 根据配置决定何时触发I-PDU的传输
-
过滤机制:
- 对接收到的信号应用过滤条件
- 减少不必要的信号处理
-
超时监控:
- 监控接收信号是否在预期时间内到达
- 处理信号超时情况
-
信号网关功能:
- 将接收到的I-PDU中的信号路由到待传输的I-PDU中
- 支持信号组路由
/* COM模块初始化示例代码 */
void Com_Init(const Com_ConfigType* config)
{
/* 参数检查 */
if (config == NULL)
{
/* 报告错误 */
return;
}
/* 初始化内部状态 */
Com_Status = COM_INIT;
/* 初始化I-PDU组状态 */
for (uint16 i = 0; i < COM_IPDU_GROUP_COUNT; i++)
{
Com_IpduGroupStatus[i] = COM_IPDU_GROUP_STOPPED;
}
/* 初始化信号缓冲区 */
for (uint16 i = 0; i < COM_SIGNAL_COUNT; i++)
{
Com_SignalBuffer[i] = config->ComSignalInitValue[i];
}
/* 其他初始化步骤... */
}
3. 配置结构
COM模块的配置结构包括顶层配置容器、I-PDU组、I-PDU、信号和信号组等多个层次的配置对象。
3.1 配置类图
下图展示了COM模块的主要配置结构及其关系:
3.2 配置参数详解
-
Com(顶层配置容器):
ComConfigurationReleaseVersion
:配置版本号,用于版本兼容性检查ComSupportedIPduGroups
:COM模块支持的最大I-PDU组数量ComVersionInfoAPI
:是否支持版本信息API(TRUE/FALSE)ComEnableMDTForCyclicTransmission
:是否为周期传输启用最小延迟时间(MDT)ComRetryFailedTransmitRequests
:是否重试失败的传输请求
-
ComIPduGroup(I-PDU组配置):
ComIPduGroupHandleId
:I-PDU组的唯一标识符
-
ComIPdu(I-PDU通用配置):
ComIPduDirection
:I-PDU方向(SEND/RECEIVE)ComIPduHandleId
:I-PDU的唯一标识符ComIPduSignalProcessing
:信号处理方式(IMMEDIATE/DEFERRED)ComIPduType
:I-PDU类型(NORMAL/TP)ComIPduGroupRef
:I-PDU所属的组引用ComTxIPduClearUpdateBit
:是否在传输确认时清除更新位
-
ComSignal(信号配置):
ComBitPosition
:信号在I-PDU中的起始位置ComBitSize
:信号的位大小ComHandleId
:信号的唯一标识符ComSignalEndianess
:信号的字节序(BIG_ENDIAN/LITTLE_ENDIAN)ComSignalInitValue
:信号的初始值ComSignalType
:信号的数据类型ComTimeoutFactor
:超时因子,用于计算超时时间ComTimeoutNotification
:超时通知回调函数ComTransferProperty
:传输属性ComUpdateBitPosition
:更新位的位置
/* COM模块配置结构定义示例 */
typedef struct {
boolean ComVersionInfoAPI;
boolean ComEnableMDTForCyclicTransmission;
boolean ComRetryFailedTransmitRequests;
uint16 ComSupportedIPduGroups;
/* 其他顶层配置参数... */
} Com_GeneralConfigType;
typedef struct {
uint16 ComIPduGroupHandleId;
/* 其他I-PDU组配置... */
} Com_IPduGroupConfigType;
typedef struct {
uint8 ComIPduDirection; /* SEND/RECEIVE */
uint16 ComIPduHandleId;
uint8 ComIPduSignalProcessing; /* IMMEDIATE/DEFERRED */
uint8 ComIPduType; /* NORMAL/TP */
const Com_IPduGroupConfigType* ComIPduGroupRef[COM_MAX_IPDU_GROUP_REF];
boolean ComTxIPduClearUpdateBit;
/* 其他I-PDU配置... */
} Com_IPduConfigType;
/* 信号配置类型定义 */
typedef struct {
uint16 ComBitPosition;
uint16 ComBitSize;
uint16 ComHandleId;
uint8 ComSignalEndianess; /* BIG_ENDIAN/LITTLE_ENDIAN */
uint32 ComSignalInitValue;
uint8 ComSignalType;
uint8 ComTimeoutFactor;
void (*ComTimeoutNotification)(void);
uint8 ComTransferProperty;
uint16 ComUpdateBitPosition;
/* 其他信号配置... */
} Com_SignalConfigType;
4. 状态管理
4.1 状态转换图
COM模块的状态管理包括模块状态和I-PDU组状态。下图展示了状态转换关系:
4.2 传输模式
COM模块支持三种主要传输模式:
-
周期传输模式:
- 按固定时间间隔周期性发送I-PDU
- 配置参数:周期时间、偏移时间
- 适用场景:需要定期更新的信息,如状态监控
-
直接传输模式:
- 仅在信号值变化时触发传输
- 配置参数:触发条件、重复次数
- 适用场景:事件驱动的信息,如开关状态变化
-
混合传输模式:
- 结合周期和直接传输的特点
- 可配置为在信号变化时立即发送,同时保持周期性发送
- 适用场景:既需要快速响应变化又需要定期确认状态的场合
/* 传输模式处理示例代码 */
void Com_TriggerIPduSend(Com_IPduHandleType PduId)
{
if (Com_IpduConfig[PduId].ComTxModeMode == COM_DIRECT)
{
/* 直接传输模式处理 */
Com_SendIpdu(PduId);
}
else if (Com_IpduConfig[PduId].ComTxModeMode == COM_PERIODIC)
{
/* 周期传输模式不需要在此触发,由主函数处理 */
}
else if (Com_IpduConfig[PduId].ComTxModeMode == COM_MIXED)
{
/* 混合模式,在信号变化时立即发送一次 */
Com_SendIpdu(PduId);
/* 周期部分由主函数处理 */
}
}
4.3 超时监控
COM模块的超时监控机制确保接收信号在预期时间内到达。超时监控包括:
- 超时检测:基于配置的超时因子计算超时时间
- 超时行为:可配置为使用替代值或保持最后接收值
- 超时通知:调用配置的回调函数通知应用层
/* 超时监控处理示例代码 */
void Com_MainFunction_RxTimout(void)
{
for (uint16 i = 0; i < COM_SIGNAL_COUNT; i++)
{
if (Com_SignalConfig[i].ComTimeoutFactor > 0)
{
/* 减少超时计数器 */
if (Com_SignalTimeoutCounter[i] > 0)
{
Com_SignalTimeoutCounter[i]--;
/* 检查是否超时 */
if (Com_SignalTimeoutCounter[i] == 0)
{
/* 处理超时 */
if (Com_SignalConfig[i].ComTimeoutAction == COM_TIMEOUT_ACTION_REPLACE)
{
/* 替换为替代值 */
Com_SignalBuffer[i] = Com_SignalConfig[i].ComTimeoutSubstituteValue;
}
/* 调用超时通知回调 */
if (Com_SignalConfig[i].ComTimeoutNotification != NULL)
{
Com_SignalConfig[i].ComTimeoutNotification();
}
}
}
}
}
}
5. 交互流程
COM模块与RTE、PDU Router和通信驱动等组件有着密切的交互。下图展示了主要的交互序列:
5.1 初始化流程
COM模块的初始化通过Com_Init()
函数完成,主要步骤包括:
- 初始化内部数据结构
- 设置所有I-PDU组为停止状态
- 使用配置的初始值填充所有信号缓冲区
Std_ReturnType Com_Init(const Com_ConfigType* config)
{
/* 检查配置指针 */
if (config == NULL)
{
return E_NOT_OK;
}
/* 保存配置指针 */
Com_Config = config;
/* 初始化模块状态 */
Com_State = COM_INIT;
/* 初始化所有PDU组为停止状态 */
for (uint16 i = 0; i < config->ComMaxIPduGroupsCnt; i++)
{
Com_IPduGroupState[i] = COM_IPDUGROUP_STOPPED;
}
/* 初始化信号缓冲区为初始值 */
for (uint16 i = 0; i < config->ComMaxSignalCnt; i++)
{
Com_SignalBuffer[i] = config->ComSignalInitValue[i];
Com_SignalUpdated[i] = FALSE;
}
return E_OK;
}
5.2 信号传输流程
信号传输流程如下:
- 应用软件组件通过RTE调用写入函数
Rte_Write_<P>_<R>(<Data>)
- RTE调用COM模块的
Com_SendSignal()
函数 - COM模块根据信号配置和传输模式决定是否立即触发I-PDU传输
- 若需要传输,COM模块打包信号并调用
PduR_ComTransmit()
- PDU Router将I-PDU转发到适当的通信驱动
Std_ReturnType Com_SendSignal(Com_SignalIdType SignalId, const void* SignalDataPtr)
{
/* 参数校验 */
if (SignalDataPtr == NULL || SignalId >= Com_Config->ComMaxSignalCnt)
{
return COM_SERVICE_NOT_AVAILABLE;
}
/* 检查模块状态 */
if (Com_State != COM_INIT)
{
return COM_SERVICE_NOT_AVAILABLE;
}
/* 获取信号配置 */
const Com_SignalConfigType* signalConfig = &Com_Config->ComSignalConfig[SignalId];
Com_IPduIdType iPduId = signalConfig->ComIPduHandleId;
/* 检查IPDU组是否启动 */
if (Com_GetIPduGroupStatus(signalConfig->ComIPduGroupRef) == COM_IPDUGROUP_STOPPED)
{
return COM_SERVICE_NOT_AVAILABLE;
}
/* 更新信号值 */
memcpy(&Com_SignalBuffer[SignalId], SignalDataPtr, signalConfig->ComBitSize / 8);
/* 设置更新标志 */
Com_SignalUpdated[SignalId] = TRUE;
/* 检查是否需要设置更新位 */
if (signalConfig->ComUpdateBitPosition != COM_INVALID_UPDATEBIT_POS)
{
Com_SetUpdateBit(iPduId, signalConfig->ComUpdateBitPosition);
}
/* 检查传输模式,决定是否触发传输 */
if (Com_Config->ComIPduConfig[iPduId].ComTxModeMode == COM_DIRECT ||
Com_Config->ComIPduConfig[iPduId].ComTxModeMode == COM_MIXED)
{
/* 触发IPDU传输 */
Com_TriggerIPDUSend(iPduId);
}
return E_OK;
}
5.3 信号接收流程
信号接收流程如下:
- 通信驱动接收到数据并调用PDU Router的接收指示函数
- PDU Router调用COM模块的
Com_RxIndication()
函数 - COM模块从I-PDU中解包信号并应用过滤器
- 对于有效的信号,COM重置超时计数器
- COM模块通知RTE接收到新的信号值
void Com_RxIndication(PduIdType RxPduId, const PduInfoType* PduInfoPtr)
{
/* 参数校验 */
if (PduInfoPtr == NULL || RxPduId >= Com_Config->ComMaxRxIPduCnt)
{
return;
}
/* 检查模块状态 */
if (Com_State != COM_INIT)
{
return;
}
/* 获取IPDU配置 */
const Com_IPduConfigType* ipduConfig = &Com_Config->ComIPduConfig[RxPduId];
/* 检查IPDU组是否启动 */
if (Com_GetIPduGroupStatus(ipduConfig->ComIPduGroupRef) == COM_IPDUGROUP_STOPPED)
{
return;
}
/* 拷贝接收到的数据到PDU缓冲区 */
memcpy(Com_IPduBuffer[RxPduId], PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);
/* 处理IPDU中的所有信号 */
for (uint16 i = 0; i < ipduConfig->ComSignalCount; i++)
{
Com_SignalIdType signalId = ipduConfig->ComSignalRef[i];
const Com_SignalConfigType* signalConfig = &Com_Config->ComSignalConfig[signalId];
/* 从IPDU中提取信号值 */
uint32 signalValue = Com_ExtractSignalFromPdu(RxPduId, signalConfig);
/* 应用信号过滤器 */
if (Com_ApplySignalFilter(signalId, signalValue))
{
/* 更新信号缓冲区 */
Com_SignalBuffer[signalId] = signalValue;
/* 重置超时计数器 */
if (signalConfig->ComTimeoutFactor > 0)
{
Com_SignalTimeoutCounter[signalId] = signalConfig->ComTimeoutFactor;
}
/* 通知RTE */
if (signalConfig->ComNotification != NULL)
{
signalConfig->ComNotification();
}
}
}
}
5.4 周期性处理
COM模块需要周期性执行以下主函数:
-
Com_MainFunctionTx():
- 处理周期性传输任务
- 管理传输模式状态转换
- 触发需要周期传输的I-PDU
-
Com_MainFunctionRx():
- 检查信号超时
- 执行超时动作
- 通知超时事件
void Com_MainFunctionTx(void)
{
/* 检查模块状态 */
if (Com_State != COM_INIT)
{
return;
}
/* 遍历所有发送IPDU */
for (uint16 i = 0; i < Com_Config->ComMaxTxIPduCnt; i++)
{
const Com_IPduConfigType* ipduConfig = &Com_Config->ComIPduConfig[i];
/* 检查IPDU组是否启动 */
if (Com_GetIPduGroupStatus(ipduConfig->ComIPduGroupRef) == COM_IPDUGROUP_STARTED)
{
/* 检查是否为周期传输或混合传输模式 */
if (ipduConfig->ComTxModeMode == COM_PERIODIC ||
ipduConfig->ComTxModeMode == COM_MIXED)
{
/* 减少周期计数器 */
if (Com_TxModeTimePeriodCounter[i] > 0)
{
Com_TxModeTimePeriodCounter[i]--;
/* 检查是否达到发送周期 */
if (Com_TxModeTimePeriodCounter[i] == 0)
{
/* 重新加载计数器 */
Com_TxModeTimePeriodCounter[i] = ipduConfig->ComTxModeTimePeriod;
/* 触发IPDU传输 */
Com_TriggerIPDUSend(i);
}
}
}
}
}
}
6. 总结
AUTOSAR COM模块作为AUTOSAR通信服务层的核心组件,提供了信号层面的通信抽象,使应用软件组件能够便捷地进行数据交换,而无需关注底层通信细节。
主要特点
- 标准化接口:提供统一的API,简化软件组件集成
- 灵活配置:支持多种传输模式和信号属性配置
- 抽象通信:屏蔽底层通信协议差异
- 信号处理:处理信号打包、解包、过滤和超时监控等
- 网关功能:支持信号路由,便于构建复杂的通信拓扑
应用场景
COM模块适用于以下应用场景:
- 车内网络通信:ECU之间的数据交换
- 诊断应用:收集和传输诊断数据
- 多ECU协同功能:需要多个ECU协同工作的功能实现
- 网关功能:不同网络之间的信号路由
通过正确配置和使用COM模块,可以构建灵活、可靠的汽车电子通信系统,满足现代汽车电子架构的需求。