当前位置: 首页 > news >正文

循环队列通用模版

循环队列:

RingQ.h

#ifndef RINGQ_H
#define RINGQ_H#include <stdint.h>
#include <stddef.h>
#include "stm32g4xx_hal.h"#ifndef RINGQ_DEFAULT_CAP
#define RINGQ_DEFAULT_CAP  (2048U)   // 默认 2KB
#endif// 可选:RTOS/中断临界区(按需在编译单元里重定义)
#ifndef RINGQ_ENTER_CRITICAL
#define RINGQ_ENTER_CRITICAL() __disable_irq()
#endif
#ifndef RINGQ_EXIT_CRITICAL
#define RINGQ_EXIT_CRITICAL() __enable_irq()
#endif#ifdef __cplusplus
extern "C" {
#endif// 基础循环队列核心(把它放进你自己的结构体即可)
typedef struct {uint8_t  *buf;           // 缓冲区uint32_t  cap;           // 容量(字节)volatile uint32_t head;  // 写索引 [0..cap-1]volatile uint32_t tail;  // 读索引 [0..cap-1]volatile uint32_t size;  // 已用字节数 [0..cap]
} RingQ;// ① 注册/初始化:绑定缓冲并清零
void     RingQ_Register(RingQ *q, void *buf, uint32_t cap);// ② 写入:把 src 的 len 字节写入队列;返回实际写入(空间不足则部分写入)
uint32_t RingQ_Write   (RingQ *q, const void *src, uint32_t len);// ③ 读取:从队列读最多 want_len 字节到 dst;返回实际读到的字节数
uint32_t RingQ_Read    (RingQ *q, void *dst, uint32_t want_len);// 便捷宏:静态声明一个队列与其缓冲,并提供 init
#define RINGQ_DECLARE(name, capacity)                                  \static uint8_t name##_buf[(capacity)];                              \static RingQ   name;                                                \static inline void name##_init(void){                               \RingQ_Register(&name, name##_buf, (capacity));                  \}#ifdef __cplusplus
}
#endif#endif // RINGQ_H

RingQ.c

#include "ringq.h"
#include <string.h>static inline uint32_t _min_u32(uint32_t a, uint32_t b){ return (a<b)?a:b; }void RingQ_Register(RingQ *q, void *buf, uint32_t cap){if (!q || !buf || cap == 0) return;q->buf  = (uint8_t*)buf;q->cap  = cap;q->head = 0;q->tail = 0;q->size = 0;
}uint32_t RingQ_Write(RingQ *q, const void *src_, uint32_t len){if (!q || !src_ || q->cap == 0 || len == 0) return 0;const uint8_t *src = (const uint8_t*)src_;RINGQ_ENTER_CRITICAL();uint32_t free = q->cap - q->size;uint32_t to_write = _min_u32(len, free);uint32_t widx = q->head;uint32_t first  = _min_u32(to_write, q->cap - widx);  // 尾部连续可写if (first) memcpy(&q->buf[widx], src, first);uint32_t second = to_write - first;                   // 环回到起始if (second) memcpy(&q->buf[0], src + first, second);q->head = (widx + to_write) % q->cap;q->size += to_write;RINGQ_EXIT_CRITICAL();return to_write;
}uint32_t RingQ_Read(RingQ *q, void *dst_, uint32_t want_len){if (!q || !dst_ || q->cap == 0 || want_len == 0) return 0;uint8_t *dst = (uint8_t*)dst_;RINGQ_ENTER_CRITICAL();uint32_t used = q->size;uint32_t to_read = _min_u32(want_len, used);uint32_t ridx = q->tail;uint32_t first  = _min_u32(to_read, q->cap - ridx);  // 尾部连续可读if (first) memcpy(dst, &q->buf[ridx], first);uint32_t second = to_read - first;                   // 环回到起始if (second) memcpy(dst + first, &q->buf[0], second);q->tail = (ridx + to_read) % q->cap;q->size -= to_read;RINGQ_EXIT_CRITICAL();return to_read;
}

注意!!!如果存在中断入队的情况记得加上开关中断,那么问题来了,如果不开关中断的话有没有办法不出错呢?

 

http://www.zskr.cn/news/41125.html

相关文章:

  • 如何选择一个人工智能项目
  • STL初识project11
  • CSS 中 overflow 属性的两个分属性 overflow-x 和 overflow-y 互相影响问题
  • Day13显示模式
  • 如何是一个人工智能公司
  • 关于OpenGL在AMD设备无法显示内容的解决方法
  • 超越代码补全:5个能理解你项目上下文的AI编程伙伴
  • 共绩算力 vscode git笔记
  • 不止高精度!正点原子 EL15 深度解析:精度、性价比全拉满!
  • NOIP 模拟赛 2 总结
  • 利用点击劫持漏洞触发XSS攻击:我是如何赚取350美元的
  • 人狗大战Ⅳ
  • 2025年智能家居产品品牌推荐排行 top 5
  • Web3 去魅:写给程序员和普通人的技术解读
  • 2025年度全自动四辊卷板机制造商推荐:四辊卷板机哪家好
  • 2025 年安全触边厂家最新推荐榜:聚焦品质服务商,结合权威测评与市场口碑的全面选购指南防爆灵敏安全触边/无人车安全触边公司推荐
  • 2025 年 11 月高性价比学习机推荐:松鼠 AI S20 深度测评与选购指南
  • 什么是未来的好产业
  • 安川机器人管材焊接智能节气仪
  • 2025年无线充电方案厂家新排行榜,稳定无线充电方案公司推荐
  • 2025年升降舞台机械厂家权威推荐榜单:移动舞台机械/舞台机械方案/异形舞台机械源头厂家精选
  • 2025年河北公司注册代理记账服务权威推荐榜单:河北税务咨询/河北会计税务服务商/河北营业执照年检服务精选
  • 为运动注入智能:结合 AI、立体视觉与边缘计算
  • 2025 年 11 月电能质量分析仪厂家权威推荐榜:A类/B类/动态/三相电能质量监测仪、在线监测装置及系统精选
  • 2025 年 11 月电气防火保护器厂家推荐排行榜,电弧故障保护器/断路器,防火限流保护器,故障电弧探测器,单相/三相保护装置专业选购指南
  • 原型污染攻击工具揭秘:Prototype Pollution Gadgets Finder
  • 2025 年 11 月箱包五金电镀加工,链条电镀加工,饰品电镀加工厂家最新推荐,产能、专利、环保三维数据透视!
  • 我用 Docker 部署 RabbitMQ 踩了 3 个大坑,10 分钟搞定的记录
  • 在远程 Ubuntu 24.04.2 LTS 上安装并运行图形界面
  • Day31-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\Regex-正则表达式+爬虫