AUTOSAR Flash Test模块详解与分析
目录
- 1. Flash Test模块概述
- 1.1 模块作用与功能
- 1.2 适用范围
- 2. Flash Test模块架构
- 2.1 模块位置
- 2.2 组件关系
- 3. 状态管理
- 3.1 状态定义
- 3.2 状态转换
- 4. 后台测试执行流程
- 4.1 测试间隔概念
- 4.2 部分测试机制
- 4.3 测试周期控制
- 5. API详解
- 5.1 初始化与去初始化
- 5.2 测试执行控制
- 5.3 状态与结果查询
- 6. 错误处理机制
- 7. 总结与应用场景
1. Flash Test模块概述
1.1 模块作用与功能
Flash Test模块是AUTOSAR基础软件中的一个关键组件,主要用于对不变内存(如数据/程序Flash、程序SRAM、锁定缓存)进行测试。这些内存可能嵌入在微控制器内部或通过存储器映射连接到微控制器。
根据源文档中的描述:
“此Flash测试模块提供算法来测试不变存储器。不变存储器可以是数据/程序Flash、程序SRAM、锁定缓存,要么嵌入在微控制器中,要么通过存储器映射连接到微控制器。为了简化,该软件模块称为Flash Test驱动。”
该模块具有以下主要特性和功能:
- 多种测试模式:支持前台(同步)和后台(异步)测试执行方式
- 可配置的测试算法:系统可根据安全需求选择适合的测试算法
- 灵活的执行时间:可在MCU初始化后的任何时间执行测试
- 整合安全概念:作为整体安全概念的一部分,提供必要的诊断覆盖
1.2 适用范围
Flash Test模块适用于需要确保存储内容完整性的安全关键型应用场景。根据文档中的描述,该模块:
- 依赖于系统的存储概念
- 需要与整体安全概念集成
- 单独使用时无法提供所需的诊断覆盖
- 可配置使用不同的测试算法,以满足各种安全需求
2. Flash Test模块架构
2.1 模块位置
Flash Test模块位于AUTOSAR软件架构的微控制器抽象层(MCAL)中,与其他基础软件模块有明确的交互关系。下图展示了Flash Test模块在整个AUTOSAR架构中的位置和与其他模块的关系:
2.2 组件关系
从上图中可以看出Flash Test模块的关键组件关系:
组件 Flash Test模块:
- 职责: 提供对不变内存(Flash/SRAM)的测试功能
- 功能点:
- 支持前台(同步)和后台(异步)测试模式
- 提供可配置的测试块和测试间隔
- 支持测试暂停、恢复和中止
- 报告测试结果和状态
接口 FlsTst_Init
:
- 提供的服务: 初始化Flash Test模块
- 调用方式: 在系统启动阶段由RTE调用
接口 FlsTst_MainFunction
:
- 提供的服务: 定期执行后台Flash测试的部分步骤
- 调用方式: 由BSW调度器按配置的周期定期调用
层 微控制器抽象层(MCAL):
- 范围: 提供对硬件的标准化访问接口
- 包含模块: Flash Test模块、MCU驱动等
根据源文档,Flash Test模块依赖以下模块:
- BSW调度器:触发后台模式下的主函数
- DEM:报告诊断事件
- DET:报告开发错误
以下是Flash Test模块的组件关系代码示例:
/* AUTOSAR FlashTest模块头文件示例 */
#ifndef FLS_TST_H
#define FLS_TST_H#include "Std_Types.h"
#include "FlsTst_Cfg.h"/* 模块版本定义 */
#define FLSTST_SW_MAJOR_VERSION 4
#define FLSTST_SW_MINOR_VERSION 4
#define FLSTST_SW_PATCH_VERSION 0/* 模块状态定义 */
typedef enum {FLSTST_UNINIT = 0, /* 模块未初始化 */FLSTST_INIT, /* 模块已初始化,可以启动测试 */FLSTST_RUNNING, /* 后台测试运行中 */FLSTST_SUSPENDED /* 后台测试暂停 */
} FlsTst_StateType;/* 测试结果定义 */
typedef enum {FLSTST_OK = 0, /* 测试成功 */FLSTST_NOT_TESTED, /* 未测试 */FLSTST_FAILED, /* 测试失败 */FLSTST_NON_MATCHING_CRC /* CRC不匹配 */
} FlsTst_TestResultType;/* 模块API声明 */
extern void FlsTst_Init(const FlsTst_ConfigType* ConfigPtr);
extern void FlsTst_DeInit(void);
extern Std_ReturnType FlsTst_StartForeground(void);
extern Std_ReturnType FlsTst_StartBackground(void);
extern Std_ReturnType FlsTst_Suspend(void);
extern Std_ReturnType FlsTst_Resume(void);
extern void FlsTst_Abort(void);
extern Std_ReturnType FlsTst_GetTestStatus(FlsTst_StateType* StatePtr);
extern Std_ReturnType FlsTst_GetTestResult(FlsTst_TestResultType* ResultPtr);
extern Std_ReturnType FlsTst_GetTestSignature(uint32* SignaturePtr);
extern void FlsTst_MainFunction(void);#endif /* FLS_TST_H */
3. 状态管理
3.1 状态定义
Flash Test模块实现了精确的状态管理,用于控制测试流程和跟踪测试进度。下图展示了FlashTest模块的状态转换图:
3.2 状态转换
根据上图和源文档中的信息,Flash Test模块维护以下状态:
状态 FLSTST_INIT:
- 描述: 初始化状态,模块初始化后的状态
- 功能: 在此状态下,可以启动前台或后台测试
- 进入条件:
- 模块初始化完成后
- 通过调用
FlsTst_Abort()
中止测试后
状态 FLSTST_RUNNING:
- 描述: 运行状态,后台测试执行中
- 功能: 在此状态下,通过
FlsTst_MainFunction()
触发定期测试 - 进入条件:
- 从FLSTST_INIT状态调用
FlsTst_StartBackground()
- 从FLSTST_SUSPENDED状态调用
FlsTst_Resume()
- 从FLSTST_INIT状态调用
状态 FLSTST_SUSPENDED:
- 描述: 暂停状态,后台测试暂停
- 功能: 保存当前测试位置,可以恢复或终止测试
- 进入条件:
- 从FLSTST_RUNNING状态调用
FlsTst_Suspend()
- 从FLSTST_RUNNING状态调用
状态转换的代码实现示例:
/* FlashTest状态管理示例代码 *//* 模块内部状态变量 */
static FlsTst_StateType FlsTst_State = FLSTST_UNINIT;
static FlsTst_TestResultType FlsTst_TestResult = FLSTST_NOT_TESTED;
static uint32 FlsTst_CurrentTestIntervalId = 0;/* 初始化函数 */
void FlsTst_Init(const FlsTst_ConfigType* ConfigPtr)
{if (ConfigPtr == NULL) {/* 报告开发错误 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_INIT_ID, FLSTST_E_PARAM_POINTER);return;}/* 初始化内部变量 */FlsTst_CurrentTestIntervalId = 0;FlsTst_TestResult = FLSTST_NOT_TESTED;/* 设置模块状态为初始化完成 */FlsTst_State = FLSTST_INIT;/* 如果配置了自动启动,则启动后台测试 */if (ConfigPtr->FlsTstAutoStart == TRUE) {FlsTst_StartBackground();}
}/* 启动后台测试 */
Std_ReturnType FlsTst_StartBackground(void)
{if (FlsTst_State == FLSTST_UNINIT) {/* 报告开发错误 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_START_BACKGROUND_ID, FLSTST_E_UNINIT);return E_NOT_OK;}/* 准备后台测试 */FlsTst_PrepareBackgroundTest();/* 更改状态为RUNNING */FlsTst_State = FLSTST_RUNNING;return E_OK;
}/* 暂停后台测试 */
Std_ReturnType FlsTst_Suspend(void)
{if (FlsTst_State != FLSTST_RUNNING) {/* 报告开发错误 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_SUSPEND_ID, FLSTST_E_INVALID_STATE);return E_NOT_OK;}/* 保存当前测试位置 */FlsTst_SaveCurrentTestPosition();/* 更改状态为SUSPENDED */FlsTst_State = FLSTST_SUSPENDED;return E_OK;
}/* 恢复后台测试 */
Std_ReturnType FlsTst_Resume(void)
{if (FlsTst_State != FLSTST_SUSPENDED) {/* 报告开发错误 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_RESUME_ID, FLSTST_E_INVALID_STATE);return E_NOT_OK;}/* 恢复之前的测试位置 */FlsTst_RestoreTestPosition();/* 更改状态为RUNNING */FlsTst_State = FLSTST_RUNNING;return E_OK;
}/* 中止测试 */
void FlsTst_Abort(void)
{if (FlsTst_State == FLSTST_UNINIT) {/* 报告开发错误 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_ABORT_ID, FLSTST_E_UNINIT);return;}/* 清理测试状态 */FlsTst_CleanupTestState();/* 更改状态为INIT */FlsTst_State = FLSTST_INIT;
}
4. 后台测试执行流程
Flash Test模块的后台测试是一个可中断的、分段执行的过程,通过FlsTst_MainFunction
周期性地执行部分测试。下图展示了后台测试的执行流程:
4.1 测试间隔概念
根据源文档,Flash Test中的测试间隔是一个重要概念:
“在后台模式下,测试块应按照在配置结构中配置的相同顺序进行测试。当所有块都测试完成时,完成一个测试间隔(参见图2)。在后台测试中,部分测试应通过FlsTst_MainFunction触发(参见SWS_FlsTst_00066)。”
测试间隔具有以下特性:
- 每个测试间隔都有一个标识符,在每次启动新的测试间隔时递增
- 测试间隔完成意味着所有配置的内存块都已测试完毕
- 当一个测试间隔完成后,系统会自动开始下一个测试间隔
4.2 部分测试机制
部分测试是Flash Test后台测试模式的核心机制:
“部分测试的长度由在一个调度任务中要测试的单元数量定义,这应该可配置(参见ECUC_FlsTst_00161)。执行部分测试所需的时间(不中断)定义为"测试时间”。"
部分测试具有以下特性:
- 在每次
FlsTst_MainFunction
调用中执行一部分测试 - 测试单元数量可配置(
FlsTstNumberOfTestedCells
) - 部分测试可以被高优先级任务中断,无需原子序列
- 用户负责确保在调度器间隔结束前完成可中断的部分测试
4.3 测试周期控制
Flash Test模块提供了灵活的测试周期控制机制:
- 暂停与恢复:通过
FlsTst_Suspend()
和FlsTst_Resume()
控制测试流程 - 中止测试:通过
FlsTst_Abort()
完全终止测试流程 - 延迟处理:API调用请求处理的最大延迟时间可配置(ECUC_FlsTst_00120)
以下是后台测试流程的代码实现示例:
/* 后台测试执行相关代码示例 *//* 部分测试参数 */
static uint32 FlsTst_CurrentBlock; /* 当前测试块索引 */
static uint32 FlsTst_CurrentBlockAddress; /* 当前测试块内地址 */
static uint32 FlsTst_CurrentBlockSize; /* 当前块的大小 */
static uint32 FlsTst_TestedCellsInBlock; /* 当前块中已测试的单元数 *//* MainFunction实现 */
void FlsTst_MainFunction(void)
{uint32 cellsToTest;uint8 testResult;/* 检查模块状态 */if (FlsTst_State != FLSTST_RUNNING) {/* 模块未处于运行状态,不执行测试 */return;}/* 获取本次要测试的单元数量 */cellsToTest = FlsTst_ConfigPtr->FlsTstNumberOfTestedCells;/* 执行部分测试 */while (cellsToTest > 0 && FlsTst_State == FLSTST_RUNNING) {/* 检查当前块是否测试完成 */if (FlsTst_TestedCellsInBlock >= FlsTst_CurrentBlockSize) {/* 当前块测试完成,移至下一块 */FlsTst_CurrentBlock++;/* 检查是否所有块都已测试完成 */if (FlsTst_CurrentBlock >= FlsTst_ConfigPtr->FlsTstBlockNumberBgnd) {/* 测试间隔完成,增加测试间隔ID */FlsTst_CurrentTestIntervalId++;FlsTst_CurrentBlock = 0;/* 重新开始第一个块的测试 */FlsTst_InitializeBlockTest(0);return;}/* 初始化新块的测试 */FlsTst_InitializeBlockTest(FlsTst_CurrentBlock);}/* 测试当前位置的内存单元 */testResult = FlsTst_TestMemoryCell(FlsTst_CurrentBlockAddress);/* 检查测试结果 */if (testResult != FLSTST_TEST_OK) {/* 测试失败,报告错误 */FlsTst_TestResult = FLSTST_FAILED;/* 记录失败详情 */FlsTst_RecordTestFailure(FlsTst_CurrentBlock, FlsTst_CurrentBlockAddress, testResult);/* 报告诊断事件 */Dem_ReportErrorStatus(FlsTst_ConfigPtr->FlsTstDemEventIdBgnd, DEM_EVENT_STATUS_FAILED);/* 中止测试 */FlsTst_State = FLSTST_INIT;return;}/* 更新测试进度 */FlsTst_CurrentBlockAddress++;FlsTst_TestedCellsInBlock++;cellsToTest--;}
}/* 初始化块测试 */
static void FlsTst_InitializeBlockTest(uint32 blockIdx)
{/* 获取块配置 */const FlsTst_BlockConfigType* blockConfig = &FlsTst_ConfigPtr->FlsTstBlockConfig[blockIdx];/* 设置块参数 */FlsTst_CurrentBlockAddress = blockConfig->FlsTstBlockBaseAddress;FlsTst_CurrentBlockSize = blockConfig->FlsTstBlockSize;FlsTst_TestedCellsInBlock = 0;
}/* 测试内存单元函数 */
static uint8 FlsTst_TestMemoryCell(uint32 address)
{uint8 readValue;uint8 expectedValue;/* 根据配置的测试算法进行测试 */switch (FlsTst_ConfigPtr->FlsTstBlockConfig[FlsTst_CurrentBlock].FlsTstBlockTestAlgorithm) {case FLSTST_ALGORITHM_CHECKSUM:/* 执行校验和测试 */return FlsTst_PerformChecksumTest(address);case FLSTST_ALGORITHM_CRC:/* 执行CRC测试 */return FlsTst_PerformCrcTest(address);case FLSTST_ALGORITHM_CUSTOM:/* 执行自定义测试 */return FlsTst_PerformCustomTest(address);default:/* 无效算法 */return FLSTST_TEST_INVALID_ALGORITHM;}
}
5. API详解
5.1 初始化与去初始化
Flash Test模块提供以下初始化与去初始化API:
函数 FlsTst_Init
:
- 描述: 初始化Flash Test模块,必须在使用其他API前调用
- 参数:
ConfigPtr
[输入]: 指向配置数据的指针,类型: const FlsTst_ConfigType*,取值范围: 非NULL有效指针
- 返回值: 无
- 相关函数:
- 上层: 应用初始化函数
- 下层: 无
函数 FlsTst_DeInit
:
- 描述: 去初始化Flash Test模块
- 参数: 无
- 返回值: 无
- 相关函数:
- 上层: 应用终止函数
- 下层: 无
5.2 测试执行控制
Flash Test模块提供以下测试执行控制API:
函数 FlsTst_StartForeground
:
- 描述: 启动前台测试(同步测试)
- 参数: 无
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败
- 相关函数:
- 上层: 应用测试函数
- 下层: 内部测试执行函数
函数 FlsTst_StartBackground
:
- 描述: 启动后台测试(异步测试)
- 参数: 无
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败
- 相关函数:
- 上层: 应用测试函数
- 下层: 内部测试准备函数
函数 FlsTst_Suspend
:
- 描述: 暂停当前运行的后台测试
- 参数: 无
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败(如模块状态不正确)
- 相关函数:
- 上层: 应用控制函数
- 下层: 内部状态保存函数
函数 FlsTst_Resume
:
- 描述: 恢复之前暂停的后台测试
- 参数: 无
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败(如模块状态不正确)
- 相关函数:
- 上层: 应用控制函数
- 下层: 内部状态恢复函数
函数 FlsTst_Abort
:
- 描述: 中止当前的测试
- 参数: 无
- 返回值: 无
- 相关函数:
- 上层: 应用控制函数
- 下层: 内部清理函数
函数 FlsTst_MainFunction
:
- 描述: 执行后台测试的部分测试步骤,由调度器定期调用
- 参数: 无
- 返回值: 无
- 相关函数:
- 上层: BSW调度器
- 下层: 内部测试执行函数
5.3 状态与结果查询
Flash Test模块提供以下状态和结果查询API:
函数 FlsTst_GetTestStatus
:
- 描述: 获取当前测试状态
- 参数:
StatePtr
[输出]: 存储当前状态的指针,类型: FlsTst_StateType*,取值范围: 非NULL有效指针
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败(如参数无效)
- 相关函数:
- 上层: 应用状态查询函数
- 下层: 无
函数 FlsTst_GetTestResult
:
- 描述: 获取最近一次测试的结果
- 参数:
ResultPtr
[输出]: 存储测试结果的指针,类型: FlsTst_TestResultType*,取值范围: 非NULL有效指针
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败(如参数无效)
- 相关函数:
- 上层: 应用结果查询函数
- 下层: 无
函数 FlsTst_GetTestSignature
:
- 描述: 获取测试的签名值(如CRC结果)
- 参数:
SignaturePtr
[输出]: 存储签名值的指针,类型: uint32*,取值范围: 非NULL有效指针
- 返回值:
- E_OK: 操作成功
- E_NOT_OK: 操作失败(如参数无效)
- 相关函数:
- 上层: 应用签名查询函数
- 下层: 无
API使用示例:
/* Flash Test模块API使用示例 */
void Application_InitializeFlashTest(void)
{/* 初始化Flash Test模块 */FlsTst_Init(&FlsTst_Config);/* 启动后台测试 */if (FlsTst_StartBackground() != E_OK) {/* 处理错误 */Application_HandleFlashTestError();}
}void Application_CheckFlashTestStatus(void)
{FlsTst_StateType currentState;FlsTst_TestResultType testResult;/* 获取当前测试状态 */if (FlsTst_GetTestStatus(¤tState) == E_OK) {if (currentState == FLSTST_RUNNING) {/* 测试正在运行 *//* 可能需要暂停测试以执行其他操作 */FlsTst_Suspend();} else if (currentState == FLSTST_INIT) {/* 测试未运行,可以启动新测试 */FlsTst_StartBackground();}}/* 检查测试结果 */if (FlsTst_GetTestResult(&testResult) == E_OK) {if (testResult == FLSTST_FAILED) {/* 测试失败,执行恢复操作 */Application_HandleFlashTestFailure();}}
}void Application_TemporaryPauseFlashTest(void)
{FlsTst_StateType currentState;/* 获取当前测试状态 */if (FlsTst_GetTestStatus(¤tState) == E_OK) {if (currentState == FLSTST_RUNNING) {/* 暂停测试 */FlsTst_Suspend();/* 执行需要暂停测试的操作 */Application_PerformSpecialOperation();/* 恢复测试 */FlsTst_Resume();}}
}
6. 错误处理机制
Flash Test模块实现了全面的错误处理机制,包括开发错误和运行时错误:
-
开发错误处理:
- 通过DET (Default Error Tracer) 报告开发阶段的错误
- 典型开发错误包括:无效参数、未初始化调用、无效的状态转换
-
运行时错误处理:
- 通过DEM (Diagnostic Event Manager) 报告运行时错误
- 主要运行时错误:内存测试失败、签名不匹配
- 测试失败会导致测试中止并报告错误
-
错误码定义:
- 源文档中提到,错误码0x05已被修改,用于表示特定失败条件
错误处理代码示例:
/* 错误处理代码示例 *//* 开发错误码定义 */
#define FLSTST_E_UNINIT 0x01 /* 模块未初始化 */
#define FLSTST_E_ALREADY_INIT 0x02 /* 模块已初始化 */
#define FLSTST_E_PARAM_POINTER 0x03 /* 参数指针无效 */
#define FLSTST_E_INVALID_STATE 0x04 /* 无效状态 */
#define FLSTST_E_PARAM_VALUE 0x05 /* 参数值无效 *//* 初始化函数中的错误处理 */
void FlsTst_Init(const FlsTst_ConfigType* ConfigPtr)
{/* 检查是否已初始化 */if (FlsTst_State != FLSTST_UNINIT) {/* 报告开发错误:重复初始化 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_INIT_ID, FLSTST_E_ALREADY_INIT);return;}/* 参数指针检查 */if (ConfigPtr == NULL) {/* 报告开发错误:无效指针 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_INIT_ID, FLSTST_E_PARAM_POINTER);return;}/* 配置参数有效性检查 */if (FlsTst_CheckConfigValidity(ConfigPtr) == FALSE) {/* 报告开发错误:无效参数值 */Det_ReportError(FLSTST_MODULE_ID, FLSTST_INSTANCE_ID, FLSTST_INIT_ID, FLSTST_E_PARAM_VALUE);return;}/* 正常初始化流程... */
}/* 内存测试失败处理 */
static void FlsTst_HandleTestFailure(uint32 blockIdx, uint32 address, uint8 errorType)
{/* 记录错误详情 */FlsTst_ErrorInfo.BlockIdx = blockIdx;FlsTst_ErrorInfo.Address = address;FlsTst_ErrorInfo.ErrorType = errorType;/* 更新测试结果 */FlsTst_TestResult = FLSTST_FAILED;/* 报告诊断事件 */if (FlsTst_ConfigPtr->FlsTstDemEventIdRef != 0) {if (FlsTst_IsBackgroundTestActive) {Dem_ReportErrorStatus(FlsTst_ConfigPtr->FlsTstDemEventIdBgnd, DEM_EVENT_STATUS_FAILED);} else {Dem_ReportErrorStatus(FlsTst_ConfigPtr->FlsTstDemEventIdFgnd, DEM_EVENT_STATUS_FAILED);}}/* 中止后台测试 */if (FlsTst_IsBackgroundTestActive) {FlsTst_State = FLSTST_INIT;}
}
7. 总结与应用场景
总结
AUTOSAR Flash Test模块是一个专门设计用于测试不变存储器的基础软件模块,具有以下主要特点:
-
灵活的测试机制:
- 支持前台(同步)和后台(异步)测试模式
- 可配置的测试块和测试算法
- 支持测试暂停、恢复和中止
-
强大的状态管理:
- 清晰定义的状态转换
- 完整的状态查询接口
- 精确的错误处理机制
-
高度可配置性:
- 可配置的测试块和大小
- 可配置的测试单元数量
- 可选的测试算法
-
集成安全机制:
- 与DEM集成报告诊断事件
- 与DET集成报告开发错误
- 支持测试结果和签名查询
应用场景
Flash Test模块特别适用于以下应用场景:
-
安全关键型应用:
- 需要定期验证内存完整性的场景
- 需要满足功能安全标准(如ISO 26262)的系统
- 需要确保代码和数据未被篡改的场景
-
嵌入式控制系统:
- 汽车电子控制单元(ECU)
- 工业控制系统
- 需要监控Flash内存健康状态的设备
-
有预防性维护需求的系统:
- 需要提前检测存储器故障的场景
- 需要定期验证系统关键数据完整性的应用
-
高可靠性要求的系统:
- 远程或难以维护的设备
- 长期运行不中断的系统
- 需要高可靠性保障的关键应用
Flash Test模块作为AUTOSAR基础软件的一部分,为开发者提供了标准化的接口和功能,简化了不变存储器测试的实现,同时确保了测试功能的可靠性和一致性。