- 新增混流解析函数 `parse_mixed_stream()`,支持标准包与光泵包交替出现的二进制文件 - 新增光泵磁力仪模拟器 `OpticMagSimulatorThread`,以可配置频率发送BCD帧 - 新增光泵磁场显示标签页,支持文件模式与实时模式下的磁场曲线绘制 - 新增 `flash_counter` 模块,用于NOFX模式下文件序号持久化 ♻️ refactor(data_storage): 重构数据存储目录与文件命名策略 - 会话目录改为按GPS日期命名(YYYYMMDD),无GPS时使用NOFX目录 - 文件命名改为基于GPS时间(HHMMSS)或Flash计数器(C开头),消除序号文件依赖 - 移除 `config_manager` 依赖和 `PARAM.TXT` 序号文件读写逻辑 - 新增 `GPS_ParseGPRMC()` 解析函数,提取日期字段用于目录命名 🐛 fix(ltc2508_driver): 修复DMA启动失败时资源泄漏问题 - SPI2/SPI3 DMA启动失败时主动停止已启动的DMA,防止资源泄漏 - 将SPI1的dummy发送缓冲区改为static,确保DMA传输期间数据有效 🐛 fix(rs485_driver): 修复DMA发送缓冲区可能被覆盖的问题 - 引入静态发送缓冲区 `s_tx_buf`,隔离调用方数据与DMA传输,防止TIM2 ISR覆盖 ♻️ refactor(ATEMParse): 重构数据结构定义与解析逻辑 - 移除硬编码的V1/V2 dtype,改为动态构建 `make_dtype()` 函数 - 新增数据格式选项(GPS经纬度/光泵),支持灵活配置 - 新增文件模式下的分页浏览功能(滑块/上一页/下一页) - 优化实时模式下的光泵数据显示与表格列过滤
92 lines
3.3 KiB
C
92 lines
3.3 KiB
C
#ifndef DATA_STORAGE_H
|
||
#define DATA_STORAGE_H
|
||
|
||
#include "main.h"
|
||
#include "app_config.h"
|
||
#include "fatfs.h"
|
||
#include "ff.h"
|
||
#include "data_packet.h"
|
||
#include "correction.h"
|
||
#include "flash_counter.h"
|
||
#include "gps_driver.h"
|
||
#include <stdint.h>
|
||
|
||
// 数据存储配置(数值由 app_config.h 中 CFG_* 统一管理)
|
||
#define DATA_STORAGE_BUFFER_SIZE CFG_STORAGE_BUFFER_SIZE
|
||
#define DATA_STORAGE_FILE_MAX_SIZE CFG_STORAGE_FILE_MAX_SIZE
|
||
#define DATA_STORAGE_BASE_PATH "0:/DATA" // 数据存储基础路径
|
||
#define DATA_STORAGE_NOFX_DIR "0:/DATA/NOFX" // 无GPS定位时的目录
|
||
#define DATA_STORAGE_MAX_PATH_LEN 128 // 最大路径长度
|
||
|
||
// 缓冲区状态
|
||
typedef enum {
|
||
BUFFER_IDLE = 0, // 缓冲区空闲
|
||
BUFFER_WRITING, // 正在写入数据
|
||
BUFFER_READY_TO_FLUSH, // 准备刷新到文件
|
||
BUFFER_FLUSHING // 正在刷新到文件
|
||
} BufferState_t;
|
||
|
||
// 数据存储状态
|
||
typedef enum {
|
||
DATA_STORAGE_IDLE = 0,
|
||
DATA_STORAGE_RECORDING,
|
||
DATA_STORAGE_ERROR,
|
||
DATA_STORAGE_FULL
|
||
} DataStorageState_t;
|
||
|
||
// 数据存储统计信息
|
||
typedef struct {
|
||
uint32_t total_samples;
|
||
uint32_t current_file_size;
|
||
uint32_t file_count;
|
||
uint32_t error_count;
|
||
DataStorageState_t state;
|
||
char current_filename[256];
|
||
} DataStorageStats_t;
|
||
|
||
// 双缓冲区结构
|
||
typedef struct {
|
||
uint8_t data[DATA_STORAGE_BUFFER_SIZE];
|
||
uint16_t index;
|
||
BufferState_t state;
|
||
} DataBuffer_t;
|
||
|
||
// 数据存储句柄
|
||
typedef struct {
|
||
FIL file;
|
||
DataBuffer_t buffers[2]; // 双缓冲区
|
||
uint8_t active_buffer; // 当前活动缓冲区索引 (0 或 1)
|
||
uint8_t flush_buffer; // 待刷新缓冲区索引
|
||
DataStorageStats_t stats;
|
||
uint8_t initialized;
|
||
uint8_t flush_in_progress; // 刷新进行中标志
|
||
char current_session_path[DATA_STORAGE_MAX_PATH_LEN]; // 当前会话文件夹路径
|
||
uint32_t file_counter; // NOFX模式下的文件序号(从Flash读取后+1000)
|
||
} DataStorageHandle_t;
|
||
|
||
// 函数声明
|
||
HAL_StatusTypeDef DataStorage_Init(DataStorageHandle_t *handle);
|
||
HAL_StatusTypeDef DataStorage_StartRecording(DataStorageHandle_t *handle);
|
||
HAL_StatusTypeDef DataStorage_StopRecording(DataStorageHandle_t *handle);
|
||
HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataPacket_t *packet);
|
||
HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectedDataPacket_t *result);
|
||
HAL_StatusTypeDef DataStorage_Flush(DataStorageHandle_t *handle);
|
||
void DataStorage_GetStats(DataStorageHandle_t *handle, DataStorageStats_t *stats);
|
||
HAL_StatusTypeDef DataStorage_CreateNewFile(DataStorageHandle_t *handle);
|
||
|
||
// 文件夹管理函数
|
||
HAL_StatusTypeDef DataStorage_CreateSessionFolder(DataStorageHandle_t *handle);
|
||
|
||
// 双缓冲区管理函数
|
||
HAL_StatusTypeDef DataStorage_SwitchBuffer(DataStorageHandle_t *handle);
|
||
HAL_StatusTypeDef DataStorage_FlushBuffer(DataStorageHandle_t *handle, uint8_t buffer_index);
|
||
void DataStorage_ProcessBackgroundTasks(DataStorageHandle_t *handle);
|
||
|
||
// 缓冲区可用性检查函数
|
||
uint8_t DataStorage_IsBufferAvailable(DataStorageHandle_t *handle, uint32_t required_size);
|
||
|
||
// 通用字节流写入(支持任意包类型,方案Y混流存储)
|
||
HAL_StatusTypeDef DataStorage_WriteRawBytes(DataStorageHandle_t *handle, const uint8_t *data, uint16_t size);
|
||
|
||
#endif // DATA_STORAGE_H
|