✨ feat(main): 新增usb连接状态检测与自动文件系统管理功能

- 新增usb连接状态检测函数,根据usb连接状态自动切换数据采集模式
- 新增文件系统动态挂载/卸载功能,usb连接时卸载文件系统,断开时重新挂载
- 修改系统启动逻辑,根据初始usb连接状态决定是否开始数据采集
- 新增usb模式系统状态,完善系统状态机

🐛 fix(sdio): 修复sdio配置问题并启用中断

- 修改sdio时钟分频为2,优化sd nand通信时序
- 启用sdio数据线内部上拉电阻,提高信号稳定性
- 提高sdio dma传输优先级至最高,确保数据传输实时性
- 启用sdio全局中断并设置优先级为9

🔧 chore(config): 优化系统配置参数

- 修改系统滴答定时器中断优先级为0(最高优先级)
- 增加堆栈大小至0x1000,增加堆大小至0x800
- 修改usb msc媒体数据包大小至32768,提高usb传输效率
- 修改fatfs配置,设置最大最小扇区大小为512字节

♻️ refactor(usb): 重构usb存储接口实现

- 修改usb存储初始化逻辑,避免重复初始化sd卡
- 优化usb存储容量报告机制,强制报告512字节扇区
- 增加sd nand读写超时等待机制,确保数据传输完成
- 修改usb中断优先级为11,避免与sdio中断冲突

📝 docs(headers): 更新头文件声明

- 在stm32f4xx_it.h中添加sdio中断处理函数声明
- 在system_monitor.h中添加usb模式系统状态定义
- 更新data_storage.h中的数据存储路径配置
This commit is contained in:
2026-02-02 23:36:20 +08:00
parent 4598f8f34f
commit 87bdfa09d9
14 changed files with 477 additions and 64 deletions
+1 -1
View File
@@ -60,7 +60,7 @@ void MX_GPIO_Init(void)
/*Configure GPIO pin : PC3 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : ADC_DRY_Pin */
+183 -9
View File
@@ -84,6 +84,11 @@ static uint32_t g_last_monitor_update = 0;
static uint8_t g_recording_enabled = 0;
static uint32_t g_sample_count = 0;
// USB连接状态管理
static uint8_t g_usb_connected = 0;
static uint8_t g_fatfs_mounted_for_sampling = 0;
static uint32_t g_last_usb_check = 0;
// 性能监控和调试输出
static uint32_t g_last_debug_output = 0;
static uint8_t g_debug_output_enabled = ENABLE_UART_DEBUG_OUTPUT;
@@ -98,6 +103,12 @@ static void StartRecording(void);
static void StopRecording(void);
static void ProcessAdcData(void);
// USB连接状态管理函数
static uint8_t CheckUSBConnectionStatus(void);
static void HandleUSBConnectionChange(void);
static HAL_StatusTypeDef MountFileSystemForSampling(void);
static void UnmountFileSystemForSampling(void);
static void DebugOutput_Init(void);
static void DebugOutput_SendString(const char* str);
static void DebugOutput_PrintSystemStats(void);
@@ -396,6 +407,141 @@ static void DebugOutput_PrintPerformanceStats(void)
#endif
}
/**
* @brief 检查USB连接状态
* @retval 1: USB已连接, 0: USB未连接
*/
static uint8_t CheckUSBConnectionStatus(void)
{
// 通过检查USB设备状态来判断是否连接到PC
extern USBD_HandleTypeDef hUsbDeviceFS;
// 检查USB设备是否已配置(枚举完成)
if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) {
return 1; // USB已连接并配置
}
return 0; // USB未连接或未配置
}
/**
* @brief 处理USB连接状态变化
* @retval None
*/
static void HandleUSBConnectionChange(void)
{
uint8_t current_usb_status = CheckUSBConnectionStatus();
if (current_usb_status != g_usb_connected) {
g_usb_connected = current_usb_status;
if (g_usb_connected) {
// USB连接:停止数据采集,卸载文件系统用于USB存储
DebugOutput_SendString("USB Connected: Stopping data acquisition\r\n");
// 停止数据记录
StopRecording();
// 卸载用于采样的文件系统
UnmountFileSystemForSampling();
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_SetState(SYSTEM_STATE_USB_MODE);
#endif
} else {
// USB断开:重新挂载文件系统,开始数据采集
DebugOutput_SendString("USB Disconnected: Starting data acquisition\r\n");
// 挂载文件系统用于数据采集
if (MountFileSystemForSampling() == HAL_OK) {
// 重新初始化数据存储
if (DataStorage_Init(&g_data_storage) == HAL_OK) {
StartRecording();
}
}
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_SetState(SYSTEM_STATE_IDLE);
#endif
}
}
}
/**
* @brief 为数据采集挂载文件系统
* @retval HAL_OK: 成功, HAL_ERROR: 失败
*/
static HAL_StatusTypeDef MountFileSystemForSampling(void)
{
extern FATFS SDFatFS;
extern char SDPath[4];
extern SD_HandleTypeDef hsd;
if (g_fatfs_mounted_for_sampling) {
return HAL_OK; // 已经挂载
}
// 初始化SD卡
if (HAL_SD_Init(&hsd) != HAL_OK) {
DebugOutput_SendString("SD card init failed\r\n");
return HAL_ERROR;
}
// FRESULT format_result = f_mkfs(SDPath, FM_FAT32, 0, NULL, 0);
// 尝试挂载文件系统
FRESULT mount_result = f_mount(&SDFatFS, SDPath, 1);
if (mount_result != FR_OK) {
if (mount_result == FR_NO_FILESYSTEM)
{
DebugOutput_SendString("No filesystem found, formatting...\r\n");
// 格式化为FAT32
FRESULT format_result = f_mkfs(SDPath, FM_FAT32, 0, NULL, 0);
if (format_result == FR_OK) {
DebugOutput_SendString("Format successful, remounting...\r\n");
mount_result = f_mount(&SDFatFS, SDPath, 1);
if (mount_result != FR_OK) {
DebugOutput_SendString("Remount after format failed\r\n");
return HAL_ERROR;
}
} else {
DebugOutput_SendString("Format failed\r\n");
return HAL_ERROR;
}
} else {
DebugOutput_SendString("Mount failed with other error\r\n");
return HAL_ERROR;
}
}
g_fatfs_mounted_for_sampling = 1;
DebugOutput_SendString("Filesystem mounted for sampling\r\n");
return HAL_OK;
}
/**
* @brief 卸载用于数据采集的文件系统
* @retval None
*/
static void UnmountFileSystemForSampling(void)
{
extern FATFS SDFatFS;
extern char SDPath[4];
if (!g_fatfs_mounted_for_sampling) {
return; // 已经卸载
}
// 卸载文件系统
f_mount(NULL, SDPath, 0);
g_fatfs_mounted_for_sampling = 0;
DebugOutput_SendString("Filesystem unmounted for USB mode\r\n");
}
/* USER CODE END 0 */
/**
@@ -422,7 +568,7 @@ int main(void)
SystemClock_Config();
/* USER CODE BEGIN SysInit */
HAL_Delay(200);
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
@@ -439,6 +585,11 @@ int main(void)
MX_USART3_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
// SD_NAND_Init_And_Mount();
// SD_Test_Write();
// SD_Test_Read();
// 初始化系统监控
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_Init();
@@ -468,15 +619,35 @@ int main(void)
Init_CorrectionParams(&g_correction_params);
Load_CorrectionParams_FromFlash(&g_correction_params);
// 初始化数据存储
if (DataStorage_Init(&g_data_storage) != HAL_OK) {
// 检查初始USB连接状态并相应初始化
HAL_Delay(2000);
g_usb_connected = CheckUSBConnectionStatus();
if (!g_usb_connected) {
// USB未连接,挂载文件系统用于数据采集
if (MountFileSystemForSampling() == HAL_OK) {
// 初始化数据存储
if (DataStorage_Init(&g_data_storage) == HAL_OK) {
// 开始数据记录
StartRecording();
} else {
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
#endif
}
} else {
#if ENABLE_SYSTEM_MONITOR
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
#endif
}
} else {
// USB已连接,不进行数据采集
DebugOutput_SendString("USB connected at startup - data acquisition disabled\r\n");
while(1)
{
;
}
}
// 开始数据记录
StartRecording();
// 系统初始化完成
#if ENABLE_SYSTEM_MONITOR
@@ -519,8 +690,11 @@ int main(void)
g_last_monitor_update = current_tick;
}
// ADC数据处理已移至1ms定时器中断中处理
// USB连接状态检测 (每500ms检测一次)
if (current_tick - g_last_usb_check >= 500) {
HandleUSBConnectionChange();
g_last_usb_check = current_tick;
}
// 处理数据存储后台任务 (轮询方式)
if (g_recording_enabled) {
+18 -6
View File
@@ -46,7 +46,7 @@ void MX_SDIO_SD_Init(void)
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 0;
hsd.Init.ClockDiv = 2;
/* USER CODE BEGIN SDIO_Init 2 */
/* USER CODE END SDIO_Init 2 */
@@ -75,8 +75,14 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
@@ -85,7 +91,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
@@ -100,7 +106,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
@@ -121,7 +127,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
@@ -133,6 +139,9 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
__HAL_LINKDMA(sdHandle,hdmatx,hdma_sdio_tx);
/* SDIO interrupt Init */
HAL_NVIC_SetPriority(SDIO_IRQn, 9, 0);
HAL_NVIC_EnableIRQ(SDIO_IRQn);
/* USER CODE BEGIN SDIO_MspInit 1 */
/* USER CODE END SDIO_MspInit 1 */
@@ -166,6 +175,9 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
/* SDIO DMA DeInit */
HAL_DMA_DeInit(sdHandle->hdmarx);
HAL_DMA_DeInit(sdHandle->hdmatx);
/* SDIO interrupt Deinit */
HAL_NVIC_DisableIRQ(SDIO_IRQn);
/* USER CODE BEGIN SDIO_MspDeInit 1 */
/* USER CODE END SDIO_MspDeInit 1 */
+15
View File
@@ -60,6 +60,7 @@
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern DMA_HandleTypeDef hdma_sdio_rx;
extern DMA_HandleTypeDef hdma_sdio_tx;
extern SD_HandleTypeDef hsd;
extern DMA_HandleTypeDef hdma_spi1_rx;
extern DMA_HandleTypeDef hdma_spi2_rx;
extern DMA_HandleTypeDef hdma_spi3_rx;
@@ -266,6 +267,20 @@ void TIM2_IRQHandler(void)
/* USER CODE END TIM2_IRQn 1 */
}
/**
* @brief This function handles SDIO global interrupt.
*/
void SDIO_IRQHandler(void)
{
/* USER CODE BEGIN SDIO_IRQn 0 */
/* USER CODE END SDIO_IRQn 0 */
HAL_SD_IRQHandler(&hsd);
/* USER CODE BEGIN SDIO_IRQn 1 */
/* USER CODE END SDIO_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream0 global interrupt.
*/