AUTOSAR进阶图解==>AUTOSAR_SWS_COMManager
AUTOSAR 通信管理器(ComM)详解
目录
- 1. 通信管理器(ComM)概述
- 2. ComM架构设计
- 3. ComM状态机
- 4. ComM配置结构
- 5. ComM用户接口
- 6. ComM部分网络管理
- 7. 总结
1. 通信管理器(ComM)概述
通信管理器(ComM)是AUTOSAR标准中的关键模块,用于协调和管理汽车ECU中的通信需求。它作为应用层与网络底层之间的抽象层,提供了统一的通信请求和管理接口。
1.1 主要职责
通信管理器(ComM)主要负责:
- 通信模式管理:管理ECU间的通信模式(如全通信、无通信或部分通信)
- 通信请求处理:处理来自应用层的通信需求
- 网络唤醒和休眠:协调网络的唤醒和休眠行为
- 部分网络管理:支持部分网络簇(PNC)功能,实现节能控制
通过ComM,AUTOSAR应用可以请求或释放通信资源,而无需了解底层网络的实现细节,从而提高了软件的可复用性和解耦性。
2. ComM架构设计
2.1 架构层次划分
通信管理器架构图清晰地展示了ComM在AUTOSAR软件架构中的位置和与其他模块的关系:
-
应用层
- 应用模块通过ComM提供的API接口请求和释放通信服务
- 应用不直接与底层网络通信模块交互,确保了抽象和解耦
-
服务层
- 通信管理器(ComM):核心组件,管理通信模式和处理请求
- 诊断通信管理器(DCM):与ComM交互以支持诊断通信
- ECU状态管理器(EcuM):向ComM通知ECU状态变化
- 基础软件模式管理器(BswM):处理模式切换请求
-
网络抽象层
- 网络管理(Nm):处理网络层面的管理任务,包括CanNm、FrNm和EthNm
- 总线状态管理器(BusSM):管理特定总线类型的状态,包括CanSM、FrSM和EthSM
- 通信栈:底层通信驱动程序
2.2 模块间接口
ComM与周围模块的交互通过标准化接口实现:
-
向上接口
- 应用层模块调用
ComM_RequestComMode()
、ComM_ReleaseComMode()
等API - ComM通过回调函数通知应用层通信状态变化
- 应用层模块调用
-
向下接口
- ComM调用Nm模块的函数,如
Nm_NetworkRequest()
、Nm_NetworkRelease()
- ComM调用BusSM模块的函数,如
BusSM_RequestComMode()
- ComM调用Nm模块的函数,如
-
水平接口
- ComM与DCM交互,支持诊断通信需求
- ComM向EcuM和BswM提供状态通知和模式切换请求
2.3 代码示例:ComM初始化
/* ComM模块初始化函数 */
void ComM_Init(const ComM_ConfigType* ConfigPtr)
{uint8 channelIndex;/* 检查配置指针 */if (ConfigPtr == NULL_PTR) {/* 使用链接时配置 */ConfigPtr = &ComM_Config;}/* 保存配置指针 */ComM_ConfigPtr = ConfigPtr;/* 初始化所有通信通道 */for (channelIndex = 0; channelIndex < ComM_ConfigPtr->ComMChannelCount; channelIndex++) {/* 设置初始通信模式为NO_COM */ComM_ChannelState[channelIndex] = COMM_NO_COM_NO_PENDING_REQUEST;/* 初始化通道状态变量 */ComM_UserRequestMode[channelIndex] = COMM_NO_COMMUNICATION;ComM_NmStateChangeNotification[channelIndex] = FALSE;/* 通知总线状态管理器初始模式 */BusSM_ModeIndication(channelIndex, COMM_NO_COMMUNICATION);}/* 设置模块状态为初始化完成 */ComM_ModuleStatus = COMM_READY;
}
3. ComM状态机
3.1 状态定义
通信管理器实现了一个状态机,管理ComM通道的不同通信状态:
-
NO_COM_NO_PENDING_REQUEST
- 描述:通信未激活,且无等待的通信请求
- 特点:低功耗模式,通信总线完全关闭
- 进入条件:ECU初始化完成或所有通信请求都已释放
-
NO_COM_REQUEST_PENDING
- 描述:通信未激活,但存在等待处理的请求
- 特点:系统正在尝试激活通信,但尚未建立
- 进入条件:应用请求通信,但网络尚未准备好
-
FULL_COM_NETWORK_REQUESTED
- 描述:通信已完全激活,网络处于活动状态
- 特点:全功能通信模式,所有通信功能可用
- 进入条件:网络已建立,响应用户通信请求
-
FULL_COM_READY_SLEEP
- 描述:通信仍然激活,但已准备好进入休眠
- 特点:通信仍可用,但系统准备关闭不必要的通信
- 进入条件:所有用户都释放了通信请求
-
SILENT_COM
- 描述:选择性唤醒模式,总线保持监听状态
- 特点:低功耗但可被唤醒,用于部分网络功能
- 进入条件:进入选择性唤醒模式的网络请求
3.2 状态转换
状态转换由以下触发条件控制:
- 用户请求通信:当应用层请求通信时,触发状态从NO_COM向FULL_COM过渡
- 网络激活: 当网络层报告通信已建立,状态从REQUEST_PENDING转为FULL_COM
- 用户释放通信:所有用户释放通信后,系统准备进入低功耗模式
- 网络管理信号:NM模块的睡眠指示会触发状态转换到NO_COM
- 唤醒信号:在部分网络功能中,唤醒信号会激活SILENT_COM状态下的通信
3.3 代码示例:状态处理
/* ComM状态处理函数 */
void ComM_MainFunction(void)
{uint8 channelIndex;ComM_ModeType currentMode, targetMode;/* 检查模块是否已初始化 */if (ComM_ModuleStatus != COMM_READY) {return;}/* 处理所有通信通道 */for (channelIndex = 0; channelIndex < ComM_ConfigPtr->ComMChannelCount; channelIndex++) {/* 获取当前状态 */ComM_GetCurrentComMode(channelIndex, ¤tMode);/* 状态机处理逻辑 */switch (ComM_ChannelState[channelIndex]) {case COMM_NO_COM_NO_PENDING_REQUEST:/* 检查是否有新的通信请求 */if (ComM_UserRequestMode[channelIndex] == COMM_FULL_COMMUNICATION) {/* 转换到请求等待状态 */ComM_ChannelState[channelIndex] = COMM_NO_COM_REQUEST_PENDING;/* 请求网络管理激活网络 */BusSM_RequestComMode(channelIndex, COMM_FULL_COMMUNICATION);}break;case COMM_NO_COM_REQUEST_PENDING:/* 检查网络是否已激活 */if (ComM_NmStateChangeNotification[channelIndex] == TRUE) {/* 网络已激活,转换到全通信状态 */ComM_ChannelState[channelIndex] = COMM_FULL_COM_NETWORK_REQUESTED;/* 重置通知标志 */ComM_NmStateChangeNotification[channelIndex] = FALSE;/* 通知用户模式变化 */ComM_CurrentModeIndication(channelIndex, COMM_FULL_COMMUNICATION);}/* 检查请求是否超时或取消 */else if (ComM_UserRequestMode[channelIndex] != COMM_FULL_COMMUNICATION) {/* 返回到初始状态 */ComM_ChannelState[channelIndex] = COMM_NO_COM_NO_PENDING_REQUEST;BusSM_RequestComMode(channelIndex, COMM_NO_COMMUNICATION);}break;/* 其他状态处理... */}}
}
4. ComM配置结构
4.1 配置容器层次
通信管理器的配置结构遵循AUTOSAR标准的容器模型:
-
ComM(根容器)
- 包含所有通信管理器的配置参数和子容器
- 每个ECU的ComM只有一个ComM根容器实例
-
ComMGeneral
- 包含影响整个ComM模块行为的全局参数
- 定义了开发错误检测、版本信息API等总体功能开关
-
ComMChannel
- 定义单个通信通道的配置
- 一个ECU可以有多个通道(CAN、FlexRay或以太网)
- 每个通道与特定总线类型和网络管理变体关联
-
ComMUser
- 定义可以请求通信服务的用户
- 每个用户可以关联到一个或多个通信通道
- 用户通常对应于应用模块或软件组件
-
ComMPnc
- 部分网络簇配置,仅在支持部分网络时使用
- 定义特定功能分组所需的通信设置
4.2 关键配置参数
-
ComMGeneral 关键参数
ComMDevErrorDetect
:开启/关闭开发错误检测ComMVersionInfoApi
:开启/关闭版本信息APIComMPncSupport
:开启/关闭部分网络支持ComMMainFunctionPeriod
:主函数周期(毫秒)
-
ComMChannel 关键参数
ComMChannelId
:通道唯一标识符ComMBusType
:总线类型(CAN、FlexRay、以太网等)ComMNmVariant
:网络管理变体(NONE、LIGHT、PASSIVE、FULL)ComMUserIdList
:可访问该通道的用户ID列表
-
ComMUser 关键参数
ComMUserId
:用户唯一标识符ComMChannelList
:用户可访问的通道列表
-
ComMPnc 关键参数
ComMPncId
:部分网络簇标识符ComMPncPrepareSleepTimer
:准备睡眠计时器(毫秒)ComMEcuGroupClassification
:ECU分组分类(协调器/跟随者)
4.3 代码示例:配置结构定义
/* ComM模块配置结构定义 *//* 总线类型枚举 */
typedef enum {COMM_BUS_TYPE_CAN, /* CAN总线 */COMM_BUS_TYPE_FR, /* FlexRay总线 */COMM_BUS_TYPE_ETH, /* 以太网总线 */COMM_BUS_TYPE_LIN /* LIN总线 */
} ComM_BusTypeType;/* 网络管理变体枚举 */
typedef enum {COMM_NM_VARIANT_NONE, /* 无网络管理 */COMM_NM_VARIANT_LIGHT, /* 轻量级网络管理 */COMM_NM_VARIANT_PASSIVE, /* 被动网络管理 */COMM_NM_VARIANT_FULL /* 完整网络管理 */
} ComM_NmVariantType;/* 通信模式枚举 */
typedef enum {COMM_NO_COMMUNICATION, /* 无通信模式 */COMM_SILENT_COMMUNICATION, /* 静默通信模式 */COMM_FULL_COMMUNICATION /* 完全通信模式 */
} ComM_ModeType;/* 部分网络配置 */
typedef struct {uint8 ComMPncId; /* PNC ID (0-255) */float32 ComMPncPrepareSleepTimer; /* PNC睡眠准备定时器值(毫秒) */boolean ComMPncZeroConfirmationRequired; /* 是否需要零确认 */uint8 ComMPncGatewayType; /* 网关类型(NONE/ACTIVE/PASSIVE) */uint8 ComMEcuGroupClassification; /* ECU组分类(NONE/COORDINATOR/FOLLOWER) */uint8 ComMChannelCount; /* 关联通道数量 */uint8 *ComMChannelList; /* 关联通道列表 */
} ComM_PncConfigType;/* 用户配置 */
typedef struct {uint8 ComMUserId; /* 用户ID (0-255) */uint8 ComMChannelCount; /* 关联通道数量 */uint8 *ComMChannelList; /* 关联通道列表 */
} ComM_UserConfigType;/* 通道配置 */
typedef struct {uint8 ComMChannelId; /* 通道ID (0-255) */ComM_BusTypeType ComMBusType; /* 总线类型 */ComM_NmVariantType ComMNmVariant; /* NM变体 */uint8 ComMNmChannelHandle; /* NM通道句柄 */float32 ComMMainFunctionPeriod; /* 主函数周期(毫秒) */uint8 ComMUserCount; /* 用户数量 */uint8 *ComMUserIdList; /* 用户ID列表 */uint8 ComMPncCount; /* PNC数量 */uint8 *ComMPncIdList; /* PNC ID列表 */
} ComM_ChannelConfigType;/* 常规配置 */
typedef struct {boolean ComMDevErrorDetect; /* 开发错误检测开关 */boolean ComMVersionInfoApi; /* 版本信息API开关 */boolean ComMPncSupport; /* PNC支持开关 */float32 ComMMainFunctionPeriod; /* 主函数周期(毫秒) */uint8 ComMUserSizeOfType; /* 用户ID类型大小 */uint8 ComMChannelSizeOfType; /* 通道ID类型大小 */uint8 ComMPncIdSizeOfType; /* PNC ID类型大小 */uint8 ComMModeRequestRepetitionMax; /* 模式请求最大重复次数 */
} ComM_GeneralType;/* ComM模块总配置 */
typedef struct {ComM_GeneralType ComMGeneral; /* 常规配置 */uint8 ComMChannelCount; /* 通道数量 */ComM_ChannelConfigType *ComMChannel; /* 通道配置 */uint8 ComMUserCount; /* 用户数量 */ComM_UserConfigType *ComMUser; /* 用户配置 */uint8 ComMPncCount; /* PNC数量 */ComM_PncConfigType *ComMPnc; /* PNC配置 */
} ComM_ConfigType;
5. ComM用户接口
5.1 交互流程分析
序列图展示了ComM模块与应用层、网络管理层和总线管理层之间的交互流程:
-
初始化阶段
- 应用层调用
ComM_Init()
初始化ComM模块 - ComM初始化内部状态并通知总线状态管理器初始模式
- 应用层调用
-
通信请求阶段
- 应用层调用
ComM_RequestComMode()
请求通信 - ComM更新用户请求状态并向BusSM请求通信模式
- BusSM激活通信栈并通知网络管理层进行网络请求
- 网络初始化和通信建立后,Nm通知ComM网络已启动
- ComM通知应用层通信模式已变更为全通信
- 应用层调用
-
通信释放阶段
- 应用层调用
ComM_ReleaseComMode()
释放通信 - 如果所有用户都释放了通信,ComM通知Nm进行网络释放
- BusSM准备关闭通信栈
- 应用层调用
-
通信关闭阶段
- Nm通知ComM准备总线睡眠
- ComM更新通道状态并通知应用层通信模式变更
- Nm发送总线睡眠指示,ComM完全关闭通信
-
状态查询
- 应用层可随时通过
ComM_GetCurrentComMode()
查询当前通信状态
- 应用层可随时通过
5.2 主要API接口
ComM模块提供以下关键API接口:
-
初始化与反初始化
void ComM_Init(const ComM_ConfigType* ConfigPtr)
:初始化ComM模块void ComM_DeInit(void)
:反初始化ComM模块
-
通信模式控制
Std_ReturnType ComM_RequestComMode(uint8 UserId, ComM_ModeType ComMode)
:请求通信模式Std_ReturnType ComM_ReleaseComMode(uint8 UserId, ComM_ModeType ComMode)
:释放通信模式Std_ReturnType ComM_GetCurrentComMode(uint8 UserId, ComM_ModeType* ComMode)
:获取当前通信模式
-
网络管理接口
void ComM_Nm_NetworkStartIndication(NetworkHandleType Channel)
:网络启动指示void ComM_Nm_PrepareBusSleepIndication(NetworkHandleType Channel)
:准备总线睡眠指示void ComM_Nm_BusSleepIndication(NetworkHandleType Channel)
:总线睡眠指示
-
诊断和特殊功能
Std_ReturnType ComM_GetVersionInfo(Std_VersionInfoType* versioninfo)
:获取版本信息Std_ReturnType ComM_CommunicationAllowed(NetworkHandleType Channel, boolean* Allowed)
:检查是否允许通信
5.3 代码示例:请求与释放通信
/* 应用层请求通信示例 */
void Application_StartCommunication(void) {Std_ReturnType result;ComM_ModeType currentMode;/* 请求完全通信 */result = ComM_RequestComMode(APP_USER_ID, COMM_FULL_COMMUNICATION);if (result != E_OK) {/* 错误处理 */App_ReportError(APP_COMM_REQUEST_FAILED);return;}/* 等待通信建立 */do {/* 获取当前模式 */result = ComM_GetCurrentComMode(APP_USER_ID, ¤tMode);if (result != E_OK) {/* 错误处理 */break;}/* 如果未达到全通信模式,稍作等待 */if (currentMode != COMM_FULL_COMMUNICATION) {App_Delay(10); /* 等待10ms */}} while (currentMode != COMM_FULL_COMMUNICATION);/* 通信已建立,可以开始数据交换 */if (currentMode == COMM_FULL_COMMUNICATION) {App_StartDataExchange();}
}/* 应用层释放通信示例 */
void Application_StopCommunication(void) {Std_ReturnType result;/* 先停止数据交换 */App_StopDataExchange();/* 释放通信请求 */result = ComM_ReleaseComMode(APP_USER_ID, COMM_FULL_COMMUNICATION);if (result != E_OK) {/* 错误处理 */App_ReportError(APP_COMM_RELEASE_FAILED);}
}
6. ComM部分网络管理
6.1 部分网络概念
部分网络(Partial Network)是AUTOSAR引入的节能技术,允许ECU在不需要全部功能时进入低功耗模式,但仍能响应特定唤醒请求:
-
部分网络簇(PNC)
- 定义为具有相关功能的ECU逻辑分组
- 可以独立于其他功能进行唤醒和休眠
- 通过配置确定哪些ECU属于特定PNC
-
PNC角色分类
- 协调器(Coordinator):负责控制PNC状态,发送唤醒/睡眠信号
- 跟随者(Follower):根据协调器信号改变自身状态
-
唤醒机制
- 通过网络管理帧中的特定位(唤醒位)传递唤醒信号
- ECU在休眠状态仍能监听唤醒请求
- 仅当相关PNC被请求时才唤醒特定ECU
6.2 部分网络架构
图中展示了部分网络管理的整体架构:
-
整车网络层次
- ECU 1作为协调器,控制多个PNC
- ECU 2和ECU 3分别属于不同的PNC,作为跟随者
- ECU 4不支持部分网络功能
-
ECU内部结构
-
ECU 1(协调器)内部:
- 应用层通过ComM请求/释放特定PNC
- ComM控制多个PNC管理模块
- PNC管理模块通过Nm设置唤醒位
-
ECU 2(跟随者)内部:
- ComM监控PNC接收器状态
- 接收器检测到唤醒信号时通知Nm
-
6.3 PNC状态管理
部分网络簇(PNC)具有自己的状态管理逻辑:
-
PNC状态
- PNC_REQUESTED:PNC被请求,协调器发送唤醒位
- PNC_READY_SLEEP:所有用户释放PNC,准备休眠
- PNC_NO_COMMUNICATION:PNC处于休眠状态
-
状态转换
- 当应用请求PNC时,状态变为REQUESTED
- 应用释放PNC后,启动准备睡眠定时器
- 定时器到期且无新请求,状态变为NO_COMMUNICATION
6.4 代码示例:PNC管理
/* PNC管理相关代码示例 *//* PNC请求函数 */
Std_ReturnType ComM_RequestPnc(uint8 UserId, uint8 PncId)
{uint8 pncIndex;boolean pncFound = FALSE;/* 检查模块是否已初始化 */if (ComM_ModuleStatus != COMM_READY) {return E_NOT_OK;}/* 检查用户ID有效性 */if (UserId >= ComM_ConfigPtr->ComMUserCount) {COMM_DET_REPORT_ERROR(COMM_API_ID_REQUEST_PNC, COMM_E_WRONG_PARAMETERS);return E_NOT_OK;}/* 查找PNC索引 */for (pncIndex = 0; pncIndex < ComM_ConfigPtr->ComMPncCount; pncIndex++) {if (ComM_ConfigPtr->ComMPnc[pncIndex].ComMPncId == PncId) {pncFound = TRUE;break;}}/* PNC ID无效 */if (pncFound == FALSE) {COMM_DET_REPORT_ERROR(COMM_API_ID_REQUEST_PNC, COMM_E_WRONG_PARAMETERS);return E_NOT_OK;}/* 标记用户请求 */ComM_PncUserRequestMode[pncIndex][UserId] = COMM_PNC_REQUESTED;/* 更新PNC状态 */ComM_UpdatePncState(pncIndex);return E_OK;
}/* PNC释放函数 */
Std_ReturnType ComM_ReleasePnc(uint8 UserId, uint8 PncId)
{uint8 pncIndex;boolean pncFound = FALSE;/* 检查模块是否已初始化 */if (ComM_ModuleStatus != COMM_READY) {return E_NOT_OK;}/* 查找PNC索引 */for (pncIndex = 0; pncIndex < ComM_ConfigPtr->ComMPncCount; pncIndex++) {if (ComM_ConfigPtr->ComMPnc[pncIndex].ComMPncId == PncId) {pncFound = TRUE;break;}}/* PNC ID无效 */if (pncFound == FALSE) {COMM_DET_REPORT_ERROR(COMM_API_ID_RELEASE_PNC, COMM_E_WRONG_PARAMETERS);return E_NOT_OK;}/* 标记用户释放 */ComM_PncUserRequestMode[pncIndex][UserId] = COMM_PNC_NO_COMMUNICATION;/* 更新PNC状态 */ComM_UpdatePncState(pncIndex);return E_OK;
}/* PNC状态更新处理 */
void ComM_UpdatePncState(uint8 PncIndex)
{uint8 userId;boolean pncRequested = FALSE;uint8 channelIndex, nmChannel;/* 检查任何用户是否请求PNC */for (userId = 0; userId < ComM_ConfigPtr->ComMUserCount; userId++) {if (ComM_PncUserRequestMode[PncIndex][userId] == COMM_PNC_REQUESTED) {pncRequested = TRUE;break;}}/* 根据请求状态更新PNC状态 */if (pncRequested == TRUE) {/* 如果PNC当前不是请求状态 */if (ComM_PncState[PncIndex] != COMM_PNC_REQUESTED) {ComM_PncState[PncIndex] = COMM_PNC_REQUESTED;/* 设置PNC唤醒位 */for (channelIndex = 0; channelIndex < ComM_ConfigPtr->ComMPnc[PncIndex].ComMChannelCount; channelIndex++) {nmChannel = ComM_ConfigPtr->ComMPnc[PncIndex].ComMChannelList[channelIndex];/* 只在协调器ECU上设置唤醒位 */if (ComM_ConfigPtr->ComMPnc[PncIndex].ComMEcuGroupClassification == COMM_ECU_GROUP_COORDINATOR) {Nm_SetPncWakeupBit(nmChannel, ComM_ConfigPtr->ComMPnc[PncIndex].ComMPncId);}}}} else {/* 所有用户都释放了PNC */if (ComM_PncState[PncIndex] == COMM_PNC_REQUESTED) {/* 启动准备睡眠定时器 */ComM_PncState[PncIndex] = COMM_PNC_READY_SLEEP;ComM_StartPncPrepareSleepTimer(PncIndex);}}
}
7. 总结
本文详细分析了AUTOSAR通信管理器(ComM)的核心功能、架构设计、状态管理、配置结构和应用接口。通过对ComM的深入了解,可以总结以下几点:
7.1 ComM的核心价值
-
抽象层设计
- ComM作为抽象层,隔离应用与底层网络实现细节
- 提供统一的通信管理接口,简化应用开发
-
状态管理
- 通过状态机实现精细化的通信状态控制
- 确保网络通信按需启动和关闭,优化资源使用
-
节能技术
- 部分网络功能支持ECU选择性唤醒
- 只有需要的功能被激活,提高整车能源效率
7.2 实际应用场景
ComM在现代汽车中的典型应用场景包括:
- 按需启动系统:如信息娱乐系统只在用户请求时激活网络通信
- 诊断通信管理:在维修场景下按需激活诊断通信
- 节能优化:在车辆停止状态下自动关闭不必要的网络通信
- 功能分组:通过PNC实现功能相关ECU的分组管理和唤醒
7.3 设计思考
AUTOSAR ComM模块的设计展示了以下软件工程最佳实践:
- 单一职责原则:ComM专注于通信管理,不涉及具体通信实现
- 层次化设计:清晰的层次结构使责任边界明确
- 状态驱动架构:使用状态机管理复杂的行为逻辑
- 配置驱动开发:通过配置适应不同的硬件平台和应用需求
通信管理器作为AUTOSAR架构的关键组件,展示了汽车软件设计中模块化、可配置和分层架构的重要性。通过合理使用ComM提供的功能,可以有效降低汽车电子系统的能耗,同时简化应用软件开发。