# Flash 错误存储方案

## 概述

将关键错误信息存储到 Flash，以便产品回收时分析产品弱点。

## 关于硬件故障（HardFault）

### ⚠️ 重要限制

**硬件故障时可能来不及写入 Flash**，原因：

1. **系统状态不稳定**：HardFault 发生时，系统可能已经损坏
2. **Flash 写入需要时间**：Flash 写入操作需要几毫秒到几十毫秒
3. **中断可能被禁用**：HardFault 处理程序可能运行在禁用中断的状态

### ✅ 推荐方案

**在正常运行时记录关键状态**，而不是在 HardFault 时：

1. **定期检查**：定期检查系统状态，记录异常
2. **错误捕获**：在错误处理函数中记录错误
3. **状态快照**：在关键操作前后记录状态快照

## 可以存储的错误数据

### 1. 系统错误

- 错误代码
- 时间戳
- 错误上下文（文件名、行号等）
- 系统状态（堆栈使用、内存使用等）

### 2. 硬件故障信息

- 程序计数器 (PC)
- 链接寄存器 (LR)
- 栈指针 (SP)
- 故障类型（MemManage、BusFault、UsageFault 等）
- 故障地址（如果可用）

### 3. 传感器错误

- 传感器类型
- 错误代码
- 校准数据
- 采样数据

### 4. BLE 错误

- 连接状态
- 错误代码
- 服务状态

### 5. 校准错误

- 校准类型
- 校准数据
- 验证结果

## 实现方案

### 数据结构

```c
typedef struct {
    uint32_t magic;           /* 魔数，用于验证 */
    uint32_t timestamp;      /* 时间戳 */
    uint8_t type;            /* 错误类型 */
    uint8_t code;            /* 错误代码 */
    uint16_t data_len;       /* 数据长度 */
    uint8_t data[64];        /* 错误数据 */
    uint32_t crc;            /* CRC 校验 */
} error_log_entry_t;
```

### 存储位置

使用 NVS (Non-Volatile Storage) 存储错误日志：
- 分区：`storage_partition`
- 最多存储 50 条错误记录
- 使用环形缓冲区，自动覆盖旧记录

### 使用示例

```c
/* 记录系统错误 */
error_log_write(ERROR_TYPE_SYSTEM, 0x01, NULL, 0);

/* 记录传感器错误 */
uint8_t sensor_data[] = {0x01, 0x02, 0x03};
error_log_write(ERROR_TYPE_SENSOR, 0x10, sensor_data, sizeof(sensor_data));

/* 记录硬件故障（在正常运行时调用） */
error_log_hardfault(pc, lr, sp, fault_type);

/* 读取所有错误日志 */
error_log_entry_t entries[50];
uint16_t count;
error_log_read(entries, 50, &count);
```

## 产品回收时的分析

### 可以分析的信息

1. **错误频率**：哪些错误最常发生
2. **错误模式**：错误发生的模式（时间、条件等）
3. **系统状态**：错误发生时的系统状态
4. **硬件问题**：硬件故障的类型和频率
5. **软件问题**：软件错误的位置和原因

### 分析工具

1. **通过 BLE NUS**：连接设备后，发送命令读取错误日志
2. **通过 USB**：如果支持 USB，可以通过 USB 读取
3. **通过 Flash 读取器**：直接读取 Flash 内容

## 最佳实践

### 1. 记录时机

- ✅ **正常运行时**：在错误处理函数中记录
- ✅ **定期检查**：定期检查系统状态，记录异常
- ❌ **HardFault 时**：不建议在 HardFault 处理程序中写入 Flash

### 2. 记录内容

- ✅ **关键信息**：错误代码、时间戳、上下文
- ✅ **系统状态**：堆栈、内存、关键变量
- ❌ **敏感信息**：避免记录用户数据、密钥等

### 3. 存储管理

- ✅ **限制数量**：最多存储 50 条记录
- ✅ **自动覆盖**：使用环形缓冲区，自动覆盖旧记录
- ✅ **CRC 校验**：每条记录都有 CRC 校验

### 4. 性能考虑

- ✅ **异步写入**：使用 NVS，写入操作是异步的
- ✅ **批量读取**：读取时批量读取所有记录
- ❌ **频繁写入**：避免频繁写入，影响 Flash 寿命

## 实现状态

### ✅ 已完成

1. 错误日志数据结构
2. NVS 存储实现
3. 错误记录和读取接口
4. CRC 校验

### ⏳ 待完成

1. 集成到错误处理函数
2. 添加定期状态检查
3. 通过 BLE NUS 读取错误日志的命令

## 注意事项

1. **Flash 寿命**：Flash 写入次数有限，避免频繁写入
2. **数据安全**：错误日志可能包含敏感信息，注意保护
3. **存储空间**：确保有足够的 Flash 空间存储错误日志
4. **读取方式**：确保有可靠的方式读取错误日志（BLE、USB 等）

