generated from hulk/gd32e23x_template_cmake_vscode
Follow the reference to port the bootloader
This commit is contained in:
@@ -1,104 +1,58 @@
|
||||
/**
|
||||
* @file uart_ring_buffer.c
|
||||
* @brief 字节环形接收缓冲区的实现。
|
||||
* @details 适用于中断接收(写)与主循环解析(读)的典型串口场景;
|
||||
* 采用“预留一格”区分空/满,最大可用容量为 UART_RX_BUFFER_SIZE-1。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
#include "uart_ring_buffer.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;
|
||||
// 环形缓冲区结构体定义(精简版)
|
||||
struct uart_ring_buffer {
|
||||
volatile uint8_t buffer[UART_RX_BUFFER_SIZE];
|
||||
volatile uint8_t head; // 写指针
|
||||
volatile uint8_t tail; // 读指针
|
||||
};
|
||||
|
||||
static uart_ring_buffer_t uart_rx_buf = {0};
|
||||
|
||||
/**
|
||||
* @brief 重置环形缓冲区状态。
|
||||
* @details 将读指针、写指针与丢弃计数清零,不清空数据区内容。
|
||||
* @note 内部工具函数;对外请优先使用 uart_ring_buffer_init()/uart_ring_buffer_clear()。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
static void uart_ring_buffer_reset_state(void) {
|
||||
write_index = 0;
|
||||
read_index = 0;
|
||||
dropped_bytes = 0;
|
||||
uart_rx_buf.head = 0;
|
||||
uart_rx_buf.tail = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化环形缓冲区。
|
||||
* @details 调用内部重置逻辑,复位读写索引与丢弃计数,准备接收数据。
|
||||
* @note 若在中断环境使用,初始化前建议关闭相关接收中断以避免并发竞争。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
void uart_ring_buffer_init(void) {
|
||||
uart_ring_buffer_reset_state();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前可读的字节数。
|
||||
* @details 通过读/写指针的快照计算可读长度,范围为 [0, UART_RX_BUFFER_SIZE-1]。
|
||||
* @return uint8_t 可读字节数。
|
||||
* @note 预留一个空槽区分“空/满”,因此满时返回 UART_RX_BUFFER_SIZE-1。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
uint8_t uart_ring_buffer_available(void) {
|
||||
/* 使用快照减少并发不一致窗口 */
|
||||
uint8_t w = write_index;
|
||||
uint8_t r = read_index;
|
||||
return (uint8_t)((w + UART_RX_BUFFER_SIZE - r) % UART_RX_BUFFER_SIZE);
|
||||
uint8_t h = uart_rx_buf.head;
|
||||
uint8_t t = uart_rx_buf.tail;
|
||||
return (uint8_t)((h + UART_RX_BUFFER_SIZE - t) % UART_RX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从环形缓冲区读取一个字节。
|
||||
* @details 若缓冲区非空,返回队头字节并推进读指针;若为空,返回 -1。
|
||||
* @return int 读取到的字节(0..255),或 -1 表示缓冲区为空。
|
||||
* @ingroup RingBuffer
|
||||
* @brief 从UART环形缓冲区中获取一个数据
|
||||
*
|
||||
* @return int 成功返回获取到的8位数据,如果缓冲区为空则返回-1
|
||||
*/
|
||||
int uart_ring_buffer_get(void) {
|
||||
if (read_index == write_index) return -1; // 空
|
||||
uint8_t data = uart_rx_buffer[read_index];
|
||||
read_index = (read_index + 1) % UART_RX_BUFFER_SIZE;
|
||||
// 检查环形缓冲区是否为空(tail与head相等表示缓冲区为空)
|
||||
if (uart_rx_buf.tail == uart_rx_buf.head) return -1;
|
||||
// 从缓冲区tail位置获取数据
|
||||
uint8_t data = uart_rx_buf.buffer[uart_rx_buf.tail];
|
||||
// 更新tail位置,实现环形缓冲区的循环使用
|
||||
// 使用取模运算确保tail在缓冲区大小范围内循环
|
||||
uart_rx_buf.tail = (uart_rx_buf.tail + 1) % UART_RX_BUFFER_SIZE;
|
||||
// 返回获取到的数据
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 向环形缓冲区写入一个字节。
|
||||
* @details 尝试写入一个新字节;若缓冲区已满则丢弃并计数。
|
||||
* @param data 待写入的字节。
|
||||
* @return bool 是否写入成功。
|
||||
* @retval true 写入成功。
|
||||
* @retval false 写入失败(缓冲区已满,数据被丢弃并计数)。
|
||||
* @note 如需“覆盖写入”策略,可在满时先推进读指针再写入。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
bool uart_ring_buffer_put(uint8_t data) {
|
||||
uint8_t next = (write_index + 1) % UART_RX_BUFFER_SIZE;
|
||||
if (next != read_index) { // 缓冲区未满
|
||||
uart_rx_buffer[write_index] = data;
|
||||
write_index = next;
|
||||
uint8_t next = (uart_rx_buf.head + 1) % UART_RX_BUFFER_SIZE;
|
||||
if (next != uart_rx_buf.tail) {
|
||||
uart_rx_buf.buffer[uart_rx_buf.head] = data;
|
||||
uart_rx_buf.head = next;
|
||||
return true;
|
||||
} else {
|
||||
/* 缓冲区已满,丢弃新字节并计数 */
|
||||
dropped_bytes++;
|
||||
// 缓冲区满,静默丢弃新数据
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清空环形缓冲区。
|
||||
* @details 复位读写索引与丢弃计数,相当于逻辑上丢弃所有已接收数据,不擦除数据区内容。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
void uart_ring_buffer_clear(void) {
|
||||
uart_ring_buffer_reset_state();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取因满而被丢弃的字节累计数量。
|
||||
* @details 写入时缓冲区满会丢弃新字节并累加计数;该计数在 init/clear 时清零。
|
||||
* @return uint32_t 丢弃的累计字节数。
|
||||
* @ingroup RingBuffer
|
||||
*/
|
||||
uint32_t uart_ring_buffer_drop_count(void) {
|
||||
return dropped_bytes;
|
||||
}
|
||||
|
Reference in New Issue
Block a user