From beae8c556ba7bc0192a0f68b31518873985ef1ce Mon Sep 17 00:00:00 2001 From: qiuxin Date: Tue, 27 May 2025 11:44:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=88=86=E5=B8=A7=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Inc/usart.h | 2 +- Core/Src/freertos.c | 114 ++++++++++++++------ Core/Src/usart.c | 38 +++++-- User/application/src/tcpserverc.c | 171 ++++++++++++++++++++++++------ 4 files changed, 252 insertions(+), 73 deletions(-) diff --git a/Core/Inc/usart.h b/Core/Inc/usart.h index 9e178ab..b279c30 100644 --- a/Core/Inc/usart.h +++ b/Core/Inc/usart.h @@ -60,7 +60,7 @@ void MX_USART3_UART_Init(void); void MX_USART6_UART_Init(void); /* USER CODE BEGIN Prototypes */ - void dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len); // DMA?? + HAL_StatusTypeDef dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len); // DMA发送函数 /* USER CODE END Prototypes */ diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index 5fcce1b..674e2fc 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -25,6 +25,8 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include // 添加标准整型定义 +#include "stm32f4xx_hal.h" // 添加HAL库定义 #include "dac161s997.h" #include "ad7124.h" #include "usart.h" @@ -110,6 +112,19 @@ volatile uint8_t tca6416_port0_dir = 0; // Port0方向寄存器值 volatile uint8_t tca6416_port1_dir = 0; // Port1方向寄存器值 volatile uint8_t tca6416_i2c_ack_status = 0; // I2C应答状态 +// 添加接收缓冲区 +static uint8_t uart6_rx_buffer[1]; +static volatile uint8_t uart6_rx_data = 0; +static volatile uint8_t uart6_rx_flag = 0; + +// 添加数据缓冲相关变量 +#define UART6_BUFFER_SIZE 128 +#define UART6_TIMEOUT_MS 50 // 50ms超时,认为数据包结束 + +static uint8_t uart6_data_buffer[UART6_BUFFER_SIZE]; +static volatile uint16_t uart6_buffer_index = 0; +static volatile uint32_t uart6_last_rx_time = 0; + /* USER CODE END Variables */ /* Private function prototypes -----------------------------------------------*/ @@ -459,11 +474,6 @@ void test_cs_pin(void) // 添加UART接收回调函数声明 static void UART6_RxCpltCallback(void); -// 添加接收缓冲区 -static uint8_t uart6_rx_buffer[1]; -static volatile uint8_t uart6_rx_data = 0; -static volatile uint8_t uart6_rx_flag = 0; - // UART接收完成回调函数 static void UART6_RxCpltCallback(void) { @@ -472,12 +482,12 @@ static void UART6_RxCpltCallback(void) // 重新启动接收 HAL_UART_Receive_IT(&huart6, uart6_rx_buffer, 1); } - +//HART1 串口测试任务 void start_usart6_test_task(void const *argument) { /* USER CODE BEGIN start_usart6_test_task */ - uint8_t rx_buffer[1]; // 接收缓冲区 err_t err; + uint32_t current_time; // 确保UART6已正确初始化 if (huart6.Instance == NULL) { @@ -504,9 +514,15 @@ void start_usart6_test_task(void const *argument) Error_Handler(); } + // 初始化缓冲区 + uart6_buffer_index = 0; + uart6_last_rx_time = 0; + /* Infinite loop */ for(;;) { + current_time = HAL_GetTick(); + // 直接检查接收标志 if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_RXNE)) { @@ -524,40 +540,30 @@ void start_usart6_test_task(void const *argument) if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_FE)) uart6_error_flags |= 0x02; if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_ORE)) uart6_error_flags |= 0x04; - // 使用数据位作为接收数据 - rx_buffer[0] = uart6_data_bits; - // 检查是否有接收错误 if (uart6_error_flags == 0) { - // 检查TCP连接状态 - if (server_pcb_control != NULL && tcp_echo_flags_control == 1) + // 将数据添加到缓冲区 + if (uart6_buffer_index < UART6_BUFFER_SIZE) { - // 尝试发送数据 - err = tcp_write(server_pcb_control, rx_buffer, 1, 1); - if (err == ERR_OK) + uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits; + uart6_last_rx_time = current_time; // 更新最后接收时间 + } + else + { + // 缓冲区满,强制发送 + if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && uart6_buffer_index > 0) { - err = tcp_output(server_pcb_control); - if (err != ERR_OK) + err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1); + if (err == ERR_OK) { - // TCP输出失败,可能需要重新建立连接 - tcp_abort(server_pcb_control); - server_pcb_control = NULL; - tcp_echo_flags_control = 0; + tcp_output(server_pcb_control); } } - else if (err == ERR_MEM) - { - // 内存不足,等待一段时间后重试 - vTaskDelay(10); - } - else - { - // 其他错误,关闭连接 - tcp_abort(server_pcb_control); - server_pcb_control = NULL; - tcp_echo_flags_control = 0; - } + // 重置缓冲区 + uart6_buffer_index = 0; + uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits; + uart6_last_rx_time = current_time; } } else @@ -569,7 +575,47 @@ void start_usart6_test_task(void const *argument) } } - vTaskDelay(1); // 给其他任务执行的机会 + // 检查超时,如果超时且有数据则发送 + if (uart6_buffer_index > 0 && + uart6_last_rx_time > 0 && + (current_time - uart6_last_rx_time) >= UART6_TIMEOUT_MS) + { + // 检查TCP连接状态并发送缓冲区数据 + if (server_pcb_control != NULL && tcp_echo_flags_control == 1) + { + err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1); + if (err == ERR_OK) + { + err = tcp_output(server_pcb_control); + if (err != ERR_OK) + { + // TCP输出失败,关闭连接 + tcp_abort(server_pcb_control); + server_pcb_control = NULL; + tcp_echo_flags_control = 0; + } + } + else if (err == ERR_MEM) + { + // 内存不足,等待一段时间后重试 + vTaskDelay(10); + continue; // 不清除缓冲区,下次重试 + } + else + { + // 其他错误(如连接已关闭),关闭连接 + tcp_abort(server_pcb_control); + server_pcb_control = NULL; + tcp_echo_flags_control = 0; + } + } + + // 重置缓冲区 + uart6_buffer_index = 0; + uart6_last_rx_time = 0; + } + + vTaskDelay(5); // 给其他任务执行的机会 } /* USER CODE END start_usart6_test_task */ } diff --git a/Core/Src/usart.c b/Core/Src/usart.c index e7e7f53..b9a5aa1 100644 --- a/Core/Src/usart.c +++ b/Core/Src/usart.c @@ -786,26 +786,50 @@ void HAL_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma) } /** - * @brief 使用DMA发送USART数据 + * @brief 使用DMA发送USART数据(改进版) * - * 通过USART使用DMA发送数据 + * 通过USART使用DMA发送数据,添加超时机制防止卡死 * * @param huart USART句柄,类型为UART_HandleTypeDef结构体指针 * @param buf 要发送的数据缓冲区指针 * @param len 要发送的数据长度 + * @return HAL_StatusTypeDef 发送状态 */ -void dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len) +HAL_StatusTypeDef dma_usart_send(UART_HandleTypeDef *huart, uint8_t *buf, uint8_t len) { - /* 等待上一次传输完成 */ + uint32_t timeout = 1000; // 1秒超时 + uint32_t start_time = HAL_GetTick(); + + // 检查参数有效性 + if (huart == NULL || buf == NULL || len == 0) { + return HAL_ERROR; + } + + /* 等待上一次传输完成,添加超时机制 */ while(huart->gState == HAL_UART_STATE_BUSY_TX) { + if ((HAL_GetTick() - start_time) > timeout) { + // 超时,强制停止DMA传输 + HAL_UART_DMAStop(huart); + huart->gState = HAL_UART_STATE_READY; + return HAL_TIMEOUT; + } osDelay(1); } - if (HAL_UART_Transmit_DMA(huart, buf, len) != HAL_OK) - { - Error_Handler(); + // 检查UART状态 + if (huart->gState != HAL_UART_STATE_READY) { + return HAL_BUSY; } + + // 启动DMA传输 + HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(huart, buf, len); + if (status != HAL_OK) { + // DMA启动失败,重置UART状态 + huart->gState = HAL_UART_STATE_READY; + } + + return status; } /* USER CODE END 1 */ diff --git a/User/application/src/tcpserverc.c b/User/application/src/tcpserverc.c index 875e44b..9e62d1b 100644 --- a/User/application/src/tcpserverc.c +++ b/User/application/src/tcpserverc.c @@ -472,19 +472,21 @@ uint16_t handle_type_88(const uint8_t *body, uint16_t body_len, uint8_t *tx) tx[total_len - 2] = 0x00; // 高8位强制为0 tx[total_len - 1] = checksum & 0xFF; - if (huart6.gState == HAL_UART_STATE_READY) + // 改进的UART6发送处理 + HART1_RTS_SEND; + vTaskDelay(5); + + HAL_StatusTypeDef uart_status = HAL_UART_Transmit(&huart6, body, body_len, 1000); // 增加超时时间 + if (uart_status != HAL_OK) { - - HART1_RTS_SEND; - vTaskDelay(5); - if (HAL_UART_Transmit(&huart6, body, body_len, 100) != HAL_OK) - { - Error_Handler(); - hart_ht1200m_reset(); - } - vTaskDelay(5); - HART1_RTS_RECEIVE; + // UART发送失败,不调用Error_Handler,而是重置HART模块 + hart_ht1200m_reset(); + HAL_UART_DeInit(&huart6); + MX_USART6_UART_Init(); } + + vTaskDelay(5); + HART1_RTS_RECEIVE; return total_len; } @@ -498,11 +500,21 @@ static err_t tcpecho_recv_hart1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度 server_pcb_hart1 = tpcb; // 直接赋值 memcpy(hart1_uart5.tx_data, (int *)p->payload, p->tot_len); - if (huart5.gState == HAL_UART_STATE_READY) + + // 改进的DMA发送处理 + HAL_StatusTypeDef dma_status = dma_usart_send(&huart5, hart1_uart5.tx_data, p->tot_len); + if (dma_status != HAL_OK) { - HART1_RTS_SEND; - dma_usart_send(&huart5, hart1_uart5.tx_data, p->tot_len); + // DMA发送失败,记录错误但不调用Error_Handler + // 可以在这里添加错误计数或重试逻辑 + if (dma_status == HAL_TIMEOUT) + { + // 超时错误,可能需要重置UART + HAL_UART_DeInit(&huart5); + MX_UART5_Init(); + } } + pbuf_free(p); } else if (err == ERR_OK) // 检测到对方主动关闭连接时,也会调用recv函数,此时p为空 @@ -523,10 +535,18 @@ static err_t tcpecho_recv_hart2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度 server_pcb_hart2 = tpcb; // 直接赋值 memcpy(hart2_uart2.tx_data, (int *)p->payload, p->tot_len); - if (huart2.gState == HAL_UART_STATE_READY) + + // 改进的DMA发送处理 + HAL_StatusTypeDef dma_status = dma_usart_send(&huart2, hart2_uart2.tx_data, p->tot_len); + if (dma_status != HAL_OK) { - //HART2_RTS_SEND; - dma_usart_send(&huart2, hart2_uart2.tx_data, p->tot_len); + // DMA发送失败处理 + if (dma_status == HAL_TIMEOUT) + { + // 超时错误,重置UART + HAL_UART_DeInit(&huart2); + MX_USART2_UART_Init(); + } } pbuf_free(p); @@ -550,9 +570,18 @@ static err_t tcpecho_recv_ble1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, server_pcb_ble1 = tpcb; // 直接赋值 memcpy(ble1_uart6.tx_data, (int *)p->payload, p->tot_len); - if (huart6.gState == HAL_UART_STATE_READY) + + // 改进的DMA发送处理 + HAL_StatusTypeDef dma_status = dma_usart_send(&huart6, ble1_uart6.tx_data, p->tot_len); + if (dma_status != HAL_OK) { - dma_usart_send(&huart6, ble1_uart6.tx_data, p->tot_len); + // DMA发送失败处理 + if (dma_status == HAL_TIMEOUT) + { + // 超时错误,重置UART + HAL_UART_DeInit(&huart6); + MX_USART6_UART_Init(); + } } pbuf_free(p); @@ -574,10 +603,20 @@ static err_t tcpecho_recv_ble2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, tcp_recved(tpcb, p->tot_len); // 读取数据的控制块 得到所有数据的长度 server_pcb_ble2 = tpcb; // 直接赋值 memcpy(ble2_uart3.tx_data, (int *)p->payload, p->tot_len); - if (huart3.gState == HAL_UART_STATE_READY) + + // 改进的DMA发送处理 + HAL_StatusTypeDef dma_status = dma_usart_send(&huart3, ble2_uart3.tx_data, p->tot_len); + if (dma_status != HAL_OK) { - dma_usart_send(&huart3, ble2_uart3.tx_data, p->tot_len); + // DMA发送失败处理 + if (dma_status == HAL_TIMEOUT) + { + // 超时错误,重置UART + HAL_UART_DeInit(&huart3); + MX_USART3_UART_Init(); + } } + pbuf_free(p); } else if (err == ERR_OK) // 检测到对方主动关闭连接时,也会调用recv函数,此时p为空 @@ -818,31 +857,101 @@ void tcp_echo_init(void) void user_send_data_hart1(uint8_t *data, uint16_t len) { - - tcp_write(server_pcb_hart1, data, len, 1); + if (server_pcb_hart1 != NULL && tcp_echo_flags_hart1 == 1 && data != NULL && len > 0) + { + err_t err = tcp_write(server_pcb_hart1, data, len, 1); + if (err != ERR_OK) + { + // TCP写入失败,关闭连接 + tcp_abort(server_pcb_hart1); + server_pcb_hart1 = NULL; + tcp_echo_flags_hart1 = 0; + } + else + { + // 立即输出数据 + tcp_output(server_pcb_hart1); + } + } } void user_send_data_hart2(uint8_t *data, uint16_t len) { - - tcp_write(server_pcb_hart2, data, len, 1); + if (server_pcb_hart2 != NULL && tcp_echo_flags_hart2 == 1 && data != NULL && len > 0) + { + err_t err = tcp_write(server_pcb_hart2, data, len, 1); + if (err != ERR_OK) + { + // TCP写入失败,关闭连接 + tcp_abort(server_pcb_hart2); + server_pcb_hart2 = NULL; + tcp_echo_flags_hart2 = 0; + } + else + { + // 立即输出数据 + tcp_output(server_pcb_hart2); + } + } } #if (BLE2_USART6 == 1) void user_send_data_ble1(uint8_t *data, uint16_t len) { - - tcp_write(server_pcb_ble1, data, len, 1); + if (server_pcb_ble1 != NULL && tcp_echo_flags_ble1 == 1 && data != NULL && len > 0) + { + err_t err = tcp_write(server_pcb_ble1, data, len, 1); + if (err != ERR_OK) + { + // TCP写入失败,关闭连接 + tcp_abort(server_pcb_ble1); + server_pcb_ble1 = NULL; + tcp_echo_flags_ble1 = 0; + } + else + { + // 立即输出数据 + tcp_output(server_pcb_ble1); + } + } } #endif void user_send_data_ble2(uint8_t *data, uint16_t len) { - - tcp_write(server_pcb_ble2, data, len, 1); + if (server_pcb_ble2 != NULL && tcp_echo_flags_ble2 == 1 && data != NULL && len > 0) + { + err_t err = tcp_write(server_pcb_ble2, data, len, 1); + if (err != ERR_OK) + { + // TCP写入失败,关闭连接 + tcp_abort(server_pcb_ble2); + server_pcb_ble2 = NULL; + tcp_echo_flags_ble2 = 0; + } + else + { + // 立即输出数据 + tcp_output(server_pcb_ble2); + } + } } void user_send_data_control(uint8_t *data, uint16_t len) { - - tcp_write(server_pcb_control, data, len, 1); + if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && data != NULL && len > 0) + { + err_t err = tcp_write(server_pcb_control, data, len, 1); + if (err != ERR_OK) + { + // TCP写入失败,关闭连接 + tcp_abort(server_pcb_control); + server_pcb_control = NULL; + tcp_echo_flags_control = 0; + } + else + { + // 立即输出数据 + tcp_output(server_pcb_control); + } + } } void uart_forwarding_tcp(void)