C++如何实现简单的环形缓冲区_C++在嵌入式通信中的数据存储【案例】-C++

环形缓冲区核心是用数组模拟首尾相连队列,靠volatile head/tail指针控制读写,采用“预留空位”法判满((tail+1)&(cap-1)==head),配合位运算与DMB内存屏障实现裸机下无锁安全通信。

环形缓冲区的核心实现逻辑是什么

环形缓冲区本质是用数组模拟首尾相连的队列,靠两个指针(head 和 tail)控制读写位置,避免数据搬移。在嵌入式通信中,它常用于串口、CAN 或 SPI 接收中断服务程序(ISR)与主循环之间的解耦——ISR 只管往里写,主循环只管往外读,不加锁也能安全运行(前提是单生产者 + 单消费者,且不跨线程)。

关键不是“怎么封装类”,而是“怎么保证边界不越界、不覆盖、不漏读”。最简实现只需三个成员:buffer(固定大小数组)、head(下一次读的位置)、tail(下一次写的位置),以及一个预设容量 capacity。

常见错误现象:head == tail 时无法区分“空”和“满”;直接用 (tail + 1) % capacity 判断是否满,但未预留一个空位;在 ISR 中修改 tail 后没做内存屏障(ARM Cortex-M 上可能被编译器乱序优化)。

  • 推荐用“预留一个空位”法:缓冲区实际可用长度为 capacity - 1,full() 条件是 (tail + 1) % capacity == head
  • head 和 tail 必须声明为 volatile(若在 ISR 和主循环间共享),或使用 std::atomic(C++11 起,但嵌入式常禁用 STL)
  • 容量建议设为 2 的幂(如 64、256),方便用位运算替代取模:tail = (tail + 1) & (capacity - 1),省去除法开销

如何在裸机嵌入式环境里安全地用 C++ 实现

裸机(无 OS、无 STL)下不能依赖 std::queue 或 std::vector,必须手写、零动态分配、所有变量静态或栈上。典型结构体如下:

立即学习“C++免费学习笔记(深入)”;

struct RingBuffer {
    uint8_t buffer[256];
    volatile uint16_t head;
    volatile uint16_t tail;
    static const uint16_t capacity = 256;
};

注意:uint16_t 足够覆盖 64KB 缓冲区,但若容量 ≤ 256,可用 uint8_t 节省空间;volatile 是强制要求,否则编译器可能缓存 head/tail 值导致读写逻辑失效。

写操作(如 UART RX ISR 中):

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » C++如何实现简单的环形缓冲区_C++在嵌入式通信中的数据存储【案例】-C++
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4009089+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4009089+
  • 本周更新: 0+
  • 最后更新: 2026-03-16