AUTOSAR进阶图解==>AUTOSAR_SWS_FlexRayTransceiverDriver
AUTOSAR FlexRay Transceiver Driver详解
目录
- 1. 概述
- 2. 架构设计
- 3. 配置模型
- 4. 状态机设计
- 5. 初始化序列
- 6. 总结
1. 概述
**FlexRay收发器驱动(FrTrcv)**是AUTOSAR BSW层的重要组件,负责管理FlexRay网络的物理层收发器硬件。该驱动提供了统一的接口来控制不同类型的FlexRay收发器,支持多种工作模式和唤醒机制,确保FlexRay通信的可靠性和功耗管理。
1.1 FrTrcv的作用
- 硬件抽象:为上层软件提供统一的FlexRay收发器访问接口
- 模式管理:支持NORMAL、STANDBY、SLEEP、RECEIVEONLY等多种工作模式
- 唤醒处理:检测和处理总线唤醒事件,支持低功耗管理
- 错误监控:监控收发器硬件状态,报告错误和故障
- 配置灵活性:支持DIO和SPI两种硬件访问方式
1.2 主要特性
- 多收发器支持:单个驱动实例可管理多个FlexRay收发器
- 硬件独立性:通过配置适配不同的收发器硬件
- 实时性能:满足FlexRay协议的实时性要求
- AUTOSAR兼容:完全符合AUTOSAR架构和接口规范
- 低功耗设计:支持多种低功耗模式和唤醒机制
2. 架构设计
2.1 架构组件详解
应用层组件
组件 FlexRay Interface (FrIf):
- 职责: FlexRay接口模块,作为FlexRay驱动和上层应用之间的桥梁
- 功能点:
- 提供统一的FlexRay网络访问接口
- 管理FlexRay控制器和收发器的协调工作
- 处理FlexRay通信的调度和路由
- 向上层提供抽象的FlexRay服务
BSW层核心组件
组件 FlexRay Transceiver Driver (FrTrcv):
- 职责: FlexRay收发器驱动核心模块,负责收发器硬件的直接控制
- 功能点:
- 收发器硬件的初始化和配置
- 工作模式的切换和管理
- 唤醒事件的检测和处理
- 错误状态的监控和报告
- 与硬件抽象层的接口管理
子组件 初始化模块:
- 职责: 负责收发器驱动的初始化过程
- 功能: 硬件资源配置、参数验证、状态设置
子组件 模式管理模块:
- 职责: 管理收发器的工作模式切换
- 功能: NORMAL/STANDBY/SLEEP/RECEIVEONLY模式控制
子组件 唤醒检测模块:
- 职责: 处理收发器的唤醒检测和通知
- 功能: 总线唤醒检测、唤醒源管理、EcuM通知
子组件 错误处理模块:
- 职责: 监控和报告收发器的错误状态
- 功能: 硬件错误检测、DEM事件报告、诊断支持
硬件抽象层组件
组件 DIO驱动 (Dio):
- 职责: 数字输入输出驱动,提供GPIO控制功能
- 功能点:
- 收发器控制引脚的读写操作
- 模式切换信号的控制
- 状态和错误信号的读取
组件 SPI驱动 (Spi):
- 职责: 串行外设接口驱动,提供SPI通信功能
- 功能点:
- 收发器寄存器的读写访问
- 配置数据的传输
- 状态信息的获取
组件 ICU驱动 (Icu):
- 职责: 输入捕获单元驱动,提供中断和边沿检测功能
- 功能点:
- 唤醒信号的边沿检测
- 中断事件的处理
- 定时器功能支持
外部模块
组件 ECU状态管理器 (EcuM):
- 职责: ECU状态管理器,负责ECU的电源和唤醒管理
- 交互: 接收来自FrTrcv的唤醒事件通知
组件 默认错误跟踪器 (Det):
- 职责: 开发时错误跟踪器,用于开发阶段的错误检测
- 交互: 接收FrTrcv报告的开发时错误
组件 诊断事件管理器 (Dem):
- 职责: 诊断事件管理器,处理运行时错误和故障
- 交互: 接收FrTrcv报告的运行时错误事件
2.2 接口设计
接口 主要API接口:
- 提供的服务: FrTrcv_Init、FrTrcv_SetTransceiverMode、FrTrcv_GetTransceiverMode
- 调用方式: 同步调用,通过FrIf间接调用
接口 唤醒API接口:
- 提供的服务: FrTrcv_CheckWakeup、FrTrcv_ClearTransceiverWakeup
- 调用方式: 同步调用,支持唤醒事件的检测和清除
2.3 架构代码示例
/* AUTOSAR FlexRay收发器驱动架构实现示例 *//* 主要数据结构定义 */
typedef struct {FrTrcv_TrcvModeType currentMode; /* 当前收发器模式 */boolean isInitialized; /* 初始化状态标志 */EcuM_WakeupSourceType wakeupSource; /* 唤醒源配置 */const FrTrcv_ConfigType* configPtr; /* 配置数据指针 */
} FrTrcv_ChannelStateType;/* 全局状态数组 */
static FrTrcv_ChannelStateType FrTrcv_ChannelState[FRTRCV_NUMBER_OF_CHANNELS];/* 初始化接口实现 */
void FrTrcv_Init(const FrTrcv_ConfigType* ConfigPtr)
{uint8 channelIndex;/* 参数验证 */if (ConfigPtr == NULL_PTR) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_INIT, FRTRCV_E_PARAM_POINTER);return;}/* 初始化所有配置的通道 */for (channelIndex = 0; channelIndex < ConfigPtr->numberOfChannels; channelIndex++) {/* 初始化通道状态 */FrTrcv_ChannelState[channelIndex].currentMode = ConfigPtr->channelConfig[channelIndex].initState;FrTrcv_ChannelState[channelIndex].isInitialized = TRUE;FrTrcv_ChannelState[channelIndex].wakeupSource = ConfigPtr->channelConfig[channelIndex].wakeupSource;FrTrcv_ChannelState[channelIndex].configPtr = ConfigPtr;/* 根据访问类型初始化硬件 */if (ConfigPtr->channelConfig[channelIndex].accessConfig->accessType == FRTRCV_ACCESS_DIO) {/* DIO方式初始化 */FrTrcv_InitDioAccess(channelIndex, &ConfigPtr->channelConfig[channelIndex]);} else if (ConfigPtr->channelConfig[channelIndex].accessConfig->accessType == FRTRCV_ACCESS_SPI) {/* SPI方式初始化 */FrTrcv_InitSpiAccess(channelIndex, &ConfigPtr->channelConfig[channelIndex]);}/* 设置初始工作模式 */FrTrcv_SetHardwareMode(channelIndex, ConfigPtr->channelConfig[channelIndex].initState);/* 配置唤醒检测 */if (ConfigPtr->channelConfig[channelIndex].wakeupByBusUsed == TRUE) {Icu_EnableWakeup(ConfigPtr->channelConfig[channelIndex].wakeupSource);}}
}/* 模式设置接口实现 */
Std_ReturnType FrTrcv_SetTransceiverMode(uint8 FrTrcv_TrcvIdx, FrTrcv_TrcvModeType FrTrcv_TrcvMode)
{Std_ReturnType result = E_OK;/* 参数验证 */if (FrTrcv_TrcvIdx >= FRTRCV_NUMBER_OF_CHANNELS) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_PARAM_TRCV);return E_NOT_OK;}if (FrTrcv_ChannelState[FrTrcv_TrcvIdx].isInitialized == FALSE) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_UNINIT);return E_NOT_OK;}/* 检查是否需要模式切换 */if (FrTrcv_ChannelState[FrTrcv_TrcvIdx].currentMode != FrTrcv_TrcvMode) {/* 执行硬件模式切换 */result = FrTrcv_SetHardwareMode(FrTrcv_TrcvIdx, FrTrcv_TrcvMode);if (result == E_OK) {/* 更新内部状态 */FrTrcv_ChannelState[FrTrcv_TrcvIdx].currentMode = FrTrcv_TrcvMode;}}return result;
}/* 硬件模式设置内部函数 */
static Std_ReturnType FrTrcv_SetHardwareMode(uint8 channelIndex, FrTrcv_TrcvModeType mode)
{const FrTrcv_ChannelConfigType* channelConfig = &FrTrcv_ChannelState[channelIndex].configPtr->channelConfig[channelIndex];if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_DIO) {/* DIO方式控制 */switch (mode) {case FRTRCV_TRCVMODE_NORMAL:Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[0].channelRef, STD_HIGH);Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[1].channelRef, STD_LOW);break;case FRTRCV_TRCVMODE_STANDBY:Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[0].channelRef, STD_LOW);Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[1].channelRef, STD_HIGH);break;case FRTRCV_TRCVMODE_SLEEP:Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[0].channelRef, STD_LOW);Dio_WriteChannel(channelConfig->accessConfig->dioAccess->channelAccess[1].channelRef, STD_LOW);break;default:return E_NOT_OK;}} else if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_SPI) {/* SPI方式控制 */uint8 modeData = (uint8)mode;Spi_WriteIB(channelConfig->accessConfig->spiAccess->spiSequence, &modeData);return Spi_AsyncTransmit(channelConfig->accessConfig->spiAccess->spiSequence);}return E_OK;
}/* 唤醒检测处理 */
void FrTrcv_CheckWakeup(uint8 FrTrcv_TrcvIdx)
{if (FrTrcv_TrcvIdx >= FRTRCV_NUMBER_OF_CHANNELS) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_CHECK_WAKEUP, FRTRCV_E_PARAM_TRCV);return;}if (FrTrcv_ChannelState[FrTrcv_TrcvIdx].isInitialized == FALSE) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_CHECK_WAKEUP, FRTRCV_E_UNINIT);return;}/* 检测唤醒事件 */if (FrTrcv_IsWakeupDetected(FrTrcv_TrcvIdx)) {/* 通知EcuM唤醒事件 */EcuM_SetWakeupEvent(FrTrcv_ChannelState[FrTrcv_TrcvIdx].wakeupSource);}
}
3. 配置模型
3.1 配置结构详解
主配置类
类 FrTrcv_ConfigType:
- 功能: FlexRay收发器驱动的主配置结构,包含所有配置信息的根节点
- 关键属性:
- configPtr:
- 描述: 指向具体配置数据的指针,用于运行时访问配置信息
- 类型: const void*
- 取值范围: 有效的内存地址
- 默认值: 由配置工具生成,无默认值
- 约束: 必须指向有效的配置数据结构
- 来源: 由AUTOSAR配置工具基于ECU配置生成
- numberOfChannels:
- 描述: 配置的FlexRay收发器通道数量
- 类型: uint8
- 取值范围: 1-255
- 默认值: 取决于ECU硬件配置
- 约束: 必须与实际硬件通道数匹配
- 来源: 由系统配置工具根据硬件规格设置
- channelConfig[]:
- 描述: 指向通道配置数组的指针,包含每个通道的详细配置
- 类型: FrTrcvChannelConfig*
- 取值范围: 有效的配置数组地址
- 默认值: 由配置工具分配
- 约束: 数组大小必须等于numberOfChannels
- 来源: 配置工具基于通道配置生成
- generalConfig:
- 描述: 指向通用配置的指针,包含全局配置参数
- 类型: FrTrcvGeneralConfig*
- 取值范围: 有效的配置结构地址
- 默认值: 由配置工具生成
- 约束: 必须包含有效的全局配置
- 来源: 基于模块级配置参数生成
- configPtr:
类 FrTrcvGeneralConfig:
- 功能: 包含FlexRay收发器驱动的全局配置参数
- 关键属性:
- devErrorDetect:
- 描述: 启用或禁用开发错误检测功能
- 类型: boolean
- 取值范围: TRUE/FALSE
- 默认值: FALSE
- 约束: 开发阶段建议设置为TRUE
- 来源: 开发配置决定
- versionInfoApi:
- 描述: 启用或禁用版本信息API
- 类型: boolean
- 取值范围: TRUE/FALSE
- 默认值: FALSE
- 约束: 可选功能,根据需求配置
- 来源: 功能需求配置
- retryCountInInit:
- 描述: 初始化过程中的重试次数
- 类型: uint8
- 取值范围: 0-255
- 默认值: 3
- 约束: 过高可能导致初始化超时
- 来源: 根据硬件可靠性配置
- devErrorDetect:
通道配置类
类 FrTrcvChannelConfig:
- 功能: 单个FlexRay收发器通道的配置信息
- 关键属性:
- channelId:
- 描述: 通道的唯一标识符
- 类型: uint8
- 取值范围: 0-254
- 默认值: 从0开始递增
- 约束: 在同一驱动实例中必须唯一
- 来源: 配置工具自动分配
- initState:
- 描述: 通道初始化后的工作模式
- 类型: FrTrcv_TrcvModeType
- 取值范围: NORMAL/STANDBY/SLEEP/RECEIVEONLY
- 默认值: FRTRCV_TRCVMODE_NORMAL
- 约束: 必须是硬件支持的模式
- 来源: 根据系统启动需求配置
- wakeupByBusUsed:
- 描述: 是否启用总线唤醒功能
- 类型: boolean
- 取值范围: TRUE/FALSE
- 默认值: FALSE
- 约束: 依赖于硬件唤醒支持
- 来源: 功耗管理需求决定
- channelId:
访问配置类
类 FrTrcvAccessConfig:
- 功能: 定义收发器硬件的访问方式配置
- 关键属性:
- accessType:
- 描述: 硬件访问类型,决定使用DIO还是SPI方式
- 类型: FrTrcvAccessType
- 取值范围: FRTRCV_ACCESS_DIO/FRTRCV_ACCESS_SPI
- 默认值: 根据硬件设计决定
- 约束: 必须与硬件连接方式匹配
- 来源: 硬件设计规格
- accessType:
3.2 配置关系说明
关系 MainConfig–GeneralConfig:
- 主配置结构包含一个通用配置实例,提供全局参数设置
关系 MainConfig–ChannelConfig:
- 主配置结构包含多个通道配置,每个通道一个配置实例
关系 ChannelConfig–AccessConfig:
- 每个通道配置包含一个访问配置,定义硬件访问方式
关系 AccessConfig–DioAccess/SpiAccess:
- 访问配置根据访问类型引用相应的DIO或SPI配置
3.3 配置代码示例
/* AUTOSAR FlexRay收发器驱动配置实现示例 *//* 枚举类型定义 */
typedef enum {FRTRCV_TRCVMODE_NORMAL = 0, /* 正常模式 */FRTRCV_TRCVMODE_STANDBY = 1, /* 待机模式 */FRTRCV_TRCVMODE_SLEEP = 2, /* 休眠模式 */FRTRCV_TRCVMODE_RECEIVEONLY = 3 /* 仅接收模式 */
} FrTrcv_TrcvModeType;typedef enum {FRTRCV_ACCESS_DIO = 0, /* DIO访问方式 */FRTRCV_ACCESS_SPI = 1 /* SPI访问方式 */
} FrTrcvAccessType;/* DIO访问配置结构 */
typedef struct {const char* hardwareInterfaceName; /* 硬件接口名称 */uint8 numberOfChannelAccess; /* 通道访问数量 */const FrTrcvDioChannelAccess* channelAccess; /* 通道访问配置数组 */
} FrTrcvDioAccess;typedef struct {const char* channelSymName; /* 通道符号名称 */const char* portSymName; /* 端口符号名称 */Dio_ChannelType channelRef; /* DIO通道引用 */
} FrTrcvDioChannelAccess;/* SPI访问配置结构 */
typedef struct {const char* hardwareInterfaceName; /* 硬件接口名称 */Spi_SequenceType spiSequence; /* SPI序列 */const void* spiSequenceRef; /* SPI序列引用 */
} FrTrcvSpiAccess;/* 访问配置结构 */
typedef struct {FrTrcvAccessType accessType; /* 访问类型 */const FrTrcvDioAccess* dioAccess; /* DIO访问配置 */const FrTrcvSpiAccess* spiAccess; /* SPI访问配置 */
} FrTrcvAccessConfig;/* DEM事件配置结构 */
typedef struct {Dem_EventIdType frErrNTrcvRef; /* 收发器错误事件ID */Dem_EventIdType frBusErrRef; /* 总线错误事件ID */
} FrTrcvDemEventParameterRefs;/* 通道配置结构 */
typedef struct {uint8 channelId; /* 通道ID */boolean channelUsed; /* 通道是否使用 */FrTrcv_TrcvModeType initState; /* 初始状态 */boolean wakeupByBusUsed; /* 是否使用总线唤醒 */EcuM_WakeupSourceType wakeupSource; /* 唤醒源 */const FrTrcvAccessConfig* accessConfig; /* 访问配置 */const FrTrcvDemEventParameterRefs* demEventParameterRefs; /* DEM事件配置 */
} FrTrcvChannelConfig;/* 通用配置结构 */
typedef struct {boolean devErrorDetect; /* 开发错误检测 */boolean versionInfoApi; /* 版本信息API */uint8 retryCountInInit; /* 初始化重试次数 */boolean errorCheckInInit; /* 初始化错误检查 */boolean errorCheckDuringCommunication; /* 通信期间错误检查 */const char* demReportErrorStatusConfiguration; /* DEM错误报告配置 */
} FrTrcvGeneralConfig;/* 主配置结构 */
typedef struct {const void* configPtr; /* 配置指针 */uint8 numberOfChannels; /* 通道数量 */const FrTrcvChannelConfig* channelConfig; /* 通道配置数组 */const FrTrcvGeneralConfig* generalConfig; /* 通用配置 */
} FrTrcv_ConfigType;/* 配置实例示例 *//* DIO通道访问配置 */
static const FrTrcvDioChannelAccess FrTrcv_DioChannelAccess_0[] = {{.channelSymName = "FrTrcv_EN_Pin",.portSymName = "PORT_A",.channelRef = DIO_CHANNEL_A_0},{.channelSymName = "FrTrcv_STB_Pin", .portSymName = "PORT_A",.channelRef = DIO_CHANNEL_A_1}
};/* DIO访问配置 */
static const FrTrcvDioAccess FrTrcv_DioAccess_0 = {.hardwareInterfaceName = "FlexRay_Transceiver_0",.numberOfChannelAccess = 2,.channelAccess = FrTrcv_DioChannelAccess_0
};/* 访问配置 */
static const FrTrcvAccessConfig FrTrcv_AccessConfig_0 = {.accessType = FRTRCV_ACCESS_DIO,.dioAccess = &FrTrcv_DioAccess_0,.spiAccess = NULL_PTR
};/* DEM事件配置 */
static const FrTrcvDemEventParameterRefs FrTrcv_DemEventRefs_0 = {.frErrNTrcvRef = DemConf_DemEventParameter_FRTRCV_E_FR_ERRN_TRCV_0,.frBusErrRef = DemConf_DemEventParameter_FRTRCV_E_FR_BUSERROR_TRCV_0
};/* 通道配置 */
static const FrTrcvChannelConfig FrTrcv_ChannelConfig_0 = {.channelId = 0,.channelUsed = TRUE,.initState = FRTRCV_TRCVMODE_NORMAL,.wakeupByBusUsed = TRUE,.wakeupSource = EcuMConf_EcuMWakeupSource_FLEXRAY_WAKEUP,.accessConfig = &FrTrcv_AccessConfig_0,.demEventParameterRefs = &FrTrcv_DemEventRefs_0
};/* 通用配置 */
static const FrTrcvGeneralConfig FrTrcv_GeneralConfig = {.devErrorDetect = TRUE,.versionInfoApi = FALSE,.retryCountInInit = 3,.errorCheckInInit = TRUE,.errorCheckDuringCommunication = TRUE,.demReportErrorStatusConfiguration = "Dem_SetEventStatus"
};/* 主配置 */
const FrTrcv_ConfigType FrTrcv_Config = {.configPtr = &FrTrcv_Config,.numberOfChannels = 1,.channelConfig = &FrTrcv_ChannelConfig_0,.generalConfig = &FrTrcv_GeneralConfig
};/* 配置验证函数 */
Std_ReturnType FrTrcv_ValidateConfig(const FrTrcv_ConfigType* ConfigPtr)
{uint8 channelIndex;/* 基本参数验证 */if (ConfigPtr == NULL_PTR) {return E_NOT_OK;}if (ConfigPtr->numberOfChannels == 0) {return E_NOT_OK;}if (ConfigPtr->channelConfig == NULL_PTR) {return E_NOT_OK;}if (ConfigPtr->generalConfig == NULL_PTR) {return E_NOT_OK;}/* 验证每个通道配置 */for (channelIndex = 0; channelIndex < ConfigPtr->numberOfChannels; channelIndex++) {const FrTrcvChannelConfig* channelConfig = &ConfigPtr->channelConfig[channelIndex];/* 验证通道ID唯一性 */if (channelConfig->channelId != channelIndex) {return E_NOT_OK;}/* 验证访问配置 */if (channelConfig->accessConfig == NULL_PTR) {return E_NOT_OK;}/* 验证访问类型配置 */if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_DIO) {if (channelConfig->accessConfig->dioAccess == NULL_PTR) {return E_NOT_OK;}} else if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_SPI) {if (channelConfig->accessConfig->spiAccess == NULL_PTR) {return E_NOT_OK;}} else {return E_NOT_OK;}/* 验证初始状态 */if ((channelConfig->initState != FRTRCV_TRCVMODE_NORMAL) &&(channelConfig->initState != FRTRCV_TRCVMODE_STANDBY) &&(channelConfig->initState != FRTRCV_TRCVMODE_SLEEP) &&(channelConfig->initState != FRTRCV_TRCVMODE_RECEIVEONLY)) {return E_NOT_OK;}}return E_OK;
}/* 配置初始化辅助函数 */
void FrTrcv_InitializeChannelFromConfig(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{/* 根据配置初始化通道状态 */FrTrcv_ChannelState[channelIndex].currentMode = channelConfig->initState;FrTrcv_ChannelState[channelIndex].isInitialized = TRUE;FrTrcv_ChannelState[channelIndex].wakeupSource = channelConfig->wakeupSource;/* 根据访问类型配置硬件接口 */if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_DIO) {/* 配置DIO通道 */uint8 i;for (i = 0; i < channelConfig->accessConfig->dioAccess->numberOfChannelAccess; i++) {/* 初始化DIO通道为输出模式 *//* 这里需要调用Port驱动配置引脚方向 */}} else if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_SPI) {/* 配置SPI通道 *//* 这里需要确保SPI驱动已经正确配置 */}/* 配置唤醒源 */if (channelConfig->wakeupByBusUsed == TRUE) {/* 启用唤醒检测 */Icu_EnableWakeup(channelConfig->wakeupSource);}
}
4. 状态机设计
4.1 状态详解
主要工作状态
状态 未初始化(UNINIT):
- 含义: FlexRay收发器驱动尚未初始化,硬件状态不确定
- 特征:
- 驱动模块未完成初始化过程
- 硬件收发器状态依赖于ECU启动条件
- 不能执行任何收发器控制操作
- 进入条件: ECU上电复位或系统重启
- 退出条件: 调用FrTrcv_Init()函数完成初始化
状态 正常模式(NORMAL):
- 含义: 收发器处于正常通信状态,支持完整的FlexRay通信功能
- 特征:
- 收发器处于最高功耗状态
- 支持发送和接收FlexRay数据帧
- 网络管理功能完全激活
- 提供完整的FlexRay协议支持
- 进入条件: 从其他模式通过FrTrcv_SetTransceiverMode()切换或初始化时设置
- 退出条件: 请求切换到其他工作模式
状态 待机模式(STANDBY):
- 含义: 收发器处于低功耗状态,保持唤醒检测能力但停止数据传输
- 特征:
- 功耗低于NORMAL模式
- 保持总线监听和唤醒检测功能
- 停止主动的数据传输
- 可快速恢复到NORMAL模式
- 进入条件: 从NORMAL或其他模式切换而来
- 退出条件: 检测到总线活动或请求模式切换
状态 休眠模式(SLEEP):
- 含义: 收发器处于最低功耗状态,支持总线唤醒检测但完全停止通信
- 特征:
- 最低功耗状态
- 保持总线唤醒检测功能
- 完全停止FlexRay通信
- 需要唤醒事件才能恢复通信
- 进入条件: 系统进入低功耗模式时切换
- 退出条件: 检测到总线唤醒事件
状态 仅接收模式(RECEIVEONLY):
- 含义: 收发器仅接收数据,禁用发送功能,主要用于监听和诊断
- 特征:
- 只能接收FlexRay数据帧
- 禁用所有发送功能
- 中等功耗状态
- 主要用于被动监听和诊断
- 进入条件: 诊断或监听需求时切换
- 退出条件: 请求切换到其他模式
4.2 状态转换详解
初始化转换
转换 UNINIT->NORMAL:
- 触发条件: 调用FrTrcv_Init()且配置InitState为NORMAL
- 业务场景: 系统启动后需要立即进行FlexRay通信
转换 UNINIT->STANDBY:
- 触发条件: 调用FrTrcv_Init()且配置InitState为STANDBY
- 业务场景: 系统启动后暂时不需要通信,但需要保持唤醒能力
转换 UNINIT->SLEEP:
- 触发条件: 调用FrTrcv_Init()且配置InitState为SLEEP
- 业务场景: 系统启动后进入低功耗模式
转换 UNINIT->RECEIVEONLY:
- 触发条件: 调用FrTrcv_Init()且配置InitState为RECEIVEONLY
- 业务场景: 系统启动后仅需要监听网络通信
运行时模式转换
转换 NORMAL->STANDBY:
- 触发条件: FrTrcv_SetTransceiverMode(FRTRCV_TRCVMODE_STANDBY)
- 业务场景: 通信暂停,但需要保持快速恢复能力
转换 NORMAL->SLEEP:
- 触发条件: FrTrcv_SetTransceiverMode(FRTRCV_TRCVMODE_SLEEP)
- 业务场景: 系统进入深度休眠模式
转换 SLEEP->NORMAL:
- 触发条件: 总线唤醒事件 + FrTrcv_SetTransceiverMode()
- 业务场景: 从休眠状态被总线活动唤醒,恢复通信
4.3 状态机代码示例
/* AUTOSAR FlexRay收发器驱动状态机实现示例 *//* 状态机相关数据结构 */
typedef struct {FrTrcv_TrcvModeType currentState; /* 当前状态 */FrTrcv_TrcvModeType requestedState; /* 请求的目标状态 */boolean transitionInProgress; /* 状态转换进行中标志 */uint32 stateTransitionTimer; /* 状态转换定时器 */uint32 stateEntryTimestamp; /* 状态进入时间戳 */
} FrTrcv_StateMachineType;/* 每个通道的状态机实例 */
static FrTrcv_StateMachineType FrTrcv_StateMachine[FRTRCV_NUMBER_OF_CHANNELS];/* 状态转换表 */
typedef struct {FrTrcv_TrcvModeType fromState; /* 源状态 */FrTrcv_TrcvModeType toState; /* 目标状态 */boolean isValidTransition; /* 是否为有效转换 */uint32 transitionTimeMs; /* 转换所需时间(毫秒) */
} FrTrcv_StateTransitionType;/* 状态转换表定义 */
static const FrTrcv_StateTransitionType FrTrcv_StateTransitionTable[] = {/* 从UNINIT的转换 */{FRTRCV_STATE_UNINIT, FRTRCV_TRCVMODE_NORMAL, TRUE, 10},{FRTRCV_STATE_UNINIT, FRTRCV_TRCVMODE_STANDBY, TRUE, 5},{FRTRCV_STATE_UNINIT, FRTRCV_TRCVMODE_SLEEP, TRUE, 2},{FRTRCV_STATE_UNINIT, FRTRCV_TRCVMODE_RECEIVEONLY, TRUE, 8},/* 从NORMAL的转换 */{FRTRCV_TRCVMODE_NORMAL, FRTRCV_TRCVMODE_STANDBY, TRUE, 3},{FRTRCV_TRCVMODE_NORMAL, FRTRCV_TRCVMODE_SLEEP, TRUE, 5},{FRTRCV_TRCVMODE_NORMAL, FRTRCV_TRCVMODE_RECEIVEONLY, TRUE, 2},/* 从STANDBY的转换 */{FRTRCV_TRCVMODE_STANDBY, FRTRCV_TRCVMODE_NORMAL, TRUE, 8},{FRTRCV_TRCVMODE_STANDBY, FRTRCV_TRCVMODE_SLEEP, TRUE, 3},/* 从SLEEP的转换 */{FRTRCV_TRCVMODE_SLEEP, FRTRCV_TRCVMODE_NORMAL, TRUE, 15},{FRTRCV_TRCVMODE_SLEEP, FRTRCV_TRCVMODE_STANDBY, TRUE, 10},/* 从RECEIVEONLY的转换 */{FRTRCV_TRCVMODE_RECEIVEONLY, FRTRCV_TRCVMODE_NORMAL, TRUE, 5},{FRTRCV_TRCVMODE_RECEIVEONLY, FRTRCV_TRCVMODE_STANDBY, TRUE, 3},{FRTRCV_TRCVMODE_RECEIVEONLY, FRTRCV_TRCVMODE_SLEEP, TRUE, 5}
};/* 状态机初始化 */
void FrTrcv_InitStateMachine(uint8 channelIndex, FrTrcv_TrcvModeType initialState)
{FrTrcv_StateMachine[channelIndex].currentState = FRTRCV_STATE_UNINIT;FrTrcv_StateMachine[channelIndex].requestedState = initialState;FrTrcv_StateMachine[channelIndex].transitionInProgress = TRUE;FrTrcv_StateMachine[channelIndex].stateTransitionTimer = 0;FrTrcv_StateMachine[channelIndex].stateEntryTimestamp = FrTrcv_GetCurrentTimestamp();
}/* 状态转换验证 */
static boolean FrTrcv_IsValidStateTransition(FrTrcv_TrcvModeType fromState, FrTrcv_TrcvModeType toState)
{uint8 i;uint8 tableSize = sizeof(FrTrcv_StateTransitionTable) / sizeof(FrTrcv_StateTransitionType);for (i = 0; i < tableSize; i++) {if ((FrTrcv_StateTransitionTable[i].fromState == fromState) &&(FrTrcv_StateTransitionTable[i].toState == toState)) {return FrTrcv_StateTransitionTable[i].isValidTransition;}}return FALSE; /* 未找到匹配的转换,默认为无效 */
}/* 获取状态转换时间 */
static uint32 FrTrcv_GetStateTransitionTime(FrTrcv_TrcvModeType fromState, FrTrcv_TrcvModeType toState)
{uint8 i;uint8 tableSize = sizeof(FrTrcv_StateTransitionTable) / sizeof(FrTrcv_StateTransitionType);for (i = 0; i < tableSize; i++) {if ((FrTrcv_StateTransitionTable[i].fromState == fromState) &&(FrTrcv_StateTransitionTable[i].toState == toState)) {return FrTrcv_StateTransitionTable[i].transitionTimeMs;}}return 0; /* 默认转换时间 */
}/* 状态转换请求处理 */
Std_ReturnType FrTrcv_RequestStateTransition(uint8 channelIndex, FrTrcv_TrcvModeType targetState)
{FrTrcv_StateMachineType* stateMachine = &FrTrcv_StateMachine[channelIndex];/* 检查是否有转换正在进行 */if (stateMachine->transitionInProgress == TRUE) {return E_NOT_OK; /* 转换正在进行中,拒绝新的转换请求 */}/* 检查是否为有效转换 */if (FrTrcv_IsValidStateTransition(stateMachine->currentState, targetState) == FALSE) {Det_ReportError(FRTRCV_MODULE_ID, channelIndex, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_PARAM_TRCVMODE);return E_NOT_OK;}/* 如果目标状态与当前状态相同,直接返回成功 */if (stateMachine->currentState == targetState) {return E_OK;}/* 启动状态转换 */stateMachine->requestedState = targetState;stateMachine->transitionInProgress = TRUE;stateMachine->stateTransitionTimer = FrTrcv_GetStateTransitionTime(stateMachine->currentState, targetState);/* 执行硬件层状态转换 */return FrTrcv_ExecuteHardwareStateTransition(channelIndex, stateMachine->currentState, targetState);
}/* 硬件状态转换执行 */
static Std_ReturnType FrTrcv_ExecuteHardwareStateTransition(uint8 channelIndex, FrTrcv_TrcvModeType fromState, FrTrcv_TrcvModeType toState)
{const FrTrcvChannelConfig* channelConfig = &FrTrcv_ChannelState[channelIndex].configPtr->channelConfig[channelIndex];Std_ReturnType result = E_OK;/* 状态转换前的准备工作 */FrTrcv_PrepareStateTransition(channelIndex, fromState, toState);/* 根据访问类型执行硬件控制 */if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_DIO) {result = FrTrcv_ExecuteDioStateTransition(channelIndex, toState);} else if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_SPI) {result = FrTrcv_ExecuteSpiStateTransition(channelIndex, toState);}/* 状态转换后的后续处理 */if (result == E_OK) {FrTrcv_CompleteStateTransition(channelIndex, toState);}return result;
}/* DIO方式状态转换 */
static Std_ReturnType FrTrcv_ExecuteDioStateTransition(uint8 channelIndex, FrTrcv_TrcvModeType targetState)
{const FrTrcvChannelConfig* channelConfig = &FrTrcv_ChannelState[channelIndex].configPtr->channelConfig[channelIndex];const FrTrcvDioAccess* dioAccess = channelConfig->accessConfig->dioAccess;/* 根据目标状态设置控制引脚 */switch (targetState) {case FRTRCV_TRCVMODE_NORMAL:/* 设置EN=HIGH, STB=LOW */Dio_WriteChannel(dioAccess->channelAccess[0].channelRef, STD_HIGH); /* EN */Dio_WriteChannel(dioAccess->channelAccess[1].channelRef, STD_LOW); /* STB */break;case FRTRCV_TRCVMODE_STANDBY:/* 设置EN=LOW, STB=HIGH */Dio_WriteChannel(dioAccess->channelAccess[0].channelRef, STD_LOW); /* EN */Dio_WriteChannel(dioAccess->channelAccess[1].channelRef, STD_HIGH); /* STB */break;case FRTRCV_TRCVMODE_SLEEP:/* 设置EN=LOW, STB=LOW */Dio_WriteChannel(dioAccess->channelAccess[0].channelRef, STD_LOW); /* EN */Dio_WriteChannel(dioAccess->channelAccess[1].channelRef, STD_LOW); /* STB */break;case FRTRCV_TRCVMODE_RECEIVEONLY:/* 设置为接收模式的特定组合 */Dio_WriteChannel(dioAccess->channelAccess[0].channelRef, STD_HIGH); /* EN */Dio_WriteChannel(dioAccess->channelAccess[1].channelRef, STD_HIGH); /* STB */break;default:return E_NOT_OK;}return E_OK;
}/* 状态机主函数 - 处理状态转换和超时 */
void FrTrcv_MainFunction_StateMachine(void)
{uint8 channelIndex;for (channelIndex = 0; channelIndex < FRTRCV_NUMBER_OF_CHANNELS; channelIndex++) {FrTrcv_StateMachineType* stateMachine = &FrTrcv_StateMachine[channelIndex];/* 检查是否有转换正在进行 */if (stateMachine->transitionInProgress == TRUE) {/* 递减转换定时器 */if (stateMachine->stateTransitionTimer > 0) {stateMachine->stateTransitionTimer--;} else {/* 转换时间到达,完成状态转换 */stateMachine->currentState = stateMachine->requestedState;stateMachine->transitionInProgress = FALSE;stateMachine->stateEntryTimestamp = FrTrcv_GetCurrentTimestamp();/* 通知状态变化 */FrTrcv_NotifyStateChange(channelIndex, stateMachine->currentState);}}/* 检查唤醒事件 */if ((stateMachine->currentState == FRTRCV_TRCVMODE_SLEEP) ||(stateMachine->currentState == FRTRCV_TRCVMODE_STANDBY)) {if (FrTrcv_IsWakeupDetected(channelIndex)) {/* 处理唤醒事件 */FrTrcv_HandleWakeupEvent(channelIndex);}}/* 执行状态相关的周期性任务 */FrTrcv_ExecuteStateSpecificTasks(channelIndex, stateMachine->currentState);}
}/* 状态特定任务执行 */
static void FrTrcv_ExecuteStateSpecificTasks(uint8 channelIndex, FrTrcv_TrcvModeType currentState)
{switch (currentState) {case FRTRCV_TRCVMODE_NORMAL:/* NORMAL模式下的任务 */FrTrcv_CheckCommunicationErrors(channelIndex);FrTrcv_UpdateNetworkStatus(channelIndex);break;case FRTRCV_TRCVMODE_STANDBY:/* STANDBY模式下的任务 */FrTrcv_CheckWakeupConditions(channelIndex);break;case FRTRCV_TRCVMODE_SLEEP:/* SLEEP模式下的任务 */FrTrcv_MonitorWakeupEvents(channelIndex);break;case FRTRCV_TRCVMODE_RECEIVEONLY:/* RECEIVEONLY模式下的任务 */FrTrcv_ProcessReceivedData(channelIndex);break;default:/* 未知状态处理 */break;}
}/* 唤醒事件处理 */
static void FrTrcv_HandleWakeupEvent(uint8 channelIndex)
{/* 清除唤醒事件 */FrTrcv_ClearWakeupEvent(channelIndex);/* 通知EcuM */EcuM_SetWakeupEvent(FrTrcv_ChannelState[channelIndex].wakeupSource);/* 根据配置决定是否自动转换到NORMAL模式 */if (FrTrcv_ChannelState[channelIndex].configPtr->generalConfig->autoWakeupToNormal == TRUE) {FrTrcv_RequestStateTransition(channelIndex, FRTRCV_TRCVMODE_NORMAL);}
}/* 获取当前状态 */
FrTrcv_TrcvModeType FrTrcv_GetCurrentState(uint8 channelIndex)
{if (channelIndex >= FRTRCV_NUMBER_OF_CHANNELS) {return FRTRCV_STATE_UNINIT;}return FrTrcv_StateMachine[channelIndex].currentState;
}/* 检查状态转换是否完成 */
boolean FrTrcv_IsStateTransitionComplete(uint8 channelIndex)
{if (channelIndex >= FRTRCV_NUMBER_OF_CHANNELS) {return FALSE;}return (FrTrcv_StateMachine[channelIndex].transitionInProgress == FALSE);
}
5. 初始化序列
5.1 序列参与者详解
应用层参与者
参与者 FlexRay Interface (FrIf):
- 角色: FlexRay接口模块,负责协调FlexRay控制器和收发器的操作
- 职责:
- 发起FlexRay收发器的初始化请求
- 管理FlexRay网络的启动序列
- 协调不同FlexRay组件的工作
- 向上层应用提供统一的FlexRay服务接口
BSW层参与者
参与者 FlexRay Transceiver Driver (FrTrcv):
- 角色: FlexRay收发器驱动核心模块
- 职责:
- 执行收发器硬件的初始化操作
- 验证配置参数的有效性
- 管理收发器的工作模式
- 处理错误检测和报告
- 配置唤醒检测功能
硬件抽象层参与者
参与者 DIO驱动 (Dio):
- 角色: 数字输入输出驱动,提供GPIO控制接口
- 职责:
- 控制收发器的模式选择引脚
- 读取收发器的状态和错误信号
- 提供数字信号的读写操作
参与者 SPI驱动 (Spi):
- 角色: 串行外设接口驱动,提供SPI通信功能
- 职责:
- 通过SPI接口配置收发器寄存器
- 执行收发器的命令传输
- 读取收发器的状态信息
参与者 ICU驱动 (Icu):
- 角色: 输入捕获单元驱动,提供中断和边沿检测
- 职责:
- 配置唤醒信号的边沿检测
- 启用或禁用唤醒中断
- 处理唤醒事件的捕获
外部模块参与者
参与者 ECU状态管理器 (EcuM):
- 角色: ECU状态管理器,负责系统的电源和唤醒管理
- 职责:
- 接收来自收发器的唤醒事件通知
- 管理ECU的电源状态转换
- 协调系统的启动和关闭过程
参与者 默认错误跟踪器 (Det):
- 角色: 开发时错误跟踪器
- 职责:
- 接收和记录开发时检测到的错误
- 提供错误信息用于调试和验证
- 支持错误统计和分析
5.2 初始化操作组详解
操作组 FlexRay收发器驱动初始化
场景: 系统启动时需要初始化FlexRay收发器驱动以支持FlexRay通信
触发条件: ECU启动完成基础驱动初始化后,FlexRay Interface请求初始化收发器驱动
关键函数调用详解:
函数 FrTrcv_Init:
- 描述: FlexRay收发器驱动的主初始化函数,负责完成驱动和硬件的初始化设置
- 参数:
- ConfigPtr [输入]: 指向配置数据结构的指针,类型: const FrTrcv_ConfigType*,取值范围: 有效的配置指针
- 返回值:
- void: 该函数无返回值,错误通过DET报告
- 相关函数:
- 上层: FrIf_Init调用该函数进行收发器初始化
- 下层: 该函数调用Dio_WriteChannel、Spi_AsyncTransmit等硬件访问函数
- 并列: 与FrTrcv_SetTransceiverMode功能相关,都涉及收发器控制
函数 验证配置参数:
- 描述: 内部函数,验证传入的配置参数是否有效和完整
- 参数:
- ConfigPtr [输入]: 配置指针,需要验证其有效性
- 返回值:
- boolean: TRUE表示参数有效,FALSE表示参数无效
- 相关函数:
- 上层: FrTrcv_Init调用此函数验证参数
- 下层: 无直接调用的下层函数
- 并列: 与其他参数验证函数功能类似
操作组 收发器模式切换
场景: 运行时需要改变收发器的工作模式以适应不同的通信需求
触发条件: 上层应用或网络管理需要切换收发器模式时发起请求
关键函数调用详解:
函数 FrTrcv_SetTransceiverMode:
- 描述: 设置收发器的工作模式,支持NORMAL、STANDBY、SLEEP、RECEIVEONLY等模式
- 参数:
- FrTrcv_TrcvIdx [输入]: 收发器索引,类型: uint8,取值范围: 0到配置的最大通道数-1
- FrTrcv_TrcvMode [输入]: 目标工作模式,类型: FrTrcv_TrcvModeType,取值范围: 枚举定义的有效模式
- 返回值:
- E_OK: 模式设置成功
- E_NOT_OK: 模式设置失败或参数无效
- 相关函数:
- 上层: FrIf_SetTransceiverMode调用该函数
- 下层: 该函数调用Dio_WriteChannel或Spi_AsyncTransmit执行硬件控制
- 并列: 与FrTrcv_GetTransceiverMode功能相关
5.3 初始化序列代码示例
/* AUTOSAR FlexRay收发器驱动初始化序列实现示例 *//* 初始化状态跟踪结构 */
typedef struct {boolean initInProgress; /* 初始化进行中标志 */uint8 currentChannelIndex; /* 当前初始化的通道索引 */uint8 initRetryCount; /* 初始化重试计数 */uint32 initStartTime; /* 初始化开始时间 */FrTrcv_InitStateType initState; /* 初始化状态 */
} FrTrcv_InitContextType;/* 初始化状态枚举 */
typedef enum {FRTRCV_INIT_STATE_IDLE = 0, /* 空闲状态 */FRTRCV_INIT_STATE_PARAM_CHECK, /* 参数检查阶段 */FRTRCV_INIT_STATE_HW_INIT, /* 硬件初始化阶段 */FRTRCV_INIT_STATE_MODE_SET, /* 模式设置阶段 */FRTRCV_INIT_STATE_WAKEUP_CONFIG, /* 唤醒配置阶段 */FRTRCV_INIT_STATE_ERROR_CHECK, /* 错误检查阶段 */FRTRCV_INIT_STATE_COMPLETE /* 初始化完成 */
} FrTrcv_InitStateType;/* 初始化上下文 */
static FrTrcv_InitContextType FrTrcv_InitContext;/* 主初始化函数实现 */
void FrTrcv_Init(const FrTrcv_ConfigType* ConfigPtr)
{uint8 channelIndex;Std_ReturnType result;/* 第一阶段:参数验证 */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_PARAM_CHECK;FrTrcv_InitContext.initInProgress = TRUE;FrTrcv_InitContext.initStartTime = FrTrcv_GetCurrentTimestamp();/* 验证配置参数 */if (ConfigPtr == NULL_PTR) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_INIT, FRTRCV_E_PARAM_POINTER);FrTrcv_InitContext.initInProgress = FALSE;return;}if (ConfigPtr->numberOfChannels == 0) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_INIT, FRTRCV_E_PARAM_CONFIG);FrTrcv_InitContext.initInProgress = FALSE;return;}if (ConfigPtr->channelConfig == NULL_PTR) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_INIT, FRTRCV_E_PARAM_POINTER);FrTrcv_InitContext.initInProgress = FALSE;return;}/* 第二阶段:初始化内部变量 */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_HW_INIT;/* 清除所有通道状态 */for (channelIndex = 0; channelIndex < FRTRCV_NUMBER_OF_CHANNELS; channelIndex++) {FrTrcv_ChannelState[channelIndex].currentMode = FRTRCV_STATE_UNINIT;FrTrcv_ChannelState[channelIndex].isInitialized = FALSE;FrTrcv_ChannelState[channelIndex].wakeupSource = 0;FrTrcv_ChannelState[channelIndex].configPtr = ConfigPtr;}/* 第三阶段:逐个初始化配置的通道 */for (channelIndex = 0; channelIndex < ConfigPtr->numberOfChannels; channelIndex++) {FrTrcv_InitContext.currentChannelIndex = channelIndex;FrTrcv_InitContext.initRetryCount = 0;/* 初始化单个通道 */result = FrTrcv_InitChannel(channelIndex, &ConfigPtr->channelConfig[channelIndex]);if (result != E_OK) {/* 初始化失败,根据配置决定是否重试 */if (ConfigPtr->generalConfig->retryCountInInit > 0) {result = FrTrcv_RetryChannelInit(channelIndex, &ConfigPtr->channelConfig[channelIndex]);}if (result != E_OK) {/* 重试后仍然失败,报告错误 */Det_ReportRuntimeError(FRTRCV_MODULE_ID, channelIndex, FRTRCV_SID_INIT, FRTRCV_E_INIT_FAILED);FrTrcv_InitContext.initInProgress = FALSE;return;}}}/* 第四阶段:初始化完成 */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_COMPLETE;FrTrcv_InitContext.initInProgress = FALSE;
}/* 单通道初始化函数 */
static Std_ReturnType FrTrcv_InitChannel(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{Std_ReturnType result = E_OK;/* 第一步:根据访问类型初始化硬件接口 */if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_DIO) {result = FrTrcv_InitDioHardware(channelIndex, channelConfig);} else if (channelConfig->accessConfig->accessType == FRTRCV_ACCESS_SPI) {result = FrTrcv_InitSpiHardware(channelIndex, channelConfig);} else {return E_NOT_OK;}if (result != E_OK) {return result;}/* 第二步:设置初始工作模式 */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_MODE_SET;result = FrTrcv_SetHardwareMode(channelIndex, channelConfig->initState);if (result != E_OK) {return result;}/* 第三步:配置唤醒检测 */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_WAKEUP_CONFIG;if (channelConfig->wakeupByBusUsed == TRUE) {result = FrTrcv_ConfigureWakeupDetection(channelIndex, channelConfig);if (result != E_OK) {return result;}/* 检查是否有待处理的唤醒事件 */if (FrTrcv_CheckPendingWakeup(channelIndex)) {/* 通知EcuM有待处理的唤醒事件 */EcuM_SetWakeupEvent(channelConfig->wakeupSource);}}/* 第四步:错误检查(如果配置启用) */FrTrcv_InitContext.initState = FRTRCV_INIT_STATE_ERROR_CHECK;if (channelConfig->configPtr->generalConfig->errorCheckInInit == TRUE) {result = FrTrcv_PerformInitErrorCheck(channelIndex, channelConfig);if (result != E_OK) {/* 检测到硬件错误 */Dem_SetEventStatus(channelConfig->demEventParameterRefs->frErrNTrcvRef, DEM_EVENT_STATUS_PREFAILED);return result;} else {/* 没有检测到错误 */Dem_SetEventStatus(channelConfig->demEventParameterRefs->frErrNTrcvRef, DEM_EVENT_STATUS_PREPASSED);}}/* 第五步:更新通道状态 */FrTrcv_ChannelState[channelIndex].currentMode = channelConfig->initState;FrTrcv_ChannelState[channelIndex].isInitialized = TRUE;FrTrcv_ChannelState[channelIndex].wakeupSource = channelConfig->wakeupSource;return E_OK;
}/* DIO硬件初始化 */
static Std_ReturnType FrTrcv_InitDioHardware(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{const FrTrcvDioAccess* dioAccess = channelConfig->accessConfig->dioAccess;uint8 i;/* 验证DIO访问配置 */if (dioAccess == NULL_PTR) {return E_NOT_OK;}if (dioAccess->channelAccess == NULL_PTR) {return E_NOT_OK;}/* 初始化所有DIO通道为默认状态 */for (i = 0; i < dioAccess->numberOfChannelAccess; i++) {/* 设置初始电平为低电平 */Dio_WriteChannel(dioAccess->channelAccess[i].channelRef, STD_LOW);}/* 延时以确保硬件稳定 */FrTrcv_DelayMs(FRTRCV_HW_STABILIZATION_TIME_MS);return E_OK;
}/* SPI硬件初始化 */
static Std_ReturnType FrTrcv_InitSpiHardware(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{const FrTrcvSpiAccess* spiAccess = channelConfig->accessConfig->spiAccess;uint8 initData[] = {0x00, 0x00}; /* 初始化数据 */Std_ReturnType result;/* 验证SPI访问配置 */if (spiAccess == NULL_PTR) {return E_NOT_OK;}/* 写入初始化数据 */Spi_WriteIB(spiAccess->spiSequence, initData);/* 执行SPI传输 */result = Spi_AsyncTransmit(spiAccess->spiSequence);if (result != E_OK) {return result;}/* 等待传输完成 */while (Spi_GetSequenceResult(spiAccess->spiSequence) == SPI_SEQ_PENDING) {/* 等待传输完成 */}if (Spi_GetSequenceResult(spiAccess->spiSequence) != SPI_SEQ_OK) {return E_NOT_OK;}return E_OK;
}/* 唤醒检测配置 */
static Std_ReturnType FrTrcv_ConfigureWakeupDetection(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{/* 启用ICU唤醒检测 */Icu_EnableWakeup(channelConfig->wakeupSource);/* 配置唤醒边沿检测 */Icu_SetActivationCondition(channelConfig->wakeupSource, ICU_RISING_EDGE);/* 启用唤醒通知 */Icu_EnableNotification(channelConfig->wakeupSource);return E_OK;
}/* 初始化错误检查 */
static Std_ReturnType FrTrcv_PerformInitErrorCheck(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{Dio_LevelType errorLevel;const FrTrcvDioAccess* dioAccess = channelConfig->accessConfig->dioAccess;/* 检查是否有错误引脚配置 */if (dioAccess->numberOfChannelAccess > 2) {/* 假设第三个引脚是错误引脚(ERRN) */errorLevel = Dio_ReadChannel(dioAccess->channelAccess[2].channelRef);/* ERRN引脚低电平表示错误 */if (errorLevel == STD_LOW) {return E_NOT_OK;}}return E_OK;
}/* 初始化重试机制 */
static Std_ReturnType FrTrcv_RetryChannelInit(uint8 channelIndex, const FrTrcvChannelConfig* channelConfig)
{uint8 retryCount;Std_ReturnType result = E_NOT_OK;uint8 maxRetries = channelConfig->configPtr->generalConfig->retryCountInInit;for (retryCount = 0; retryCount < maxRetries; retryCount++) {FrTrcv_InitContext.initRetryCount = retryCount + 1;/* 延时后重试 */FrTrcv_DelayMs(FRTRCV_INIT_RETRY_DELAY_MS);/* 重新初始化通道 */result = FrTrcv_InitChannel(channelIndex, channelConfig);if (result == E_OK) {break; /* 初始化成功,退出重试循环 */}}return result;
}/* 模式设置函数实现 */
Std_ReturnType FrTrcv_SetTransceiverMode(uint8 FrTrcv_TrcvIdx, FrTrcv_TrcvModeType FrTrcv_TrcvMode)
{Std_ReturnType result = E_OK;/* 参数验证 */if (FrTrcv_TrcvIdx >= FRTRCV_NUMBER_OF_CHANNELS) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_PARAM_TRCV);return E_NOT_OK;}if (FrTrcv_ChannelState[FrTrcv_TrcvIdx].isInitialized == FALSE) {Det_ReportError(FRTRCV_MODULE_ID, 0, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_UNINIT);return E_NOT_OK;}/* 验证目标模式 */if ((FrTrcv_TrcvMode != FRTRCV_TRCVMODE_NORMAL) &&(FrTrcv_TrcvMode != FRTRCV_TRCVMODE_STANDBY) &&(FrTrcv_TrcvMode != FRTRCV_TRCVMODE_SLEEP) &&(FrTrcv_TrcvMode != FRTRCV_TRCVMODE_RECEIVEONLY)) {Det_ReportError(FRTRCV_MODULE_ID, FrTrcv_TrcvIdx, FRTRCV_SID_SET_TRANSCEIVER_MODE, FRTRCV_E_PARAM_TRCVMODE);return E_NOT_OK;}/* 检查是否需要模式切换 */if (FrTrcv_ChannelState[FrTrcv_TrcvIdx].currentMode != FrTrcv_TrcvMode) {/* 执行状态转换 */result = FrTrcv_RequestStateTransition(FrTrcv_TrcvIdx, FrTrcv_TrcvMode);if (result == E_OK) {/* 等待状态转换完成 */while (FrTrcv_IsStateTransitionComplete(FrTrcv_TrcvIdx) == FALSE) {/* 等待转换完成 */FrTrcv_DelayMs(1);}/* 更新内部状态 */FrTrcv_ChannelState[FrTrcv_TrcvIdx].currentMode = FrTrcv_TrcvMode;}}return result;
}/* 延时函数实现 */
static void FrTrcv_DelayMs(uint32 delayMs)
{uint32 startTime = FrTrcv_GetCurrentTimestamp();while ((FrTrcv_GetCurrentTimestamp() - startTime) < delayMs) {/* 忙等待 */}
}/* 获取当前时间戳 */
static uint32 FrTrcv_GetCurrentTimestamp(void)
{/* 这里应该调用系统时间服务获取当前时间戳 *//* 示例实现,实际应该调用OS或GPT服务 */static uint32 timestamp = 0;return ++timestamp;
}
6. 总结
6.1 技术优势
通过本文的详细分析,AUTOSAR FlexRay收发器驱动展现出以下关键技术优势:
- 架构清晰性:采用分层架构设计,实现了硬件抽象和软件模块化,便于维护和扩展
- 配置灵活性:支持多种硬件访问方式和丰富的配置参数,适应不同的硬件平台和应用需求
- 状态管理完善:提供完整的状态机设计,支持多种工作模式和可靠的状态转换机制
- 初始化机制健壮:实现了完整的初始化序列,包括参数验证、硬件配置、错误检查和重试机制
- 错误处理全面:集成了开发时错误检测和运行时错误报告,提供完善的诊断支持
6.2 应用场景
FlexRay收发器驱动适用于以下典型应用场景:
- 高端汽车电子系统:支持需要高速、确定性通信的汽车应用,如底盘控制、动力总成管理
- 安全关键系统:提供可靠的通信基础设施,满足功能安全要求
- 实时控制系统:支持严格实时性要求的控制应用,如电子稳定控制、主动悬架系统
- 网络诊断系统:提供丰富的诊断接口和错误报告机制,支持车辆诊断和维护
6.3 实施建议
在实际项目中实施FlexRay收发器驱动时,建议关注以下要点:
- 硬件适配:根据具体的收发器硬件特性,正确配置访问方式和控制参数
- 时序优化:确保状态转换和通信时序满足FlexRay协议要求和硬件规格
- 错误处理:建立完善的错误检测、报告和恢复机制,提高系统可靠性
- 功耗管理:合理利用不同工作模式,实现系统功耗优化
- 集成测试:进行充分的集成测试,验证驱动与其他FlexRay组件的协调工作
通过遵循AUTOSAR规范和本文提供的设计指导,可以实现高质量、高可靠性的FlexRay收发器驱动,为汽车电子系统提供强大的通信基础设施支持。