串口环形缓冲区强化:单独单写及最小临界区修改

This commit is contained in:
2026-02-24 14:22:01 +08:00
parent 7419dec1b5
commit 1e50a94427
5 changed files with 52 additions and 0 deletions

View File

@@ -11,6 +11,7 @@
#include "command.h"
#include "uart_ring_buffer.h"
#include "uart.h"
#include "led.h"
#include <stdint.h>
#include <stdbool.h>
@@ -588,7 +589,9 @@ void command_process(void) {
handle_command(cmd_buf, expected_cmd_len);
} else {
// 验证失败时清空缓冲区,避免后续帧受影响
uart_rx_irq_pause();
uart_ring_buffer_clear();
uart_rx_irq_resume();
}
// 复位,等待下一帧
@@ -633,7 +636,9 @@ void command_execute(const char *cmd_str)
frame_buf[frame_len - 1] = (uint8_t)(crc & 0xFF);
// 清空缓冲区并执行命令
uart_rx_irq_pause();
uart_ring_buffer_clear();
uart_rx_irq_resume();
for (uint8_t i = 0; i < frame_len; i++) {
uart_ring_buffer_put(frame_buf[i]);
}

View File

@@ -32,6 +32,14 @@ void uart_init(void) {
usart_interrupt_enable(UART_PHY, USART_INT_RBNE);
}
void uart_rx_irq_pause(void) {
usart_interrupt_disable(UART_PHY, USART_INT_RBNE);
}
void uart_rx_irq_resume(void) {
usart_interrupt_enable(UART_PHY, USART_INT_RBNE);
}
/******************************************************************************/
/* 具体的中断处理函数实现 */
/******************************************************************************/

View File

@@ -6,12 +6,25 @@
* @ingroup RingBuffer
*/
#include "uart_ring_buffer.h"
#include "gd32e23x.h"
static volatile uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];
static volatile uint8_t write_index = 0;
static volatile uint8_t read_index = 0;
static volatile uint32_t dropped_bytes = 0;
static inline uint32_t irq_save(void) {
uint32_t primask = __get_PRIMASK();
__disable_irq();
return primask;
}
static inline void irq_restore(uint32_t primask) {
if (primask == 0U) {
__enable_irq();
}
}
/**
* @brief 重置环形缓冲区状态。
* @details 将读指针、写指针与丢弃计数清零,不清空数据区内容。
@@ -31,7 +44,9 @@ static void uart_ring_buffer_reset_state(void) {
* @ingroup RingBuffer
*/
void uart_ring_buffer_init(void) {
uint32_t irq_key = irq_save();
uart_ring_buffer_reset_state();
irq_restore(irq_key);
}
/**
@@ -90,7 +105,9 @@ bool uart_ring_buffer_put(uint8_t data) {
* @ingroup RingBuffer
*/
void uart_ring_buffer_clear(void) {
uint32_t irq_key = irq_save();
uart_ring_buffer_reset_state();
irq_restore(irq_key);
}
/**