当前位置: 首页 > news >正文

AUTOSAR进阶图解==>AUTOSAR_SWS_FlexRayTransceiverDriver

AUTOSAR FlexRay Transceiver Driver详解

基于AUTOSAR SWS FlexRayTransceiverDriver规范的技术详解

目录

  • 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*
      • 取值范围: 有效的配置结构地址
      • 默认值: 由配置工具生成
      • 约束: 必须包含有效的全局配置
      • 来源: 基于模块级配置参数生成

类 FrTrcvGeneralConfig:

  • 功能: 包含FlexRay收发器驱动的全局配置参数
  • 关键属性:
    • devErrorDetect:
      • 描述: 启用或禁用开发错误检测功能
      • 类型: boolean
      • 取值范围: TRUE/FALSE
      • 默认值: FALSE
      • 约束: 开发阶段建议设置为TRUE
      • 来源: 开发配置决定
    • versionInfoApi:
      • 描述: 启用或禁用版本信息API
      • 类型: boolean
      • 取值范围: TRUE/FALSE
      • 默认值: FALSE
      • 约束: 可选功能,根据需求配置
      • 来源: 功能需求配置
    • retryCountInInit:
      • 描述: 初始化过程中的重试次数
      • 类型: uint8
      • 取值范围: 0-255
      • 默认值: 3
      • 约束: 过高可能导致初始化超时
      • 来源: 根据硬件可靠性配置
通道配置类

类 FrTrcvChannelConfig:

  • 功能: 单个FlexRay收发器通道的配置信息
  • 关键属性:
    • channelId:
      • 描述: 通道的唯一标识符
      • 类型: uint8
      • 取值范围: 0-254
      • 默认值: 从0开始递增
      • 约束: 在同一驱动实例中必须唯一
      • 来源: 配置工具自动分配
    • initState:
      • 描述: 通道初始化后的工作模式
      • 类型: FrTrcv_TrcvModeType
      • 取值范围: NORMAL/STANDBY/SLEEP/RECEIVEONLY
      • 默认值: FRTRCV_TRCVMODE_NORMAL
      • 约束: 必须是硬件支持的模式
      • 来源: 根据系统启动需求配置
    • wakeupByBusUsed:
      • 描述: 是否启用总线唤醒功能
      • 类型: boolean
      • 取值范围: TRUE/FALSE
      • 默认值: FALSE
      • 约束: 依赖于硬件唤醒支持
      • 来源: 功耗管理需求决定
访问配置类

类 FrTrcvAccessConfig:

  • 功能: 定义收发器硬件的访问方式配置
  • 关键属性:
    • accessType:
      • 描述: 硬件访问类型,决定使用DIO还是SPI方式
      • 类型: FrTrcvAccessType
      • 取值范围: FRTRCV_ACCESS_DIO/FRTRCV_ACCESS_SPI
      • 默认值: 根据硬件设计决定
      • 约束: 必须与硬件连接方式匹配
      • 来源: 硬件设计规格

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收发器驱动,为汽车电子系统提供强大的通信基础设施支持。

http://www.lryc.cn/news/623154.html

相关文章:

  • 如何在FastAPI中玩转APScheduler,实现动态定时任务的魔法?
  • 【Docker】Ubuntu上安装Docker(网络版)
  • 储能领域大数据平台的设计中如何使用 Hadoop、Spark、Flink 等组件实现数据采集、清洗、存储及实时 / 离线计算,支持储能系统分析与预测
  • 打卡day40
  • 一些 DS 题目
  • Spark 数据分发性能深度剖析:mapPartitions vs. UDF – 你该选择哪一个?
  • docker-compose-mysql-定时备份数据库到其他服务器脚本
  • 【Web后端】Django、flask及其场景——以构建系统原型为例
  • 【OpenGL】LearnOpenGL学习笔记09 - 材质、光照贴图
  • 体彩排列三第2025218期号码分析
  • [Python]PTA:for 求奇数分之一序列前N项和
  • OpenWrt的快速设置向导功能与相关问题解答
  • Media Controller API 介绍
  • ClickHouse的学习与了解
  • 离线环境中使用ISO文件构建Yum源
  • 双重调度(Double Dispatch):《More Effective C++》条款31
  • 视频理解综述
  • 低空经济产业链全景解析
  • cPanel Python 应用部署流程
  • 存算分离与云原生:数据平台的新基石
  • Flowith-节点式GPT-4 驱动的AI生产力工具
  • 数据结构初阶(17)排序算法——非比较排序(计数排序·动图演示)、排序算法总结
  • 基于Spring Boot的快递物流仓库管理系统 商品库存管理系统
  • 中国大学排名爬取与数据分析案例总结
  • 深入解析 @nestjs/typeorm的 forRoot 与 forFeature
  • UDP/TCP套接字编程简单实战指南
  • 【深度学习】基于ESRNet模型的图像超分辨率训练
  • Bash常用操作总结
  • Maven私服配置模版
  • 机器学习——CountVectorizer将文本集合转换为 基于词频的特征矩阵