✨ feat(system): 优化系统性能并简化监控模块

- 新增VSCode编辑器配置,启用保存时自动格式化
- 新增DMA2_Stream5和USART1中断处理函数,优化SPI传输性能
- 移除TIM1相关配置和性能监控模块,简化系统架构
- 优化GPIO配置,将ADC_SYNC和PA8引脚合并配置
- 简化系统监控模块,仅保留采样计数和数据溢出统计
- 优化SPI配置,使用16位数据宽度并提高DMA优先级
- 提高USART波特率(USART1:2Mbps, USART3:921600bps)
- 优化LTC2508驱动,增加初始化状态检查和缓冲区大小
- 修正数据存储模块,使用校正数据包而非校正结果结构体
- 优化RS485驱动,使用中断传输并添加传输完成回调
- 更新IOC配置文件,移除TIM1并调整中断优先级配置
- 新增系统监控简化说明文档,详细记录架构变更
This commit is contained in:
2026-02-06 22:45:25 +08:00
parent 87bdfa09d9
commit fee2e96eaa
24 changed files with 388 additions and 818 deletions
+130
View File
@@ -0,0 +1,130 @@
# SystemMonitor 简化说明
## 简化目标
为了提高系统性能,将SystemMonitor模块从复杂的状态机和多种错误类型简化为只统计两个关键指标:
1. **采样样点数** - 记录总共采集的样本数量
2. **数据溢出次数** - 记录数据来不及处理的次数
## 简化前后对比
### 简化前的结构
```c
typedef struct {
SystemState_t current_state; // 系统状态
SystemError_t last_error; // 最后错误
uint32_t uptime_seconds; // 运行时间
uint32_t total_samples; // 总样本数
uint32_t error_count; // 错误计数
uint32_t memory_usage; // 内存使用
uint8_t cpu_usage_percent; // CPU使用率
uint8_t temperature_celsius; // 温度
} SystemMonitorStats_t;
```
包含多个函数:
- `SystemMonitor_SetState()` - 设置系统状态
- `SystemMonitor_ReportError()` - 报告各种错误
- `SystemMonitor_Update()` - 定期更新统计
- `SystemMonitor_IsHealthy()` - 健康检查
### 简化后的结构
```c
typedef struct {
uint32_t total_samples; // 总采样样点数
uint32_t data_overflow_count; // 数据来不及处理的次数
} SystemMonitorStats_t;
```
只保留3个核心函数:
- [`SystemMonitor_Init()`](User/system_monitor.h:14) - 初始化
- [`SystemMonitor_IncrementSampleCount()`](User/system_monitor.h:15) - 增加采样计数
- [`SystemMonitor_ReportDataOverflow()`](User/system_monitor.h:16) - 报告数据溢出
- [`SystemMonitor_GetStats()`](User/system_monitor.h:17) - 获取统计信息
## 使用方式
### 1. 初始化
在系统启动时调用:
```c
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_Init();
#endif
```
### 2. 采样计数
在 [`ProcessAdcData()`](Core/Src/main.c:146) 中,每处理一个样本时调用:
```c
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_IncrementSampleCount();
#endif
```
### 3. 数据溢出报告
当检测到数据来不及处理时(缓冲区无可用数据但应该有数据):
```c
} else {
// 数据来不及处理
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_ReportDataOverflow();
#endif
}
```
### 4. 查看统计信息
通过调试输出查看:
```c
SystemMonitorStats_t sys_stats;
SystemMonitor_GetStats(&sys_stats);
snprintf(buffer, sizeof(buffer),
"\r\n=== System Stats ===\r\n"
"Total Samples: %lu\r\n"
"Data Overflow: %lu\r\n",
sys_stats.total_samples,
sys_stats.data_overflow_count);
```
## 性能优势
1. **减少函数调用开销** - 从多个状态设置和错误报告函数简化为2个简单的计数器操作
2. **减少内存占用** - 统计结构从8个字段减少到2个字段
3. **消除复杂逻辑** - 移除状态机、健康检查等复杂逻辑
4. **提高实时性** - 减少中断和关键路径中的处理时间
## 关键指标说明
### total_samples(总采样样点数)
- 每成功处理一个ADC样本时递增
- 用于监控系统采样率和运行状态
- 可以计算实际采样率:`samples / uptime`
### data_overflow_count(数据溢出次数)
- 当数据处理速度跟不上采样速度时递增
- 表示数据丢失或处理延迟的情况
- 理想情况下应该为0或非常小的值
## 调试输出示例
```
=== System Stats ===
Total Samples: 40000
Data Overflow: 0
```
这表示系统已采集40000个样本,没有发生数据溢出,系统运行正常。
如果看到:
```
=== System Stats ===
Total Samples: 40000
Data Overflow: 150
```
说明有150次数据来不及处理,需要优化数据处理流程或降低采样率。
+3 -3
View File
@@ -21,9 +21,9 @@ void Init_CorrectionParams(CorrectionParams_t *params)
// 初始化为单位矩阵
memset(params->correction_matrix, 0, sizeof(params->correction_matrix));
params->correction_matrix[0] = 1.0f; // [0,0]
params->correction_matrix[4] = 1.0f; // [1,1]
params->correction_matrix[8] = 1.0f; // [2,2]
params->correction_matrix[0] = 5.0f / 0x7FFFFFFF; // [0,0]
params->correction_matrix[4] = 5.0f / 0x7FFFFFFF; // [1,1]
params->correction_matrix[8] = 5.0f / 0x7FFFFFFF; // [2,2]
#if USE_ARM_DSP
// 初始化ARM DSP矩阵实例 (3x3矩阵)
+6 -6
View File
@@ -34,9 +34,9 @@ void PackData(DataPacket_t *packet, int32_t adc1, int32_t adc2, int32_t adc3)
packet->adc_data3 = adc3;
// 计算校验和 (不包括校验和字段本身和包尾)
uint16_t checksum = Calculate_CRC16((uint8_t*)packet,
sizeof(DataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte));
packet->checksum = checksum;
uint16_t checksum = Calculate_CRC16((uint8_t*)packet,
sizeof(DataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte));
packet->checksum = checksum;
// 设置包尾
packet->end_byte = PACKET_END_BYTE;
@@ -96,9 +96,9 @@ void PackCorrectedData(CorrectedDataPacket_t *packet, float x, float y, float z)
packet->corrected_z = z;
// 计算校验和
uint16_t checksum = Calculate_CRC16((uint8_t*)packet,
sizeof(CorrectedDataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte));
packet->checksum = checksum;
uint16_t checksum = Calculate_CRC16((uint8_t*)packet,
sizeof(CorrectedDataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte));
packet->checksum = checksum;
// 设置包尾
packet->end_byte = PACKET_END_BYTE;
+7 -7
View File
@@ -109,14 +109,14 @@ HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataP
}
/**
* @brief 写入校正后的数据到存储
* @brief 写入校正后的数据包到存储
* @param handle: 数据存储句柄指针
* @param result: 校正结果指针
* @param packet: 数据包指针
* @retval HAL_StatusTypeDef
*/
HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectionResult_t *result)
HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectedDataPacket_t *packet)
{
if (handle == NULL || result == NULL || !handle->initialized) {
if (handle == NULL || packet == NULL || !handle->initialized) {
return HAL_ERROR;
}
@@ -127,7 +127,7 @@ HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, co
DataBuffer_t *active_buf = &handle->buffers[handle->active_buffer];
// 检查当前活动缓冲区空间
if (active_buf->index + sizeof(CorrectionResult_t) > DATA_STORAGE_BUFFER_SIZE) {
if (active_buf->index + sizeof(CorrectedDataPacket_t) > DATA_STORAGE_BUFFER_SIZE) {
// 切换缓冲区
if (DataStorage_SwitchBuffer(handle) != HAL_OK) {
handle->stats.error_count++;
@@ -137,8 +137,8 @@ HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, co
}
// 复制校正后的数据到活动缓冲区
memcpy(&active_buf->data[active_buf->index], result, sizeof(CorrectionResult_t));
active_buf->index += sizeof(CorrectionResult_t);
memcpy(&active_buf->data[active_buf->index], packet, sizeof(CorrectedDataPacket_t));
active_buf->index += sizeof(CorrectedDataPacket_t);
active_buf->state = BUFFER_WRITING;
handle->stats.total_samples++;
+4 -4
View File
@@ -10,9 +10,9 @@
// 数据存储配置
#define DATA_STORAGE_BUFFER_SIZE 32768 // 缓冲区大小(字节)
#define DATA_STORAGE_FILE_MAX_SIZE (10*1024*1024) // 单个文件最大10MB
#define DATA_STORAGE_PATH "0:/DATA1" // 数据存储路径
#define DATA_STORAGE_FILE_PREFIX "ADC_DATA_" // 文件名前缀
#define DATA_STORAGE_FILE_MAX_SIZE (20*1024*1024) // 单个文件最大20MB
#define DATA_STORAGE_PATH "0:/DATA2" // 数据存储路径
#define DATA_STORAGE_FILE_PREFIX "/ADC_DATA_" // 文件名前缀
// 缓冲区状态
typedef enum {
@@ -63,7 +63,7 @@ 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 CorrectionResult_t *result);
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);
+16 -5
View File
@@ -16,6 +16,17 @@ static SPI_HandleTypeDef *g_hspi1 = NULL;
static SPI_HandleTypeDef *g_hspi2 = NULL;
static SPI_HandleTypeDef *g_hspi3 = NULL;
/**
* @brief LTC2508 是否初始化
* @retval 0-未初始化 1-已初始化
*/
uint32_t LTC2508_IsInited()
{
return (g_hspi1 != NULL && g_hspi2 != NULL && g_hspi3 != NULL);
}
/**
* @brief 初始化 LTC2508 驱动
* @param hspi1: SPI1 句柄指针
@@ -81,27 +92,27 @@ LTC2508_StatusTypeDef LTC2508_TriggerDmaRead(void)
current_buffer->timestamp = HAL_GetTick();
// SPI2 和 SPI3 作为从机只接收
if (HAL_SPI_Receive_DMA(g_hspi2, (uint8_t*)current_buffer->data[1], LTC2508_DATA_LEN * 2) != HAL_OK)
if (HAL_SPI_Receive_DMA(g_hspi2, (uint8_t*)current_buffer->data[1], LTC2508_DATA_LEN) != HAL_OK)
{
current_buffer->state = LTC2508_BUFFER_EMPTY;
g_ltc2508_stats.dma_error_count++;
g_ltc2508_stats.error_count++;
g_ltc2508_stats.last_error = LTC2508_ERROR_DMA;
return LTC2508_ERROR_DMA;
// return LTC2508_ERROR_DMA;
}
if (HAL_SPI_Receive_DMA(g_hspi3, (uint8_t*)current_buffer->data[2], LTC2508_DATA_LEN * 2) != HAL_OK)
if (HAL_SPI_Receive_DMA(g_hspi3, (uint8_t*)current_buffer->data[2], LTC2508_DATA_LEN) != HAL_OK)
{
current_buffer->state = LTC2508_BUFFER_EMPTY;
g_ltc2508_stats.dma_error_count++;
g_ltc2508_stats.error_count++;
g_ltc2508_stats.last_error = LTC2508_ERROR_DMA;
return LTC2508_ERROR_DMA;
// return LTC2508_ERROR_DMA;
}
// SPI1 作为主机收发,先发一个 dummy 数据触发时钟
uint16_t dummy_tx[LTC2508_DATA_LEN] = {0}; // 可以是任意值
if (HAL_SPI_TransmitReceive_DMA(g_hspi1, (uint8_t*)dummy_tx, (uint8_t*)current_buffer->data[0], LTC2508_DATA_LEN * 2) != HAL_OK)
if (HAL_SPI_TransmitReceive_DMA(g_hspi1, (uint8_t*)dummy_tx, (uint8_t*)current_buffer->data[0], LTC2508_DATA_LEN) != HAL_OK)
{
current_buffer->state = LTC2508_BUFFER_EMPTY;
g_ltc2508_stats.dma_error_count++;
+2 -1
View File
@@ -10,7 +10,7 @@
#define NUM_LTC2508 3
// 双缓冲区定义
#define LTC2508_BUFFER_COUNT 64
#define LTC2508_BUFFER_COUNT 128
// 缓冲区状态定义
typedef enum {
@@ -62,6 +62,7 @@ extern volatile uint8_t g_current_read_buffer;
extern LTC2508_StatsTypeDef g_ltc2508_stats;
// 函数原型
uint32_t LTC2508_IsInited();
LTC2508_StatusTypeDef LTC2508_Init(SPI_HandleTypeDef *hspi1, SPI_HandleTypeDef *hspi2, SPI_HandleTypeDef *hspi3);
LTC2508_StatusTypeDef LTC2508_TriggerDmaRead(void);
void LTC2508_DmaComplete_Callback(SPI_HandleTypeDef *hspi);
-193
View File
@@ -1,193 +0,0 @@
#include "performance_monitor.h"
#include <string.h>
#include <stdlib.h>
// 静态变量
static SystemPerfStats_t g_perf_stats = {0};
static uint32_t g_task_start_time[PERF_MON_MAX_TASKS] = {0};
static uint8_t g_task_active[PERF_MON_MAX_TASKS] = {0};
// 外部符号声明 (用于堆栈监控)
extern uint32_t _estack;
extern uint32_t _Min_Stack_Size;
/**
* @brief 初始化性能监控模块
* @param None
* @retval None
*/
void PerformanceMonitor_Init(void)
{
memset(&g_perf_stats, 0, sizeof(SystemPerfStats_t));
memset(g_task_start_time, 0, sizeof(g_task_start_time));
memset(g_task_active, 0, sizeof(g_task_active));
g_perf_stats.sample_period_ms = PERF_MON_SAMPLE_PERIOD_MS;
g_perf_stats.last_update_tick = HAL_GetTick();
// 初始化最小执行时间为最大值
for (int i = 0; i < PERF_MON_MAX_TASKS; i++) {
g_perf_stats.tasks[i].min_time_us = UINT32_MAX;
}
}
/**
* @brief 开始任务性能监控
* @param task_id: 任务ID
* @retval None
*/
void PerformanceMonitor_TaskStart(PerfTaskID_t task_id)
{
if (task_id >= PERF_MON_MAX_TASKS) return;
g_task_start_time[task_id] = HAL_GetTick() * 1000; // 转换为微秒
g_task_active[task_id] = 1;
}
/**
* @brief 结束任务性能监控
* @param task_id: 任务ID
* @retval None
*/
void PerformanceMonitor_TaskEnd(PerfTaskID_t task_id)
{
if (task_id >= PERF_MON_MAX_TASKS || !g_task_active[task_id]) return;
uint32_t end_time = HAL_GetTick() * 1000; // 转换为微秒
uint32_t execution_time = end_time - g_task_start_time[task_id];
TaskPerfStats_t *task_stats = &g_perf_stats.tasks[task_id];
// 更新统计信息
task_stats->total_time_us += execution_time;
task_stats->call_count++;
// 更新最大最小时间
if (execution_time > task_stats->max_time_us) {
task_stats->max_time_us = execution_time;
}
if (execution_time < task_stats->min_time_us) {
task_stats->min_time_us = execution_time;
}
// 计算平均时间
task_stats->avg_time_us = task_stats->total_time_us / task_stats->call_count;
g_task_active[task_id] = 0;
}
/**
* @brief 更新性能监控统计
* @param None
* @retval None
*/
void PerformanceMonitor_Update(void)
{
uint32_t current_tick = HAL_GetTick();
// 检查是否到了更新周期
if (current_tick - g_perf_stats.last_update_tick < g_perf_stats.sample_period_ms) {
return;
}
// 计算CPU使用率
uint32_t total_cpu_time = 0;
for (int i = 0; i < PERF_MON_MAX_TASKS; i++) {
if (g_perf_stats.tasks[i].call_count > 0) {
// 计算每个任务的CPU使用率
uint32_t task_time_per_period = g_perf_stats.tasks[i].avg_time_us *
(1000 / g_perf_stats.sample_period_ms);
g_perf_stats.tasks[i].cpu_usage_percent =
(float)task_time_per_period / 10000.0f; // 转换为百分比
total_cpu_time += task_time_per_period;
}
}
// 更新总CPU使用率
g_perf_stats.total_cpu_usage_percent = total_cpu_time / 100;
// 更新内存使用情况
g_perf_stats.free_heap_size = PerformanceMonitor_GetFreeHeapSize();
if (g_perf_stats.min_free_heap_size == 0 ||
g_perf_stats.free_heap_size < g_perf_stats.min_free_heap_size) {
g_perf_stats.min_free_heap_size = g_perf_stats.free_heap_size;
}
// 更新栈使用率
g_perf_stats.stack_usage_percent = PerformanceMonitor_GetStackUsage();
g_perf_stats.last_update_tick = current_tick;
}
/**
* @brief 获取性能统计信息
* @param stats: 统计信息结构体指针
* @retval None
*/
void PerformanceMonitor_GetStats(SystemPerfStats_t *stats)
{
if (stats != NULL) {
memcpy(stats, &g_perf_stats, sizeof(SystemPerfStats_t));
}
}
/**
* @brief 重置性能统计
* @param None
* @retval None
*/
void PerformanceMonitor_ResetStats(void)
{
memset(&g_perf_stats, 0, sizeof(SystemPerfStats_t));
g_perf_stats.sample_period_ms = PERF_MON_SAMPLE_PERIOD_MS;
g_perf_stats.last_update_tick = HAL_GetTick();
// 重新初始化最小执行时间
for (int i = 0; i < PERF_MON_MAX_TASKS; i++) {
g_perf_stats.tasks[i].min_time_us = UINT32_MAX;
}
}
/**
* @brief 获取空闲堆内存大小
* @param None
* @retval 空闲堆内存大小(字节)
*/
uint32_t PerformanceMonitor_GetFreeHeapSize(void)
{
// 简单的堆内存检测方法
// 在实际应用中,可能需要更复杂的内存管理
void *ptr = malloc(1);
if (ptr != NULL) {
free(ptr);
// 这里返回一个估算值,实际项目中需要更精确的实现
return 32768; // 假设有32KB空闲堆内存
}
return 0;
}
/**
* @brief 获取栈使用率
* @param None
* @retval 栈使用率百分比
*/
uint32_t PerformanceMonitor_GetStackUsage(void)
{
// 获取当前栈指针
uint32_t current_sp;
__asm volatile ("mov %0, sp" : "=r" (current_sp));
// 计算栈使用量
uint32_t stack_top = (uint32_t)&_estack;
uint32_t min_stack_size = (uint32_t)&_Min_Stack_Size;
uint32_t stack_used = stack_top - current_sp;
// 计算使用率百分比
if (min_stack_size > 0) {
return (stack_used * 100) / min_stack_size;
}
return 0;
}
-54
View File
@@ -1,54 +0,0 @@
#ifndef PERFORMANCE_MONITOR_H
#define PERFORMANCE_MONITOR_H
#include "main.h"
#include <stdint.h>
// 性能监控配置
#define PERF_MON_MAX_TASKS 8
#define PERF_MON_SAMPLE_PERIOD_MS 100
// 任务ID定义
typedef enum {
PERF_TASK_ADC_PROCESSING = 0,
PERF_TASK_CORRECTION,
PERF_TASK_DATA_PACKET,
PERF_TASK_RS485_TX,
PERF_TASK_FATFS_WRITE,
PERF_TASK_USB_PROCESS,
PERF_TASK_SYSTEM_MONITOR,
PERF_TASK_IDLE
} PerfTaskID_t;
// 任务性能统计
typedef struct {
uint32_t total_time_us; // 总执行时间(微秒)
uint32_t max_time_us; // 最大执行时间
uint32_t min_time_us; // 最小执行时间
uint32_t call_count; // 调用次数
uint32_t avg_time_us; // 平均执行时间
float cpu_usage_percent; // CPU使用率百分比
} TaskPerfStats_t;
// 系统性能统计
typedef struct {
TaskPerfStats_t tasks[PERF_MON_MAX_TASKS];
uint32_t total_cpu_usage_percent;
uint32_t free_heap_size;
uint32_t min_free_heap_size;
uint32_t stack_usage_percent;
uint32_t sample_period_ms;
uint32_t last_update_tick;
} SystemPerfStats_t;
// 函数声明
void PerformanceMonitor_Init(void);
void PerformanceMonitor_TaskStart(PerfTaskID_t task_id);
void PerformanceMonitor_TaskEnd(PerfTaskID_t task_id);
void PerformanceMonitor_Update(void);
void PerformanceMonitor_GetStats(SystemPerfStats_t *stats);
void PerformanceMonitor_ResetStats(void);
uint32_t PerformanceMonitor_GetFreeHeapSize(void);
uint32_t PerformanceMonitor_GetStackUsage(void);
#endif // PERFORMANCE_MONITOR_H
+27 -3
View File
@@ -26,9 +26,33 @@ HAL_StatusTypeDef RS485_SendData(uint8_t *pData, uint16_t Size)
g_rs485_tx_busy = 1;
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_SET); // 设置为发送模式
ret = HAL_UART_Transmit(g_huart_485, pData, Size, 0xffff);
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET); // 切换回接收模式
g_rs485_tx_busy = 0;
ret = HAL_UART_Transmit_IT(g_huart_485, pData, Size);
// 注意:不能在这里立即切换回接收模式!
// DMA传输是非阻塞的,需要在传输完成回调中切换
if (ret != HAL_OK)
{
// 如果启动DMA失败,需要清除忙标志并切换回接收模式
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET);
g_rs485_tx_busy = 0;
}
// 等待数据传输完成
while(g_rs485_tx_busy)
{
;
}
return ret;
}
// UART DMA传输完成回调函数
void RS485_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == g_huart_485)
{
// DMA传输完成后切换回接收模式
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET);
g_rs485_tx_busy = 0;
}
}
+6 -72
View File
@@ -3,7 +3,6 @@
// 静态变量
static SystemMonitorStats_t g_system_stats = {0};
static uint32_t g_last_update_tick = 0;
/**
* @brief 初始化系统监控模块
@@ -13,71 +12,26 @@ static uint32_t g_last_update_tick = 0;
void SystemMonitor_Init(void)
{
memset(&g_system_stats, 0, sizeof(SystemMonitorStats_t));
g_system_stats.current_state = SYSTEM_STATE_INIT;
g_last_update_tick = HAL_GetTick();
}
/**
* @brief 更新系统监控状态
* @brief 增加采样样点计数
* @param None
* @retval None
*/
void SystemMonitor_Update(void)
void SystemMonitor_IncrementSampleCount(void)
{
uint32_t current_tick = HAL_GetTick();
// 更新运行时间
if (current_tick >= g_last_update_tick) {
g_system_stats.uptime_seconds = current_tick / 1000;
}
// 获取LTC2508统计信息
LTC2508_StatsTypeDef ltc_stats;
LTC2508_GetStats(&ltc_stats);
g_system_stats.total_samples = ltc_stats.total_samples;
// 检查ADC错误
if (ltc_stats.error_count > 0) {
SystemMonitor_ReportError(SYSTEM_ERROR_ADC);
}
g_last_update_tick = current_tick;
g_system_stats.total_samples++;
}
/**
* @brief 获取当前系统状态
* @brief 报告数据处理溢出(数据来不及处理)
* @param None
* @retval SystemState_t
*/
SystemState_t SystemMonitor_GetState(void)
{
return g_system_stats.current_state;
}
/**
* @brief 设置系统状态
* @param new_state: 新的系统状态
* @retval None
*/
void SystemMonitor_SetState(SystemState_t new_state)
void SystemMonitor_ReportDataOverflow(void)
{
g_system_stats.current_state = new_state;
}
/**
* @brief 报告系统错误
* @param error: 错误类型
* @retval None
*/
void SystemMonitor_ReportError(SystemError_t error)
{
g_system_stats.last_error = error;
g_system_stats.error_count++;
// 根据错误类型设置系统状态
if (error == SYSTEM_ERROR_CRITICAL) {
g_system_stats.current_state = SYSTEM_STATE_ERROR;
}
g_system_stats.data_overflow_count++;
}
/**
@@ -91,23 +45,3 @@ void SystemMonitor_GetStats(SystemMonitorStats_t *stats)
memcpy(stats, &g_system_stats, sizeof(SystemMonitorStats_t));
}
}
/**
* @brief 检查系统健康状态
* @param None
* @retval uint8_t: 1-健康, 0-异常
*/
uint8_t SystemMonitor_IsHealthy(void)
{
// 检查系统状态
if (g_system_stats.current_state == SYSTEM_STATE_ERROR) {
return 0;
}
// 检查错误计数
if (g_system_stats.error_count > 10) {
return 0;
}
return 1; // 系统健康
}
+6 -39
View File
@@ -2,51 +2,18 @@
#define SYSTEM_MONITOR_H
#include "main.h"
#include "ltc2508_driver.h"
#include "data_storage.h"
#include <stdint.h>
// 系统状态定义
typedef enum {
SYSTEM_STATE_INIT = 0,
SYSTEM_STATE_IDLE,
SYSTEM_STATE_SAMPLING,
SYSTEM_STATE_RECORDING,
SYSTEM_STATE_ERROR,
SYSTEM_STATE_MAINTENANCE,
SYSTEM_STATE_USB_MODE
} SystemState_t;
// 系统错误类型
typedef enum {
SYSTEM_ERROR_NONE = 0,
SYSTEM_ERROR_ADC,
SYSTEM_ERROR_STORAGE,
SYSTEM_ERROR_USB,
SYSTEM_ERROR_COMMUNICATION,
SYSTEM_ERROR_MEMORY,
SYSTEM_ERROR_CRITICAL
} SystemError_t;
// 系统监控统计信息
// 简化的系统监控统计信息
typedef struct {
SystemState_t current_state;
SystemError_t last_error;
uint32_t uptime_seconds;
uint32_t total_samples;
uint32_t error_count;
uint32_t memory_usage;
uint8_t cpu_usage_percent;
uint8_t temperature_celsius;
uint32_t total_samples; // 总采样样点数
uint32_t data_overflow_count; // 数据来不及处理的次数
} SystemMonitorStats_t;
// 函数声明
void SystemMonitor_Init(void);
void SystemMonitor_Update(void);
SystemState_t SystemMonitor_GetState(void);
void SystemMonitor_SetState(SystemState_t new_state);
void SystemMonitor_ReportError(SystemError_t error);
void SystemMonitor_IncrementSampleCount(void);
void SystemMonitor_ReportDataOverflow(void);
void SystemMonitor_GetStats(SystemMonitorStats_t *stats);
uint8_t SystemMonitor_IsHealthy(void);
#endif // SYSTEM_MONITOR_H
#endif // SYSTEM_MONITOR_H