环形缓冲区在嵌入式系统中的应用:串口中断VS主循环

张开发
2026/4/9 1:35:50 15 分钟阅读

分享文章

环形缓冲区在嵌入式系统中的应用:串口中断VS主循环
环形缓冲区的实现需要一个缓存数组它是固定大小的来作为环形缓冲区。为了正确的读取数据我们还需要写指针和读指针。指针的移动通过_next()函数中指针1取模实现确保数组不会越界。// 1. 缓存数组固定大小的存储空间比如256字节 static volatile uint8_t s_rxbuf[IMU_UART_RX_BUF_SIZE]; // 2. 写指针下一个要写入的位置 static volatile uint16_t s_wr 0; // 3. 读指针下一个要读取的位置 static volatile uint16_t s_rd 0; // 4. 计算下一个位置核心取模实现“环形” static inline uint16_t _next(uint16_t idx) { return (uint16_t)((idx 1u) % IMU_UART_RX_BUF_SIZE); }环形缓冲区的使用回到我们一开始的场景也就是我们决定使用环形缓冲区的起点我们遭遇的是串口中断和主循环之间的矛盾。我们应该在中断中使用写指针写数据。如下_push()函数计算下一个写入位置把字节写入写指针指向的环形缓冲区位置。当下一个写位置与读位置相等时说明缓冲区满了将读位置后移一位即丢弃最旧的一个字节。最后把当前写指针后移。写入数据 _push() 中断里调用static inline void _push(uint8_t b) { // 计算下一个写入位置 uint16_t next _next(s_wr); // 如果【下一个写位置 读位置】 缓冲区满了 if (next s_rd) { s_rd _next(s_rd); // 丢弃最旧的一个字节 } s_rxbuf[s_wr] b; // 把字节写入缓存 s_wr next; // 写指针后移 }同样地在主循环解析数据时需要用到读指针读取数据。如下_pop()函数当写指针和读指针指向同一个位置时说明没有待读数据返回-1如果有待读数据则读出数据读指针后移。2. 读取数据 _pop() 主循环解析调用static inline int _pop(uint8_t *out) { if (s_wr s_rd) return -1; // 空的没数据可读 *out s_rxbuf[s_rd]; // 读出数据 s_rd _next(s_rd); // 读指针后移 return 0; }状态判断总结缓冲区空没数据-》s_wr s_rd缓冲区满存不下-》 _next(s_wr) s_rd

更多文章