文章目录
前言
在嵌入式系统开发中,故障管理是保障系统稳定运行的关键一环。当系统出现异常时,及时准确地记录和处理故障信息,不仅有助于快速定位问题,还能为系统的优化和维护提供重要依据。本文将基于一套实际的嵌入式故障码管理系统代码,详细介绍其设计思路与实现方法。
一、故障码管理系统概述
该故障码管理系统旨在为嵌入式设备提供全面的故障记录、存储与处理能力。它能够记录系统运行过程中出现的各种故障,包括不同模块产生的不同类型故障,并根据故障的严重程度进行分类处理。同时,系统还支持故障记录的存储、查询、清除以及自检等功能,确保故障信息的完整性和准确性。
故障码管理系统主要分为两大模块:
-
FaultManager(故障管理器)
负责对外提供初始化、记录故障、查询故障、清除故障、系统自检等功能接口,并维护内部状态(如是否已初始化、已记录故障数量等)。 -
FaultStorage(故障存储)
提供对故障记录的持久化后端支持,可根据需求选择 Flash 存储或 RAM 环境下的环形/数组存储实现。包含初始化、添加记录、获取记录、删除记录和清空记录等操作。
两者通过明确定义的接口契约解耦,FaultManager 不关心底层存储细节,只要调用 FaultStorage_* 系列接口即可。
设计特点:
-
多级分类:支持Info/Warning/Error/Critical四级故障
-
模块化设计:各功能模块独立,便于扩展
-
双存储引擎:RAM缓存+Flash持久化
-
低资源占用:适合资源受限的MCU环境
二、核心数据结构设计
2.1 故障严重等级定义
typedef enum {
FAULT_SEVERITY_INFO = 0, // 信息类故障
FAULT_SEVERITY_WARNING, // 警告类故障
FAULT_SEVERITY_ERROR, // 错误类故障
FAULT_SEVERITY_CRITICAL // 严重故障
} FaultSeverity_t;
通过枚举类型定义了故障的四种严重等级。信息类故障用于提示系统的一般运行信息,如软件版本更新提示;警告类故障表示系统出现潜在问题,如磁盘空间即将不足;错误类故障会导致部分功能失效,如网络连接中断;严重故障则可能危及系统安全,如电源电压骤降,为后续分级处理故障提供了清晰标准。
2.2 模块 ID 定义
typedef enum {
FAULT_MODULE_SYSTEM = 0, // 系统模块
FAULT_MODULE_POWER, // 电源模块
FAULT_MODULE_COMM, // 通信模块
FAULT_MODULE_SENSOR, // 传感器模块
FAULT_MODULE_ACTUATOR, // 执行器模块
FAULT_MODULE_CUSTOM // 自定义模块
} FaultModule_t;
该枚举类型明确标识了嵌入式系统中常见的故障模块。不同模块对应不同的硬件或软件功能单元,例如电源模块负责供电,通信模块处理数据传输,传感器模块采集环境数据等,使得故障定位更具针对性。
2.3 故障代码结构
typedef union {
uint32_t code;
struct {
uint16_t module_id : 8; // 模块ID
uint16_t error_id : 8; // 错误ID
uint16_t severity : 4; // 严重等级
uint16_t reserved : 12; // 保留位
} fields;
} FaultCode_t;
采用联合体与结构体结合的设计,code 作为一个 32 位整数可整体存储和传输故障码,fields 结构体则将其拆分为具体信息。8 位的模块 ID 能区分多达 256 种不同模块,8 位的错误 ID 可定义 256 种具体错误类型,4 位的严重等级对应前述四种故障级别,12 位保留位为未来功能扩展预留空间。
2.4 故障记录结构
typedef struct {
FaultCode_t fault_code; // 故障代码
uint32_t timestamp; // 时间戳(ms)
uint8_t context[4]; // 上下文数据
} FaultRecord_t;
FaultRecord_t 结构体完整描述一次故障。fault_code 包含故障的类型和严重程度信息;timestamp 基于系统时钟获取故障发生的精确时刻,单位为毫秒,便于分析故障发生的时序;context 数组存储与故障相关的额外数据,如传感器的异常读数、通信数据包片段等,为故障分析提供更丰富的细节。
三、故障管理核心功能实现
3.1 初始化功能
bool FaultManager_Init(void)
{
if (fm_state.initialized) {
return true;
}
// 初始化存储子系统
if (!FaultStorage_Init()) {
return false;
}
// 获取记录数量
fm_state.record_count = FaultStorage_GetRecordCount();
fm_state.initialized = true;
return true;
}
FaultManager_Init 函数首先检查系统是否已经初始化,如果已初始化则直接返回 true。接着调用 FaultStorage_Init 函数初始化故障存储子系统,若初始化失败则返回 false。成功初始化存储子系统后,获取已有的故障记录数量,并将系统初始化状态标志 fm_state.initialized 设置为 true,最后返回 true 表示初始化成功。
3.2 故障记录功能
void FaultManager_LogFault(FaultCode_t code, const uint8_t* context)
{
if (!fm_state.initialized) {
return;
}
FaultRecord_t record;
record.fault_code = code;
record.timestamp = HAL_GetTick(); // 假设使用HAL库
if (context != NULL) {
memcpy(record.context, context, sizeof(record.context));
} else {
memset(record.context, 0, sizeof(record.context));
}
// 存储记录
if (FaultStorage_AddRecord(&record)) {
fm_state.record_count++;
}
// 根据故障等级处理
switch (code.fields.severity) {
case FAULT_SEVERITY_CRITICAL:
// 严重故障可能需要系统复位
break;
case FAULT_SEVERITY_ERROR:
// 错误处理逻辑
break;
default:
break;
}
}
FaultManager_LogFault 函数用于记录故障信息。首先检查系统是否已经初始化,若未初始化则直接返回。然后创建一个 FaultRecord_t 类型的变量 record,将传入的故障代码 code 和当前时间戳(通过 HAL_GetTick 函数获取)赋值给 record。如果存在上下文数据,则将其复制到 record.context 中;否则将 record.context 清零。接着调用 FaultStorage_AddRecord 函数将故障记录存储到存储系统中,如果存储成功则更新故障记录数量。最后根据故障的严重程度,在 switch 语句中执行相应的处理逻辑,对于严重故障可能需要考虑系统复位等操作,对于其他故障可进行相应的错误处理。
3.3 记录查询与清除功能
uint16_t FaultManager_GetRecordCount(void)
{
return fm_state.record_count;
}
bool FaultManager_GetRecord(uint16_t index, FaultRecord_t* record)
{
if (!fm_state.initialized || record == NULL) {
return false;
}
if (index >= fm_state.record_count) {
return false;
}
return FaultStorage_GetRecord(index, record);
}
void FaultManager_ClearAllRecords(void)
{
if (!fm_state.initialized) {
return;
}
FaultStorage_ClearAll();
fm_state.record_count = 0;
}
FaultManager_GetRecordCount 函数直接返回当前已记录的故障数量。FaultManager_GetRecord 函数用于获取指定索引的故障记录,首先检查系统是否初始化以及传入的记录指针是否有效,然后判断索引是否越界,若都满足条件则调用 FaultStorage_GetRecord 函数从存储系统中获取记录。FaultManager_ClearAllRecords 函数用于清除所有故障记录,同样先检查系统初始化状态,然后调用 FaultStorage_ClearAll 函数清除存储系统中的所有记录,并将记录数量清零。
3.4 系统自检功能
bool FaultManager_SelfTest(void)
{
if (!fm_state.initialized) {
return false;
}
// 测试存储系统
FaultRecord_t test_record = {
.fault_code = {.fields = {
.module_id = FAULT_MODULE_SYSTEM,
.error_id = 0xFF,
.severity = FAULT_SEVERITY_INFO
}},
.timestamp = HAL_GetTick(),
.context = {0xAA, 0x55, 0xAA, 0x55}
};
uint16_t old_count = fm_state.record_count;
// 添加测试记录
FaultManager_LogFault(test_record.fault_code, test_record.context);
// 验证记录
FaultRecord_t read_record;
if (!FaultManager_GetRecord(old_count, &read_record)) {
return false;
}
// 比较记录内容
if (memcmp(&test_record, &read_record, sizeof(FaultRecord_t)) != 0) {
return false;
}
// 恢复原始状态
FaultStorage_DeleteRecord(old_count);
fm_state.record_count = old_count;
return true;
}
FaultManager_SelfTest 函数用于对故障管理系统进行自检。先检查系统是否初始化,若未初始化则返回 false。创建一个测试用的 FaultRecord_t 类型变量 test_record,设置好故障代码、时间戳和上下文数据。记录下当前的故障记录数量 old_count,然后调用 FaultManager_LogFault 函数添加测试记录。接着尝试获取刚刚添加的测试记录,如果获取失败则返回 false。将获取到的记录与测试记录进行内容比较,如果不一致也返回 false。最后删除测试记录,恢复原始的记录数量,并返回 true 表示自检通过。
四、故障存储实现
4.1 Flash 存储实现
bool FaultStorage_Init(void)
{
// 检查Flash是否为空
uint32_t addr = FLASH_BASE_ADDR;
storage_state.record_count = 0;
while (addr < FLASH_BASE_ADDR + (MAX_RECORDS * RECORD_SIZE)) {
uint32_t value = *(__IO uint32_t*)addr;
if (value == 0xFFFFFFFF) {
break;
}
storage_state.record_count++;
addr += RECORD_SIZE;
}
storage_state.next_write_addr = FLASH_BASE_ADDR +
(storage_state.record_count * RECORD_SIZE);
return true;
}
FaultStorage_Init 函数用于初始化 Flash 存储。通过遍历 Flash 存储区域,检查每个记录存储单元的值,如果值为 0xFFFFFFFF(表示未使用)则停止遍历,同时记录已有的记录数量 record_count,并计算出下一个可写入地址 next_write_addr。
bool FaultStorage_AddRecord(const FaultRecord_t* record)
{
if (record == NULL || storage_state.record_count >= MAX_RECORDS) {
return false;
}
// 如果需要擦除扇区
if (storage_state.next_write_addr >= FLASH_BASE_ADDR +
(MAX_RECORDS * RECORD_SIZE)) {
FLASH_EraseInitTypeDef erase = {
.TypeErase = FLASH_TYPEERASE_SECTORS,
.Sector = FLASH_SECTOR,
.NbSectors = 1,
.VoltageRange = FLASH_VOLTAGE_RANGE_3
};
uint32_t sector_error;
HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&erase, §or_error) != HAL_OK) {
HAL_FLASH_Lock();
return false;
}
storage_state.next_write_addr = FLASH_BASE_ADDR;
storage_state.record_count = 0;
}
// 写入Flash
HAL_FLASH_Unlock();
uint32_t src = (uint32_t)record;
uint32_t dst = storage_state.next_write_addr;
uint32_t remaining = RECORD_SIZE;
while (remaining > 0) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, dst,
*(uint32_t*)src) != HAL_OK) {
HAL_FLASH_Lock();
return false;
}
dst += 4;
src += 4;
remaining -= 4;
}
HAL_FLASH_Lock();
storage_state.record_count++;
storage_state.next_write_addr += RECORD_SIZE;
return true;
}
FaultStorage_AddRecord 函数用于向 Flash 存储中添加故障记录。首先检查传入的记录指针是否有效以及存储记录数量是否达到上限,若不满足条件则返回 false。然后判断是否需要擦除扇区(当达到存储区域末尾时),如果需要则进行扇区擦除操作,擦除成功后更新存储状态。接着进行数据写入操作,将故障记录按字写入 Flash,写入过程中若出现错误则立即锁定 Flash 并返回 false。成功写入后更新记录数量和下一个写入地址,并返回 true。
4.2 RAM 存储实现
bool FaultStorage_Init(void)
{
memset(&ram_storage, 0, sizeof(ram_storage));
return true;
}
FaultStorage_Init 函数对于 RAM 存储的初始化非常简单,直接使用 memset 函数将存储状态结构体 ram_storage 清零即可。
bool FaultStorage_AddRecord(const FaultRecord_t* record)
{
if (record == NULL || ram_storage.record_count >= MAX_RAM_RECORDS) {
return false;
}
memcpy(&ram_storage.records[ram_storage.next_index],
record,
sizeof(FaultRecord_t));
ram_storage.next_index = (ram_storage.next_index + 1) % MAX_RAM_RECORDS;
if (ram_storage.record_count < MAX_RAM_RECORDS) {
ram_storage.record_count++;
}
return true;
}
FaultStorage_AddRecord 函数向 RAM 存储中添加故障记录。同样先检查记录指针有效性和存储数量上限,然后将记录复制到 ram_storage.records 数组的当前写入位置,更新写入索引 next_index,并根据记录数量是否达到上限决定是否增加记录数量,最后返回 true 表示添加成功。
五、测试案例
#include "fault_manager.h"
void example_usage(void)
{
// 初始化故障管理系统
FaultManager_Init();
// 记录一个电源模块的警告故障
FaultCode_t power_warning = {
.fields = {
.module_id = FAULT_MODULE_POWER,
.error_id = 0x01, // 假设0x01表示电压低
.severity = FAULT_SEVERITY_WARNING
}
};
uint8_t context[] = {0x0C, 0x22, 0x00, 0x00}; // 12.34V
FaultManager_LogFault(power_warning, context);
// 记录一个通信模块的错误故障
FaultCode_t comm_error = {
.fields = {
.module_id = FAULT_MODULE_COMM,
.error_id = 0x02, // 假设0x02表示超时
.severity = FAULT_SEVERITY_ERROR
}
};
FaultManager_LogFault(comm_error, NULL);
// 查询并打印所有故障记录
uint16_t count = FaultManager_GetRecordCount();
for (uint16_t i = 0; i < count; i++) {
FaultRecord_t record;
if (FaultManager_GetRecord(i, &record)) {
printf("[%lu] Module:%d, Error:%d, Sev:%d\n",
record.timestamp,
record.fault_code.fields.module_id,
record.fault_code.fields.error_id,
record.fault_code.fields.severity);
}
}
}
在 example_usage 测试函数中,首先调用 FaultManager_Init 函数初始化故障管理系统。接着模拟两个故障场景:记录一个电源模块的警告故障,设置故障代码表示电源模块电压低,同时提供包含电压数据的上下文信息;记录一个通信模块的错误故障,设置故障代码表示通信超时,未提供上下文数据。最后通过 FaultManager_GetRecordCount 和 FaultManager_GetRecord 函数查询并打印所有故障记录,直观展示故障记录功能的有效性,验证系统能够准确记录和查询故障信息,确保故障管理系统在实际应用中的可靠性。
谢谢你的翻阅,希望可以对你有所帮助!
六、源码
6.1 fault_manager.c
#include "fault_manager.h"
#include "fault_storage.h"
#include <string.h>
// 内部状态
static struct {
bool initialized;
uint16_t record_count;
} fm_state;
// 初始化故障管理系统
bool FaultManager_Init(void)
{
if (fm_state.initialized) {
return true;
}
// 初始化存储子系统
if (!FaultStorage_Init()) {
return false;
}
// 获取记录数量
fm_state.record_count = FaultStorage_GetRecordCount();
fm_state.initialized = true;
return true;
}
// 记录故障
void FaultManager_LogFault(FaultCode_t code, const uint8_t* context)
{
if (!fm_state.initialized) {
return;
}
FaultRecord_t record;
record.fault_code = code;
record.timestamp = HAL_GetTick(); // 假设使用HAL库
if (context != NULL) {
memcpy(record.context, context, sizeof(record.context));
} else {
memset(record.context, 0, sizeof(record.context));
}
// 存储记录
if (FaultStorage_AddRecord(&record)) {
fm_state.record_count++;
}
// 根据故障等级处理
switch (code.fields.severity) {
case FAULT_SEVERITY_CRITICAL:
// 严重故障可能需要系统复位
break;
case FAULT_SEVERITY_ERROR:
// 错误处理逻辑
break;
default:
break;
}
}
// 获取故障记录数量
uint16_t FaultManager_GetRecordCount(void)
{
return fm_state.record_count;
}
// 获取指定索引的故障记录
bool FaultManager_GetRecord(uint16_t index, FaultRecord_t* record)
{
if (!fm_state.initialized || record == NULL) {
return false;
}
if (index >= fm_state.record_count) {
return false;
}
return FaultStorage_GetRecord(index, record);
}
// 清除所有故障记录
void FaultManager_ClearAllRecords(void)
{
if (!fm_state.initialized) {
return;
}
FaultStorage_ClearAll();
fm_state.record_count = 0;
}
// 系统自检
bool FaultManager_SelfTest(void)
{
if (!fm_state.initialized) {
return false;
}
// 测试存储系统
FaultRecord_t test_record = {
.fault_code = {.fields = {
.module_id = FAULT_MODULE_SYSTEM,
.error_id = 0xFF,
.severity = FAULT_SEVERITY_INFO
}},
.timestamp = HAL_GetTick(),
.context = {0xAA, 0x55, 0xAA, 0x55}
};
uint16_t old_count = fm_state.record_count;
// 添加测试记录
FaultManager_LogFault(test_record.fault_code, test_record.context);
// 验证记录
FaultRecord_t read_record;
if (!FaultManager_GetRecord(old_count, &read_record)) {
return false;
}
// 比较记录内容
if (memcmp(&test_record, &read_record, sizeof(FaultRecord_t)) != 0) {
return false;
}
// 恢复原始状态
FaultStorage_DeleteRecord(old_count);
fm_state.record_count = old_count;
return true;
}
6.2 fault_manager.h
#ifndef FAULT_MANAGER_H
#define FAULT_MANAGER_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
// 故障严重等级定义
typedef enum {
FAULT_SEVERITY_INFO = 0, // 信息类故障
FAULT_SEVERITY_WARNING, // 警告类故障
FAULT_SEVERITY_ERROR, // 错误类故障
FAULT_SEVERITY_CRITICAL // 严重故障
} FaultSeverity_t;
// 模块ID定义
typedef enum {
FAULT_MODULE_SYSTEM = 0, // 系统模块
FAULT_MODULE_POWER, // 电源模块
FAULT_MODULE_COMM, // 通信模块
FAULT_MODULE_SENSOR, // 传感器模块
FAULT_MODULE_ACTUATOR, // 执行器模块
FAULT_MODULE_CUSTOM // 自定义模块
} FaultModule_t;
// 故障代码结构
typedef union {
uint32_t code;
struct {
uint16_t module_id : 8; // 模块ID
uint16_t error_id : 8; // 错误ID
uint16_t severity : 4; // 严重等级
uint16_t reserved : 12; // 保留位
} fields;
} FaultCode_t;
// 故障记录结构
typedef struct {
FaultCode_t fault_code; // 故障代码
uint32_t timestamp; // 时间戳(ms)
uint8_t context[4]; // 上下文数据
} FaultRecord_t;
// 初始化故障管理系统
bool FaultManager_Init(void);
// 记录故障
void FaultManager_LogFault(FaultCode_t code, const uint8_t* context);
// 获取故障记录数量
uint16_t FaultManager_GetRecordCount(void);
// 获取指定索引的故障记录
bool FaultManager_GetRecord(uint16_t index, FaultRecord_t* record);
// 清除所有故障记录
void FaultManager_ClearAllRecords(void);
// 系统自检
bool FaultManager_SelfTest(void);
#ifdef __cplusplus
}
#endif
#endif // FAULT_MANAGER_H
6.3 fault_storage.h
#ifndef FAULT_STORAGE_H
#define FAULT_STORAGE_H
#include "fault_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
// 初始化存储系统
bool FaultStorage_Init(void);
// 添加故障记录
bool FaultStorage_AddRecord(const FaultRecord_t* record);
// 获取故障记录数量
uint16_t FaultStorage_GetRecordCount(void);
// 获取指定索引的故障记录
bool FaultStorage_GetRecord(uint16_t index, FaultRecord_t* record);
// 删除指定索引的故障记录
bool FaultStorage_DeleteRecord(uint16_t index);
// 清除所有故障记录
void FaultStorage_ClearAll(void);
#ifdef __cplusplus
}
#endif
#endif // FAULT_STORAGE_H
6.4 fault_storage_flash.c
#include "fault_storage.h"
#include "stm32f4xx_hal.h" // 根据实际MCU修改
#include <string.h>
// Flash存储配置
#define FLASH_SECTOR FLASH_SECTOR_6
#define FLASH_BASE_ADDR 0x08040000 // 假设使用Sector 6
#define MAX_RECORDS 100 // 最大记录数
#define RECORD_SIZE sizeof(FaultRecord_t)
// 存储状态
static struct {
uint16_t record_count;
uint32_t next_write_addr;
} storage_state;
// 初始化Flash存储
bool FaultStorage_Init(void)
{
// 检查Flash是否为空
uint32_t addr = FLASH_BASE_ADDR;
storage_state.record_count = 0;
while (addr < FLASH_BASE_ADDR + (MAX_RECORDS * RECORD_SIZE)) {
uint32_t value = *(__IO uint32_t*)addr;
if (value == 0xFFFFFFFF) {
break;
}
storage_state.record_count++;
addr += RECORD_SIZE;
}
storage_state.next_write_addr = FLASH_BASE_ADDR +
(storage_state.record_count * RECORD_SIZE);
return true;
}
// 添加记录到Flash
bool FaultStorage_AddRecord(const FaultRecord_t* record)
{
if (record == NULL || storage_state.record_count >= MAX_RECORDS) {
return false;
}
// 如果需要擦除扇区
if (storage_state.next_write_addr >= FLASH_BASE_ADDR +
(MAX_RECORDS * RECORD_SIZE)) {
FLASH_EraseInitTypeDef erase = {
.TypeErase = FLASH_TYPEERASE_SECTORS,
.Sector = FLASH_SECTOR,
.NbSectors = 1,
.VoltageRange = FLASH_VOLTAGE_RANGE_3
};
uint32_t sector_error;
HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&erase, §or_error) != HAL_OK) {
HAL_FLASH_Lock();
return false;
}
storage_state.next_write_addr = FLASH_BASE_ADDR;
storage_state.record_count = 0;
}
// 写入Flash
HAL_FLASH_Unlock();
uint32_t src = (uint32_t)record;
uint32_t dst = storage_state.next_write_addr;
uint32_t remaining = RECORD_SIZE;
while (remaining > 0) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, dst,
*(uint32_t*)src) != HAL_OK) {
HAL_FLASH_Lock();
return false;
}
dst += 4;
src += 4;
remaining -= 4;
}
HAL_FLASH_Lock();
storage_state.record_count++;
storage_state.next_write_addr += RECORD_SIZE;
return true;
}
// 获取记录数量
uint16_t FaultStorage_GetRecordCount(void)
{
return storage_state.record_count;
}
// 从Flash获取记录
bool FaultStorage_GetRecord(uint16_t index, FaultRecord_t* record)
{
if (index >= storage_state.record_count || record == NULL) {
return false;
}
uint32_t addr = FLASH_BASE_ADDR + (index * RECORD_SIZE);
memcpy(record, (void*)addr, RECORD_SIZE);
return true;
}
// 删除记录(Flash中不支持单独删除,只能全部擦除)
bool FaultStorage_DeleteRecord(uint16_t index)
{
// Flash实现中不支持单独删除
return false;
}
// 清除所有记录
void FaultStorage_ClearAll(void)
{
FLASH_EraseInitTypeDef erase = {
.TypeErase = FLASH_TYPEERASE_SECTORS,
.Sector = FLASH_SECTOR,
.NbSectors = 1,
.VoltageRange = FLASH_VOLTAGE_RANGE_3
};
uint32_t sector_error;
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&erase, §or_error);
HAL_FLASH_Lock();
storage_state.record_count = 0;
storage_state.next_write_addr = FLASH_BASE_ADDR;
}
6.5 fault_storage_ram.c
#include "fault_storage.h"
#include <string.h>
// RAM存储配置
#define MAX_RAM_RECORDS 50 // RAM中最大记录数
// 存储状态
static struct {
FaultRecord_t records[MAX_RAM_RECORDS];
uint16_t record_count;
uint16_t next_index;
} ram_storage;
// 初始化RAM存储
bool FaultStorage_Init(void)
{
memset(&ram_storage, 0, sizeof(ram_storage));
return true;
}
// 添加记录到RAM
bool FaultStorage_AddRecord(const FaultRecord_t* record)
{
if (record == NULL || ram_storage.record_count >= MAX_RAM_RECORDS) {
return false;
}
memcpy(&ram_storage.records[ram_storage.next_index],
record,
sizeof(FaultRecord_t));
ram_storage.next_index = (ram_storage.next_index + 1) % MAX_RAM_RECORDS;
if (ram_storage.record_count < MAX_RAM_RECORDS) {
ram_storage.record_count++;
}
return true;
}
// 获取记录数量
uint16_t FaultStorage_GetRecordCount(void)
{
return ram_storage.record_count;
}
// 从RAM获取记录
bool FaultStorage_GetRecord(uint16_t index, FaultRecord_t* record)
{
if (index >= ram_storage.record_count || record == NULL) {
return false;
}
uint16_t actual_index;
if (ram_storage.record_count < MAX_RAM_RECORDS) {
actual_index = index;
} else {
actual_index = (ram_storage.next_index + index) % MAX_RAM_RECORDS;
}
memcpy(record, &ram_storage.records[actual_index], sizeof(FaultRecord_t));
return true;
}
// 删除RAM中的记录
bool FaultStorage_DeleteRecord(uint16_t index)
{
if (index >= ram_storage.record_count) {
return false;
}
if (ram_storage.record_count < MAX_RAM_RECORDS) {
// 简单数组,移动后面的元素
for (uint16_t i = index; i < ram_storage.record_count - 1; i++) {
memcpy(&ram_storage.records[i],
&ram_storage.records[i + 1],
sizeof(FaultRecord_t));
}
} else {
// 环形缓冲区,实现更复杂
// 这里简化处理,不支持删除
return false;
}
ram_storage.record_count--;
return true;
}
// 清除所有RAM记录
void FaultStorage_ClearAll(void)
{
ram_storage.record_count = 0;
ram_storage.next_index = 0;
}
6.6 example_usage
#include "fault_manager.h"
void example_usage(void)
{
// 初始化故障管理系统
FaultManager_Init();
// 记录一个电源模块的警告故障
FaultCode_t power_warning = {
.fields = {
.module_id = FAULT_MODULE_POWER,
.error_id = 0x01, // 假设0x01表示电压低
.severity = FAULT_SEVERITY_WARNING
}
};
uint8_t context[] = {0x0C, 0x22, 0x00, 0x00}; // 12.34V
FaultManager_LogFault(power_warning, context);
// 记录一个通信模块的错误故障
FaultCode_t comm_error = {
.fields = {
.module_id = FAULT_MODULE_COMM,
.error_id = 0x02, // 假设0x02表示超时
.severity = FAULT_SEVERITY_ERROR
}
};
FaultManager_LogFault(comm_error, NULL);
// 查询并打印所有故障记录
uint16_t count = FaultManager_GetRecordCount();
for (uint16_t i = 0; i < count; i++) {
FaultRecord_t record;
if (FaultManager_GetRecord(i, &record)) {
printf("[%lu] Module:%d, Error:%d, Sev:%d\n",
record.timestamp,
record.fault_code.fields.module_id,
record.fault_code.fields.error_id,
record.fault_code.fields.severity);
}
}
}