AUTOSAR进阶图解==>AUTOSAR_SWS_BusMirroring
AUTOSAR 总线镜像(Bus Mirroring)详解
目录
- 1. 概述
- 1.1 功能简介
- 1.2 应用场景
- 2. 模块架构
- 2.1 总体架构
- 2.2 组件关系
- 3. 配置结构
- 3.1 主要配置类
- 3.2 源网络配置
- 3.3 目标网络配置
- 4. 状态管理
- 4.1 状态机
- 4.2 状态转换
- 5. 数据流程
- 5.1 初始化流程
- 5.2 数据镜像流程
- 5.3 停用流程
1. 概述
1.1 功能简介
AUTOSAR 总线镜像(Bus Mirroring)模块的主要目的是将内部总线的流量和状态复制到外部总线,以便测试人员能够通过连接到外部总线进行调试和监控。
总线镜像模块提供了一种灵活的机制,允许测试人员通过诊断命令配置监控哪些总线流量,从而实现对ECU内部通信的无干扰监控。通过使用诊断协议确保只有通过安全检查后才能启用镜像功能,有效保障了系统安全性。
在AUTOSAR规范中,"总线(Bus)"和"网络(Network)“被作为同义词使用。虽然在大多数AUTOSAR规范中,“网络"是首选术语,特别是在引用API参数、配置或协议布局时,但由于该模块被称为"总线镜像”,因此在考虑镜像方向时,如"源总线"或"目标总线”,使用的是"总线"一词。
1.2 应用场景
总线镜像模块主要应用于以下场景:
- ECU内部通信调试:在开发和测试阶段,监控ECU内部总线通信,无需侵入式测试
- 网关监控:在网关ECU中,监控多个子网络之间的通信
- 诊断辅助:辅助诊断工具收集总线数据,用于故障诊断
- 系统集成测试:在系统集成测试中,验证多个ECU之间的通信
- 现场问题排查:在生产环境中,通过外部总线监控内部总线状态,帮助排查问题
2. 模块架构
2.1 总体架构
下图展示了AUTOSAR总线镜像模块的总体架构:
架构图展示了总线镜像模块的主要组件及其关系。总线镜像处理包括:
-
Mirror模块:核心组件,负责管理总线镜像功能。主要功能包括:
- 初始化和配置:通过
Mirror_Init()
函数初始化模块 - 源总线的选择和激活:通过
Mirror_StartSourceNetwork()
激活源总线 - 目标总线的切换:通过
Mirror_SwitchDestNetwork()
切换目标总线 - 帧过滤器的控制:通过过滤器相关API控制帧过滤
- 状态监控和错误处理:监控总线状态并处理错误
- 初始化和配置:通过
-
源总线处理:负责从源总线获取数据。包括三种源总线类型:
- CAN源总线:处理CAN总线帧
- LIN源总线:处理LIN总线帧
- FlexRay源总线:处理FlexRay总线帧
源总线处理功能包括:
- 总线激活:启用源总线数据获取
- 帧获取:接收源总线上的帧
- 过滤应用:根据配置的过滤器过滤帧
- 状态获取:监控源总线状态
-
目标总线处理:负责将处理后的数据发送到目标总线。包括四种目标总线类型:
- CAN目标总线:将数据发送到CAN总线
- FlexRay目标总线:将数据发送到FlexRay总线
- IP目标总线:将数据发送到IP网络
- CDD目标总线:将数据发送到自定义设备驱动程序
目标总线处理功能包括:
- 目标帧创建:基于源帧创建目标帧
- 帧排队:管理要发送的帧队列
- 帧传输:将帧发送到目标总线
- 镜像协议处理:根据目标总线类型应用适当的协议
-
过滤器管理:负责管理帧过滤器。包括三种过滤器类型:
- CAN过滤器:用于CAN总线帧过滤
- LIN过滤器:用于LIN总线帧过滤
- FlexRay过滤器:用于FlexRay总线帧过滤
-
状态管理:管理模块的状态
-
协议处理:处理镜像协议
2.2 组件关系
总线镜像模块与其他AUTOSAR组件的关系如下:
-
外部接口:
- Diagnostic:诊断服务,通过诊断命令配置和控制镜像功能
- CanIf:CAN接口,用于与CAN总线交互
- LinIf:LIN接口,用于与LIN总线交互
- FrIf:FlexRay接口,用于与FlexRay总线交互
- PduR:PDU路由器,管理PDU的路由
- SoAd:套接字适配器,用于IP通信
- Cdd:自定义设备驱动程序,用于自定义通信
-
数据流向:
- 源总线 -> Mirror模块 -> 目标总线:数据从源总线流向Mirror模块进行处理,然后发送到目标总线
- Diagnostic -> Mirror模块:诊断命令控制Mirror模块的配置和状态
Mirror模块通过回调函数接收来自源总线的帧,并通过相应的接口函数将帧发送到目标总线。回调函数包括:
Mirror_ReportCanFrame
:报告CAN帧Mirror_ReportLinFrame
:报告LIN帧Mirror_ReportFlexRayFrame
:报告FlexRay帧
/* CAN帧回调示例 */
void Mirror_ReportCanFrame(uint32 CanId, /* CAN标识符 */uint8 Dlc, /* 数据长度 */const uint8* SduPtr, /* 数据指针 */Mirror_TimestampType TimeStamp /* 时间戳 */
)
{/* 应用过滤器 */if (Mirror_ApplyCanFilter(CanId, NetworkId) == TRUE){/* 创建目标帧并发送 */Mirror_CreateDestinationFrame(CanId, Dlc, SduPtr, TimeStamp, NetworkId);}
}
3. 配置结构
3.1 主要配置类
总线镜像模块的配置结构如下图所示:
Mirror_ConfigType 是总线镜像模块的主要配置结构,包含所有需要的配置参数。它是使用Mirror_Init()
函数初始化Mirror模块的参数。主要包含以下配置:
-
MirrorGeneral:通用配置
- DevErrorDetect:开发错误检测,指定是否启用开发错误检测功能(TRUE/FALSE)
- VersionInfoApi:版本信息API,指定是否启用版本信息API(TRUE/FALSE)
- MainFunctionPeriod:主函数周期,指定
Mirror_MainFunction
的调用周期(单位:秒) - DestDataPduId:目标数据PDU ID,用于数据传输的PDU ID
- DestStatusPduId:目标状态PDU ID,用于状态传输的PDU ID
-
MirrorConfigSet:配置集,包含源网络和目标网络的配置
- MirrorSourceNetwork[]:源网络配置,定义哪些网络可以被镜像
- MirrorDestNetwork[]:目标网络配置,定义帧被镜像到哪里
/* Mirror配置结构示例 */
typedef struct {MirrorGeneral MirrorGeneralConfig; /* 通用配置 */MirrorConfigSet MirrorConfigSets[MAX_SETS]; /* 配置集 */
} Mirror_ConfigType;/* 初始化Mirror模块 */
void Mirror_Init(const Mirror_ConfigType* ConfigPtr) {/* 初始化通用配置 */mirrorDevErrorDetect = ConfigPtr->MirrorGeneralConfig.DevErrorDetect;mirrorVersionInfoApi = ConfigPtr->MirrorGeneralConfig.VersionInfoApi;mirrorMainFunctionPeriod = ConfigPtr->MirrorGeneralConfig.MainFunctionPeriod;/* 初始化源网络和目标网络 */for (uint8 i = 0; i < MAX_SETS; i++) {InitSourceNetworks(&ConfigPtr->MirrorConfigSets[i]);InitDestNetworks(&ConfigPtr->MirrorConfigSets[i]);}/* 设置模块状态为已初始化 */mirrorStatus = MIRROR_INITIALIZED;
}
3.2 源网络配置
源网络配置定义了哪些网络可以被镜像,以及如何过滤和处理来自这些网络的帧。包括:
-
MirrorSourceNetwork:源网络基类
- NetworkHandle:网络句柄,用于识别网络
- NetworkId:网络ID,用于标识网络
-
MirrorSourceNetworkCan:CAN源网络配置
- MirrorSourceCanFilter[]:CAN过滤器配置
- MirrorSourceCanId映射[]:CAN ID映射配置
-
MirrorSourceNetworkLin:LIN源网络配置
- MirrorSourceLinFilter[]:LIN过滤器配置
- MirrorSourceLinId映射[]:LIN ID映射配置
-
MirrorSourceNetworkFlexRay:FlexRay源网络配置
- MirrorSourceFlexRayFilter[]:FlexRay过滤器配置
源网络过滤器配置用于控制哪些帧应该被镜像。不同类型的过滤器包括:
-
MirrorSourceCanFilterRange:CAN范围过滤器,基于CAN ID范围过滤
- LowerCanId:最低CAN ID
- UpperCanId:最高CAN ID
-
MirrorSourceCanFilterMask:CAN掩码过滤器,基于CAN ID和掩码过滤
- CanId:CAN ID
- CanIdMask:CAN ID掩码
-
MirrorSourceLinFilterRange:LIN范围过滤器
- LowerLinId:最低LIN ID
- UpperLinId:最高LIN ID
-
MirrorSourceLinFilterMask:LIN掩码过滤器
- LinId:LIN ID
- LinIdMask:LIN ID掩码
-
MirrorSourceFlexRayFilter:FlexRay过滤器
- FlexRayChannelMask:FlexRay通道掩码
- StartSlotId:起始槽位ID
- EndSlotId:结束槽位ID
- BaseCycle:基础周期
- CyclePeriod:周期
- CycleRepetition:重复周期
/* 添加CAN范围过滤器示例 */
Mirror_FilterIdType Mirror_AddCanRangeFilter(Mirror_NetworkIdType NetworkId,Mirror_CanIdType LowerCanId,Mirror_CanIdType UpperCanId
)
{Mirror_FilterIdType filterId = MIRROR_INVALID_FILTER;/* 检查参数 */if (NetworkId >= MIRROR_MAX_NETWORKS || LowerCanId > UpperCanId || UpperCanId > MIRROR_MAX_CAN_ID) {Mirror_ReportDevError(MIRROR_API_ADD_CAN_RANGE_FILTER, MIRROR_E_PARAM);return filterId;}/* 分配新的过滤器ID */filterId = Mirror_AllocateFilterId();if (filterId != MIRROR_INVALID_FILTER) {/* 配置过滤器 */Mirror_ConfigureCanRangeFilter(filterId, NetworkId, LowerCanId, UpperCanId);}return filterId;
}
3.3 目标网络配置
目标网络配置定义了帧被镜像到哪里,以及如何在目标网络上格式化和传输这些帧。包括:
-
MirrorDestNetwork:目标网络基类
- NetworkHandle:网络句柄
- NetworkId:网络ID
-
MirrorDestNetworkCan:CAN目标网络配置
- CanIfTxPduId:CAN接口发送PDU ID
- SerialisationSupport:序列化支持,指定是否支持序列化
- SerialisationTimeout:序列化超时,指定序列化超时时间
- MaxSerializedMessages:最大序列化消息数,指定最大序列化消息数量
-
MirrorDestNetworkFlexRay:FlexRay目标网络配置
- FrIfTxPduId:FlexRay接口发送PDU ID
- FlexRayChannel:FlexRay通道
- FrameId:帧ID
- BaseCycle:基础周期
- CycleRepetition:周期重复
- SerialisationSupport:序列化支持
- MaxSerializedMessages:最大序列化消息数
-
MirrorDestNetworkIp:IP目标网络配置
- SoAdTxPduId:套接字适配器发送PDU ID
- ProtocolVersion:协议版本
- SerialisationSupport:序列化支持
- MaxSerializedMessages:最大序列化消息数
-
MirrorDestNetworkCdd:CDD目标网络配置
- ProtocolVersion:协议版本
- CddTxPduId:CDD发送PDU ID
- SerialisationSupport:序列化支持
- MaxSerializedMessages:最大序列化消息数
/* 切换目标网络示例 */
Std_ReturnType Mirror_SwitchDestNetwork(Mirror_NetworkIdType NetworkId)
{Std_ReturnType result = E_NOT_OK;/* 检查参数 */if (NetworkId >= MIRROR_MAX_NETWORKS) {Mirror_ReportDevError(MIRROR_API_SWITCH_DEST_NETWORK, MIRROR_E_PARAM);return result;}/* 检查网络是否配置为目标网络 */if (Mirror_IsNetworkConfiguredAsDest(NetworkId)) {/* 停用当前目标网络 */if (mirrorCurrentDestNetwork != MIRROR_INVALID_NETWORK) {Mirror_DeactivateDestNetwork(mirrorCurrentDestNetwork);}/* 激活新的目标网络 */result = Mirror_ActivateDestNetwork(NetworkId);if (result == E_OK) {mirrorCurrentDestNetwork = NetworkId;}}return result;
}
4. 状态管理
4.1 状态机
总线镜像模块的状态机如下图所示:
状态机描述了总线镜像模块的不同状态及其转换。主要状态包括:
-
未初始化状态:
- 模块尚未初始化
- 不能调用任何API(除
Mirror_Init
外) - 通过
Mirror_Init()
转换到已初始化状态
-
已初始化状态:
- 模块已通过
Mirror_Init
初始化 - 可以调用所有API
- 自动转入离线状态
- 通过
Mirror_DeInit()
转换回未初始化状态
- 模块已通过
-
离线状态:
- 没有活动的目标总线
- 可以激活源总线,但不会镜像到目标
- 可以通过
Mirror_SwitchDestNetwork
切换到在线状态 - 包含两个子状态:
- 无源总线激活:没有源总线被激活
- 源总线已激活:源总线已被激活,但由于没有目标总线,数据不会被镜像
-
在线状态:
- 目标总线已激活
- 可以激活源总线并将数据镜像到目标总线
- 通过
Mirror_Offline
可切换回离线状态 - 包含两个子状态:
- 无源总线镜像:没有源总线被激活进行镜像
- 源总线镜像中:源总线已激活并正在镜像数据,包含两个子子状态:
- 源总线数据过滤:对接收到的源总线帧应用过滤器
- 目标总线传输:将通过过滤的帧发送到目标总线
4.2 状态转换
状态转换由以下API触发:
-
Mirror_Init(ConfigPtr):初始化模块,从未初始化状态转换到已初始化状态
- 参数:配置指针
- 返回:无
- 前置条件:模块处于未初始化状态
- 后置条件:模块处于已初始化状态
-
Mirror_DeInit():反初始化模块,从已初始化状态转换到未初始化状态
- 参数:无
- 返回:无
- 前置条件:模块处于已初始化状态
- 后置条件:模块处于未初始化状态
-
Mirror_SwitchDestNetwork(NetworkId):切换目标网络,从离线状态转换到在线状态
- 参数:网络ID
- 返回:Std_ReturnType(E_OK或E_NOT_OK)
- 前置条件:模块处于离线状态
- 后置条件:如果成功,模块处于在线状态
-
Mirror_Offline():停用目标网络,从在线状态转换到离线状态
- 参数:无
- 返回:Std_ReturnType(E_OK或E_NOT_OK)
- 前置条件:模块处于在线状态
- 后置条件:模块处于离线状态
-
Mirror_StartSourceNetwork(NetworkId):启动源网络,激活源总线
- 参数:网络ID
- 返回:Std_ReturnType(E_OK或E_NOT_OK)
- 前置条件:模块处于已初始化状态
- 后置条件:源网络被激活
-
Mirror_StopSourceNetwork(NetworkId):停止源网络,停用源总线
- 参数:网络ID
- 返回:Std_ReturnType(E_OK或E_NOT_OK)
- 前置条件:源网络已激活
- 后置条件:源网络被停用
/* 离线状态转在线状态示例 */
Std_ReturnType Mirror_SwitchDestNetwork(Mirror_NetworkIdType NetworkId)
{Std_ReturnType result = E_NOT_OK;/* 检查模块状态 */if (mirrorStatus != MIRROR_INITIALIZED) {Mirror_ReportDevError(MIRROR_API_SWITCH_DEST_NETWORK, MIRROR_E_UNINIT);return result;}/* 检查参数 */if (NetworkId >= MIRROR_MAX_NETWORKS) {Mirror_ReportDevError(MIRROR_API_SWITCH_DEST_NETWORK, MIRROR_E_PARAM);return result;}/* 激活目标网络 */result = Mirror_ActivateDestNetwork(NetworkId);if (result == E_OK) {/* 更新状态为在线 */mirrorState = MIRROR_STATE_ONLINE;mirrorCurrentDestNetwork = NetworkId;}return result;
}
5. 数据流程
5.1 初始化流程
下图展示了总线镜像模块的初始化和数据流程:
初始化流程包括以下步骤:
-
Mirror模块调用
Mirror_Init(ConfigPtr)
初始化自身- 初始化内部数据结构
- 设置模块状态为已初始化
- 准备源总线和目标总线的配置
-
诊断工具通过诊断服务发送激活总线镜像请求
- 诊断服务调用
Mirror_SwitchDestNetwork(NetworkId)
激活目标总线 - 诊断服务调用
Mirror_StartSourceNetwork(NetworkId)
激活源总线 - 诊断服务向诊断工具返回正确响应
- 诊断服务调用
-
诊断工具通过诊断服务发送配置过滤器请求
- 诊断服务调用
Mirror_AddCanRangeFilter(NetworkId, LowerCanId, UpperCanId)
添加CAN范围过滤器 - 诊断服务调用
Mirror_SetStaticFilterState(FilterId, FilterState)
设置过滤器状态 - 诊断服务向诊断工具返回正确响应
- 诊断服务调用
/* 初始化流程伪代码 */
void InitializeMirroringProcess(void)
{/* 1. 初始化Mirror模块 */Mirror_Init(&MirrorConfig);/* 2. 激活目标总线 */if (Mirror_SwitchDestNetwork(DEST_NETWORK_ID) == E_OK) {/* 3. 激活源总线 */if (Mirror_StartSourceNetwork(SOURCE_NETWORK_ID) == E_OK) {/* 4. 配置过滤器 */Mirror_FilterIdType filterId = Mirror_AddCanRangeFilter(SOURCE_NETWORK_ID, LOWER_CAN_ID, UPPER_CAN_ID);if (filterId != MIRROR_INVALID_FILTER) {Mirror_SetStaticFilterState(filterId, MIRROR_FILTER_ENABLED);/* 初始化完成,可以开始镜像 */return;}}}/* 如果任何步骤失败,清理资源 */Mirror_Offline();Mirror_DeInit();
}
5.2 数据镜像流程
数据镜像流程包括以下步骤:
-
CAN源总线镜像流程:
- CanIf调用
Mirror_ReportCanFrame(CanId, Dlc, SduPtr, TimeStamp)
报告CAN帧 - Mirror模块应用过滤器,检查是否应该镜像该帧
- Mirror模块创建目标帧
- 根据目标总线类型,Mirror模块调用相应的传输函数:
- FlexRay:
Fr_TriggerTransmit(TxPduId, PduInfoPtr)
- CAN:
CanIf_Transmit(TxPduId, PduInfoPtr)
- IP:
SoAd_IfTransmit(TxPduId, PduInfoPtr)
- CDD:
<cdd>_Transmit(TxPduId, PduInfoPtr)
- FlexRay:
- 目标总线接口返回
E_OK
表示接受请求 - 目标总线接口调用
Mirror_TxConfirmation(TxPduId)
确认传输完成
- CanIf调用
-
FlexRay源总线镜像流程:
- FrIf调用
Mirror_ReportFlexRayFrame(SlotId, CycleCount, Channel, FrameLength, SduPtr, TimeStamp)
报告FlexRay帧 - 后续流程与CAN源总线镜像流程类似
- FrIf调用
/* CAN源总线镜像流程伪代码 */
void Mirror_ReportCanFrame(uint32 CanId, uint8 Dlc, const uint8* SduPtr, Mirror_TimestampType TimeStamp)
{/* 1. 检查模块状态 */if (mirrorState != MIRROR_STATE_ONLINE || mirrorCurrentDestNetwork == MIRROR_INVALID_NETWORK) {return; /* 模块不在在线状态或没有目标网络 */}/* 2. 应用过滤器 */if (Mirror_ApplyCanFilter(CanId) == FALSE) {return; /* 帧被过滤掉 */}/* 3. 创建目标帧 */Mirror_DestFrameType destFrame;if (Mirror_CreateDestFrame(CanId, Dlc, SduPtr, TimeStamp, &destFrame) != E_OK) {return; /* 创建目标帧失败 */}/* 4. 发送到目标总线 */switch (Mirror_GetNetworkType(mirrorCurrentDestNetwork)) {case MIRROR_NETWORK_TYPE_CAN:CanIf_Transmit(destFrame.PduId, &destFrame.PduInfo);break;case MIRROR_NETWORK_TYPE_FLEXRAY:Fr_TriggerTransmit(destFrame.PduId, &destFrame.PduInfo);break;case MIRROR_NETWORK_TYPE_IP:SoAd_IfTransmit(destFrame.PduId, &destFrame.PduInfo);break;case MIRROR_NETWORK_TYPE_CDD:/* 调用CDD特定的传输函数 */break;default:/* 未知网络类型 */break;}
}
5.3 停用流程
停用流程包括以下步骤:
-
诊断工具通过诊断服务发送停用总线镜像请求
- 诊断服务调用
Mirror_StopSourceNetwork(NetworkId)
停用源总线 - 诊断服务调用
Mirror_Offline()
停用目标总线 - 诊断服务向诊断工具返回正确响应
- 诊断服务调用
-
反初始化流程
- Mirror模块调用
Mirror_DeInit()
反初始化自身 - 释放所有资源
- 设置模块状态为未初始化
- Mirror模块调用
/* 停用流程伪代码 */
void DeactivateMirroringProcess(void)
{/* 1. 停用所有源总线 */for (uint8 i = 0; i < MIRROR_MAX_NETWORKS; i++) {if (Mirror_IsSourceNetworkStarted(i) == TRUE) {Mirror_StopSourceNetwork(i);}}/* 2. 停用目标总线 */Mirror_Offline();/* 3. 反初始化模块(可选) */Mirror_DeInit();
}
服务发送停用总线镜像请求
- 诊断服务调用
Mirror_StopSourceNetwork(NetworkId)
停用源总线 - 诊断服务调用
Mirror_Offline()
停用目标总线 - 诊断服务向诊断工具返回正确响应
- 反初始化流程
- Mirror模块调用
Mirror_DeInit()
反初始化自身 - 释放所有资源
- 设置模块状态为未初始化
- Mirror模块调用
/* 停用流程伪代码 */
void DeactivateMirroringProcess(void)
{/* 1. 停用所有源总线 */for (uint8 i = 0; i < MIRROR_MAX_NETWORKS; i++) {if (Mirror_IsSourceNetworkStarted(i) == TRUE) {Mirror_StopSourceNetwork(i);}}/* 2. 停用目标总线 */Mirror_Offline();/* 3. 反初始化模块(可选) */Mirror_DeInit();
}
总线镜像模块为AUTOSAR系统提供了强大的调试和监控能力,通过灵活的配置和过滤机制,可以满足各种调试和诊断需求。模块的设计遵循AUTOSAR标准,提供了清晰的API和状态管理,确保系统的稳定性和安全性。