generated from hulk/gd32e23x_template_cmake_vscode
120 lines
3.7 KiB
C
120 lines
3.7 KiB
C
/**
|
||
* @file uart_ring_buffer.h
|
||
* @brief 简单高效的环形接收缓冲区(字节队列)接口声明。
|
||
* @details 提供字节写入/读取、可读长度查询、清空与丢弃统计等 API,
|
||
* 适用于中断接收(写)与主循环解析(读)的典型嵌入式串口场景。
|
||
*/
|
||
#ifndef UART_RING_BUFFER_H
|
||
#define UART_RING_BUFFER_H
|
||
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
|
||
/**
|
||
* @def UART_RX_BUFFER_SIZE
|
||
* @brief 接收环形缓冲区容量(单位:字节)。
|
||
* @note 采用“预留一格”区分空/满策略,最大可用容量为 UART_RX_BUFFER_SIZE-1。
|
||
*/
|
||
#define UART_RX_BUFFER_SIZE 64
|
||
|
||
/**
|
||
* @defgroup RingBuffer 环形缓冲区
|
||
* @brief 字节环形缓冲区(接收端)
|
||
* @{
|
||
*/
|
||
|
||
/**
|
||
* @section RingBuffer_Usage 使用说明
|
||
* 典型用法:中断接收(写入环形缓冲)、主循环解析(读取环形缓冲)。
|
||
*
|
||
* 1) 初始化
|
||
* @code{.c}
|
||
* uart_ring_buffer_init();
|
||
* @endcode
|
||
*
|
||
* 2) 使能串口接收非空中断(RBNE)并开启中断(以 USART0 为例)
|
||
* @code{.c}
|
||
* usart_interrupt_enable(USART0, USART_INT_RBNE);
|
||
* nvic_irq_enable(USART0_IRQn, 2, 0); // 根据工程需要设置优先级
|
||
* @endcode
|
||
*
|
||
* 3) 在中断服务函数中写入环形缓冲(参考你当前工程的写法)
|
||
* @code{.c}
|
||
* void USART0_IRQHandler(void) {
|
||
* if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
|
||
* uint8_t data = usart_data_receive(USART0);
|
||
* (void)uart_ring_buffer_put(data); // 缓冲满时丢弃并计数
|
||
* }
|
||
* }
|
||
* @endcode
|
||
*
|
||
* 4) 在主循环中读取处理
|
||
* @code{.c}
|
||
* while (uart_ring_buffer_available() > 0) {
|
||
* int b = uart_ring_buffer_get();
|
||
* if (b >= 0) {
|
||
* // 处理字节 b
|
||
* }
|
||
* }
|
||
* @endcode
|
||
*
|
||
* @note 缓冲区满时新字节会被丢弃,可用 uart_ring_buffer_drop_count() 查看累计丢弃数。
|
||
* @note 采用“预留一格”区分空/满,最大可用容量为 UART_RX_BUFFER_SIZE-1。
|
||
*/
|
||
|
||
/**
|
||
* @brief 初始化环形缓冲区。
|
||
* @details 复位读/写索引与丢弃计数,准备接收数据。
|
||
* @note 若在中断环境使用,初始化前建议关闭相关接收中断以避免并发竞争。
|
||
* @ingroup RingBuffer
|
||
*/
|
||
void uart_ring_buffer_init(void);
|
||
|
||
/**
|
||
* @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);
|
||
|
||
/**
|
||
* @brief 从环形缓冲区读取一个字节。
|
||
* @details 若缓冲区非空,返回队头字节并推进读指针;若为空,返回 -1。
|
||
* @return 读取到的字节(0..255),或 -1 表示缓冲区为空。
|
||
* @retval -1 缓冲区为空,无数据可读。
|
||
* @ingroup RingBuffer
|
||
*/
|
||
int uart_ring_buffer_get(void);
|
||
|
||
/**
|
||
* @brief 向环形缓冲区写入一个字节。
|
||
* @param data 待写入的字节。
|
||
* @return 是否写入成功。
|
||
* @retval true 写入成功。
|
||
* @retval false 写入失败(缓冲区已满,数据被丢弃并计数)。
|
||
* @note 如需改为“覆盖写入”策略,可在满时先推进读指针再写入。
|
||
* @ingroup RingBuffer
|
||
*/
|
||
bool uart_ring_buffer_put(uint8_t data);
|
||
|
||
/**
|
||
* @brief 清空环形缓冲区。
|
||
* @details 复位读/写索引与丢弃计数,相当于逻辑上丢弃所有已接收数据,不擦除数据区内容。
|
||
* @ingroup RingBuffer
|
||
*/
|
||
void uart_ring_buffer_clear(void);
|
||
|
||
/**
|
||
* @brief 获取因缓冲区满而被丢弃的字节累计数量。
|
||
* @details 该计数在 init/clear 时清零。
|
||
* @return 丢弃的累计字节数。
|
||
* @ingroup RingBuffer
|
||
*/
|
||
uint32_t uart_ring_buffer_drop_count(void);
|
||
|
||
/** @} */
|
||
|
||
#endif // UART_RING_BUFFER_H
|