登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
环形缓冲区在嵌入式系统中的应用:串口中断VS主循环 ...
环形缓冲区在嵌入式系统中的应用:串口中断VS主循环
[ 复制链接 ]
讣丢
3 小时前
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
为什么要用环形缓冲区
假设有这样的场景:串口中断正在快速读取数据,主循环中较慢地解析数据。如果保存串口当前发送的数据后立即做处理,可能会有丢帧的风险。如果我们使用先进先出的数据结构——环形缓冲区,把串口存取的数据存进去,主循环可随时读取,既可以规避掉丢帧的风险,也确保了数据次序正确。
环形缓冲区的实现
需要一个缓存数组,它是固定大小的,来作为环形缓冲区。为了正确的读取数据,我们还需要写指针和读指针。指针的移动,通过_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
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
环形
缓冲区
嵌入式
系统
中的
相关帖子
Java 中的 实现、泛型
.NET 高级开发 | 日志系统使用技巧
Claude Code 系统提示词大公开
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
MVC中的拦截器实现案例
windows11系统安装openclaw
.NET 高级开发 | .NET 中的序列化和反序列化
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
Java 中的 实现、泛型
0
523
殳世英
2026-03-31
业界
.NET 高级开发 | 日志系统使用技巧
2
941
泥地锚
2026-04-01
业界
Claude Code 系统提示词大公开
2
920
梦霉
2026-04-01
业界
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
1
727
掳诚
2026-04-01
业界
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
2
755
浅皮懔
2026-04-01
业界
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
2
493
岑韬哎
2026-04-01
业界
实时行情系统的第一道槛:如何应对数据源的“限流”与“断流”
2
711
人弧
2026-04-01
业界
MVC中的拦截器实现案例
1
306
灼巾
2026-04-02
科技
windows11系统安装openclaw
5
872
卢铃语
2026-04-02
业界
.NET 高级开发 | .NET 中的序列化和反序列化
1
534
篁瞑普
2026-04-07
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
讣丢
3 小时前
关注
0
粉丝关注
28
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991126
anyue1937
9994892
kk14977
6845359
4
xiangqian
638210
5
神泱
9516
6
宋子
9875
7
韶又彤
9909
8
荪俗
8988
9
蓬森莉
9867
10
二艰糖
9515
查看更多
今日好文热榜
870
OpenSpec + Claude Code 实战指南:让 AI
23
Redis Sentinel高可用实战:主从自动故障转
290
自感痕迹论:差异即意义(含参考文献引用)
443
自感痕迹论:差异即意义(含参考文献引用)
498
自感痕迹论:差异即意义(含参考文献引用)
300
自感痕迹论:差异即意义(含参考文献引用)
963
自感痕迹论:差异即意义(含参考文献引用)
1001
自感痕迹论:差异即意义(含参考文献引用)
804
自感痕迹论:差异即意义(含参考文献引用)
900
环形缓冲区在嵌入式系统中的应用:串口中断
541
自感痕迹论:差异即意义(含参考文献引用)
254
自感痕迹论:差异即意义(含参考文献引用)
2
我帮你测过了,测试圈排名第一的 Skill 果
439
自感痕迹论:差异即意义(含参考文献引用)
154
自感痕迹论:差异即意义(含参考文献引用)
3
热门视频是怎样炼成的——基于 B站“每周必
757
自感痕迹论:差异即意义(含参考文献引用)
2
我帮你测过了,测试圈排名第一的 Skill 果
2
我帮你测过了,测试圈排名第一的 Skill 果
963
如何用交换机命令行创建 VLAN(轻松秒懂)