Add complete data acquisition pipeline with LTC2508 ADC drivers, correction algorithms, data storage, and system monitoring. Includes ARM DSP optimized matrix operations for sensor calibration, SD card data logging with USB mass storage, and robust error handling with validation throughout the processing chain. - Add LTC2508 multi-channel SPI driver with DMA support and error recovery - Implement correction module with ARM DSP matrix operations for sensor calibration - Add data storage system with SD card logging and configurable file management - Integrate system monitor for health tracking and error reporting - Enhance data packet structure with CRC validation and timestamps - Add USB mass storage interface for SD card access - Implement comprehensive error handling and statistics collection
195 lines
5.0 KiB
C
195 lines
5.0 KiB
C
#include "data_storage.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
/**
|
|
* @brief 初始化数据存储模块
|
|
* @param handle: 数据存储句柄指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_Init(DataStorageHandle_t *handle)
|
|
{
|
|
if (handle == NULL) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 初始化句柄
|
|
memset(handle, 0, sizeof(DataStorageHandle_t));
|
|
|
|
// 创建数据存储目录
|
|
FRESULT res = f_mkdir(DATA_STORAGE_PATH);
|
|
if (res != FR_OK && res != FR_EXIST) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
handle->stats.state = DATA_STORAGE_IDLE;
|
|
handle->initialized = 1;
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 停止数据记录
|
|
* @param handle: 数据存储句柄指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_StopRecording(DataStorageHandle_t *handle)
|
|
{
|
|
if (handle == NULL || !handle->initialized) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
if (handle->stats.state != DATA_STORAGE_RECORDING) {
|
|
return HAL_OK; // 没有在记录中
|
|
}
|
|
|
|
// 刷新缓冲区
|
|
DataStorage_Flush(handle);
|
|
|
|
// 关闭文件
|
|
f_close(&handle->file);
|
|
|
|
handle->stats.state = DATA_STORAGE_IDLE;
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 写入数据包到存储
|
|
* @param handle: 数据存储句柄指针
|
|
* @param packet: 数据包指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataPacket_t *packet)
|
|
{
|
|
if (handle == NULL || packet == NULL || !handle->initialized) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
if (handle->stats.state != DATA_STORAGE_RECORDING) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 检查缓冲区空间
|
|
if (handle->buffer_index + sizeof(DataPacket_t) > DATA_STORAGE_BUFFER_SIZE) {
|
|
// 刷新缓冲区
|
|
if (DataStorage_Flush(handle) != HAL_OK) {
|
|
handle->stats.error_count++;
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
// 复制数据到缓冲区
|
|
memcpy(&handle->buffer[handle->buffer_index], packet, sizeof(DataPacket_t));
|
|
handle->buffer_index += sizeof(DataPacket_t);
|
|
handle->stats.total_samples++;
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 刷新缓冲区到文件
|
|
* @param handle: 数据存储句柄指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_Flush(DataStorageHandle_t *handle)
|
|
{
|
|
if (handle == NULL || !handle->initialized || handle->buffer_index == 0) {
|
|
return HAL_OK;
|
|
}
|
|
|
|
UINT bytes_written;
|
|
FRESULT res = f_write(&handle->file, handle->buffer, handle->buffer_index, &bytes_written);
|
|
|
|
if (res != FR_OK || bytes_written != handle->buffer_index) {
|
|
handle->stats.error_count++;
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 同步到存储设备
|
|
f_sync(&handle->file);
|
|
|
|
handle->stats.current_file_size += bytes_written;
|
|
handle->buffer_index = 0;
|
|
|
|
// 检查文件大小是否超过限制
|
|
if (handle->stats.current_file_size >= DATA_STORAGE_FILE_MAX_SIZE) {
|
|
f_close(&handle->file);
|
|
DataStorage_CreateNewFile(handle);
|
|
}
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 创建新的数据文件
|
|
* @param handle: 数据存储句柄指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_CreateNewFile(DataStorageHandle_t *handle)
|
|
{
|
|
if (handle == NULL || !handle->initialized) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 生成文件名 (基于时间戳)
|
|
uint32_t timestamp = HAL_GetTick();
|
|
snprintf(handle->stats.current_filename, sizeof(handle->stats.current_filename),
|
|
"%s%s%08lX.dat", DATA_STORAGE_PATH, DATA_STORAGE_FILE_PREFIX, timestamp);
|
|
|
|
// 创建并打开文件
|
|
FRESULT res = f_open(&handle->file, handle->stats.current_filename,
|
|
FA_CREATE_ALWAYS | FA_WRITE);
|
|
|
|
if (res != FR_OK) {
|
|
handle->stats.error_count++;
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
handle->stats.file_count++;
|
|
handle->stats.current_file_size = 0;
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取数据存储统计信息
|
|
* @param handle: 数据存储句柄指针
|
|
* @param stats: 统计信息结构体指针
|
|
* @retval None
|
|
*/
|
|
void DataStorage_GetStats(DataStorageHandle_t *handle, DataStorageStats_t *stats)
|
|
{
|
|
if (handle == NULL || stats == NULL || !handle->initialized) {
|
|
return;
|
|
}
|
|
|
|
memcpy(stats, &handle->stats, sizeof(DataStorageStats_t));
|
|
}
|
|
|
|
/**
|
|
* @brief 开始数据记录
|
|
* @param handle: 数据存储句柄指针
|
|
* @retval HAL_StatusTypeDef
|
|
*/
|
|
HAL_StatusTypeDef DataStorage_StartRecording(DataStorageHandle_t *handle)
|
|
{
|
|
if (handle == NULL || !handle->initialized) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
if (handle->stats.state == DATA_STORAGE_RECORDING) {
|
|
return HAL_OK; // 已经在记录中
|
|
}
|
|
|
|
// 创建新文件
|
|
if (DataStorage_CreateNewFile(handle) != HAL_OK) {
|
|
handle->stats.state = DATA_STORAGE_ERROR;
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
handle->stats.state = DATA_STORAGE_RECORDING;
|
|
handle->buffer_index = 0;
|
|
|
|
return HAL_OK;
|
|
} |