- 新增配置管理器模块,支持从SD卡加载运行时配置 - 将数据输出模式从编译时宏改为运行时配置,提高灵活性 - 新增配置文件 `CONFIG.TXT`,支持串口输出和存储功能的动态开关 - 集成配置管理器到主程序,在系统启动时自动加载配置 - 更新数据存储模块,使用配置管理器管理会话序号 🐛 fix(usart): 修复USART3中断配置并优化波特率 - 添加USART3中断处理函数声明和实现 - 将USART3波特率从921600提升至2000000以提高通信速率 - 调整USART1中断优先级从2改为11,优化中断响应 - 在USART3 MSP初始化和反初始化中添加中断配置 📝 docs(user): 新增功能说明文档 - 新增《配置管理功能说明》文档,详细说明运行时配置的使用方法 - 新增《串口发送监控功能说明》文档,说明新增的串口统计功能 - 文档包含配置项说明、文件格式、使用示例和注意事项 ✨ feat(monitor): 增强系统监控功能 - 在系统监控统计中添加串口发送监控字段(发送次数、字节数、错误数) - 新增串口发送统计报告函数,集成到RS485驱动中 - 优化监控状态保存格式,采用精简格式减少文件写入阻塞时间 - 监控数据现在包含串口统计信息,便于性能分析和故障排查 ♻️ refactor(main): 重构主程序配置处理逻辑 - 移除编译时宏 `DATA_OUTPUT_MODE_UART` 和 `DATA_OUTPUT_MODE_STORAGE` - 使用 `Config_IsUartOutputEnabled()` 和 `Config_IsStorageEnabled()` 函数替代 - 优化数据存储启动逻辑,仅在存储功能启用时开始记录 - 添加配置加载成功/失败的调试输出信息
235 lines
5.7 KiB
C
235 lines
5.7 KiB
C
#include "config_manager.h"
|
|
#include "fatfs.h"
|
|
#include "ff.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
// 全局配置变量
|
|
static SystemConfig_t g_system_config = {0};
|
|
static uint8_t g_config_initialized = 0;
|
|
|
|
// 计算校验和
|
|
static uint32_t Calculate_Checksum(const SystemConfig_t *config)
|
|
{
|
|
uint32_t checksum = 0;
|
|
checksum += config->uart_output_enabled;
|
|
checksum += config->storage_enabled;
|
|
checksum += config->session_number;
|
|
checksum += config->config_version;
|
|
return checksum;
|
|
}
|
|
|
|
/**
|
|
* @brief 初始化配置管理器
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void Config_Init(void)
|
|
{
|
|
if (!g_config_initialized) {
|
|
Config_SetDefaults();
|
|
g_config_initialized = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief 设置默认配置
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void Config_SetDefaults(void)
|
|
{
|
|
g_system_config.uart_output_enabled = DEFAULT_UART_OUTPUT_ENABLED;
|
|
g_system_config.storage_enabled = DEFAULT_STORAGE_ENABLED;
|
|
g_system_config.session_number = 0; // 初始会话序号为0
|
|
g_system_config.config_version = CONFIG_VERSION;
|
|
g_system_config.checksum = Calculate_Checksum(&g_system_config);
|
|
}
|
|
|
|
/**
|
|
* @brief 从SD卡加载配置
|
|
* @param None
|
|
* @retval HAL_OK: 成功, HAL_ERROR: 失败(将使用默认配置)
|
|
*/
|
|
HAL_StatusTypeDef Config_Load(void)
|
|
{
|
|
FIL file;
|
|
FRESULT res;
|
|
UINT bytes_read;
|
|
char buffer[128];
|
|
|
|
// 尝试打开配置文件
|
|
res = f_open(&file, CONFIG_FILE_PATH, FA_READ);
|
|
if (res != FR_OK) {
|
|
// 文件不存在,使用默认配置并保存
|
|
Config_SetDefaults();
|
|
Config_Save();
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 读取配置文件
|
|
res = f_read(&file, buffer, sizeof(buffer), &bytes_read);
|
|
f_close(&file);
|
|
|
|
if (res != FR_OK || bytes_read == 0) {
|
|
Config_SetDefaults();
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 解析配置(简单的文本格式)
|
|
SystemConfig_t temp_config;
|
|
int uart_enabled, storage_enabled;
|
|
unsigned int version, session_num;
|
|
|
|
int parsed = sscanf(buffer,
|
|
"UART=%d\nSTORAGE=%d\nSESSION=%u\nVERSION=%u\n",
|
|
&uart_enabled,
|
|
&storage_enabled,
|
|
&session_num,
|
|
&version);
|
|
|
|
if (parsed == 4 && version == CONFIG_VERSION) {
|
|
temp_config.uart_output_enabled = (uint8_t)uart_enabled;
|
|
temp_config.storage_enabled = (uint8_t)storage_enabled;
|
|
temp_config.session_number = session_num;
|
|
temp_config.config_version = version;
|
|
temp_config.checksum = Calculate_Checksum(&temp_config);
|
|
|
|
// 验证配置值的合法性
|
|
if (temp_config.uart_output_enabled <= 1 &&
|
|
temp_config.storage_enabled <= 1) {
|
|
memcpy(&g_system_config, &temp_config, sizeof(SystemConfig_t));
|
|
return HAL_OK;
|
|
}
|
|
}
|
|
|
|
// 解析失败,使用默认配置
|
|
Config_SetDefaults();
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
/**
|
|
* @brief 保存配置到SD卡
|
|
* @param None
|
|
* @retval HAL_OK: 成功, HAL_ERROR: 失败
|
|
*/
|
|
HAL_StatusTypeDef Config_Save(void)
|
|
{
|
|
FIL file;
|
|
FRESULT res;
|
|
UINT bytes_written;
|
|
char buffer[128];
|
|
|
|
// 更新校验和
|
|
g_system_config.checksum = Calculate_Checksum(&g_system_config);
|
|
|
|
// 创建或覆盖配置文件
|
|
res = f_open(&file, CONFIG_FILE_PATH, FA_CREATE_ALWAYS | FA_WRITE);
|
|
if (res != FR_OK) {
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 格式化配置数据为文本(精简格式)
|
|
int len = snprintf(buffer, sizeof(buffer),
|
|
"UART=%d\nSTORAGE=%d\nSESSION=%lu\nVERSION=%lu\n",
|
|
g_system_config.uart_output_enabled,
|
|
g_system_config.storage_enabled,
|
|
g_system_config.session_number,
|
|
g_system_config.config_version);
|
|
|
|
// 写入配置数据
|
|
res = f_write(&file, buffer, len, &bytes_written);
|
|
if (res != FR_OK || bytes_written != (UINT)len) {
|
|
f_close(&file);
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
// 关闭文件
|
|
f_close(&file);
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取串口输出使能状态
|
|
* @param None
|
|
* @retval 1: 启用, 0: 禁用
|
|
*/
|
|
uint8_t Config_IsUartOutputEnabled(void)
|
|
{
|
|
return g_system_config.uart_output_enabled;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取存储使能状态
|
|
* @param None
|
|
* @retval 1: 启用, 0: 禁用
|
|
*/
|
|
uint8_t Config_IsStorageEnabled(void)
|
|
{
|
|
return g_system_config.storage_enabled;
|
|
}
|
|
|
|
/**
|
|
* @brief 设置串口输出使能
|
|
* @param enabled: 1=启用, 0=禁用
|
|
* @retval None
|
|
*/
|
|
void Config_SetUartOutput(uint8_t enabled)
|
|
{
|
|
g_system_config.uart_output_enabled = (enabled != 0) ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* @brief 设置存储使能
|
|
* @param enabled: 1=启用, 0=禁用
|
|
* @retval None
|
|
*/
|
|
void Config_SetStorage(uint8_t enabled)
|
|
{
|
|
g_system_config.storage_enabled = (enabled != 0) ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取完整配置
|
|
* @param config: 配置结构体指针
|
|
* @retval None
|
|
*/
|
|
void Config_GetConfig(SystemConfig_t *config)
|
|
{
|
|
if (config != NULL) {
|
|
memcpy(config, &g_system_config, sizeof(SystemConfig_t));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief 获取会话序号
|
|
* @param None
|
|
* @retval 当前会话序号
|
|
*/
|
|
uint32_t Config_GetSessionNumber(void)
|
|
{
|
|
return g_system_config.session_number;
|
|
}
|
|
|
|
/**
|
|
* @brief 设置会话序号
|
|
* @param session_number: 会话序号
|
|
* @retval None
|
|
*/
|
|
void Config_SetSessionNumber(uint32_t session_number)
|
|
{
|
|
g_system_config.session_number = session_number;
|
|
}
|
|
|
|
/**
|
|
* @brief 递增会话序号并返回新值
|
|
* @param None
|
|
* @retval 递增后的会话序号
|
|
*/
|
|
uint32_t Config_IncrementSessionNumber(void)
|
|
{
|
|
g_system_config.session_number++;
|
|
return g_system_config.session_number;
|
|
}
|