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

rtthread学习笔记系列-- 23 环形缓冲块 ringblock

文章目录

  • 23 环形缓冲块 ringblock
    • 23.1 初始化
    • 23.2 PUT & GET 块
    • 23.3 块释放
    • 23.4 rt_rbb_blk_queue_get
    • 23.5 rt_rbb_blk_alloc

https://github.com/wdfk-prog/RT-Thread-Study

23 环形缓冲块 ringblock

环形块状缓冲区简称为:rbb。与传统的环形缓冲区不同的是,rbb 是一个由很多不定长度的块组成的环形缓冲区,而传统的环形缓冲区是由很多个单字节的 char 组成。rbb 支持 零字节拷贝 。所以 rbb 非常适合用于生产者顺序 put 数据块,消费者顺序 get 数据块的场景,例如:DMA 传输,通信帧的接收与发送等等

ringblk: 是由 多个不同长度 的 block 组成的,ringbuff : 是由单字节的数据组成的。ringblk 每一个 block 有多少个字节可以由用户自己设定。

ringblk 支持零字节拷贝(不需要额外的 memcpy 操作)。所以 rbb 非常适合用于生产者顺序 put 数据块,消费者顺序 get 数据块的场景,例如:DMA 传输,通信帧的接收与发送等等。

23.1 初始化

  1. 初始化块链表和释放链表
  2. 对每一个块链表进行初始化,并插入到释放链表中

23.2 PUT & GET 块

  • put

block->status = RT_RBB_BLK_PUT;
  • get
  1. 判断块链表为空,则返回NULL
  2. 遍历链表,找到具有 RT_RBB_BLK_PUT状态的块,设置状态为 RT_RBB_BLK_GET,返回块指针

23.3 块释放

  1. 从块链表总移除块,并插入到释放链表中

23.4 rt_rbb_blk_queue_get


//遍历块链表for (; node; node = tmp, tmp = rt_slist_next(node)){ 如果下一个 block 为空if (!last_block){// // 获取 list 节点上的结构体的地址last_block = rt_slist_entry(node, struct rt_rbb_blk, list);if (last_block->status == RT_RBB_BLK_PUT){// 保存第一个 blockblk_queue->blocks = last_block;blk_queue->blk_num = 0;}else{// 没有找到可用的 blocklast_block = RT_NULL;continue;}}else{block = rt_slist_entry(node, struct rt_rbb_blk, list);/*1.当前块没有放置状态2.最后一个块和当前块是不连续的3.data_total_size将超出范围*/if (block->status != RT_RBB_BLK_PUT ||last_block->buf > block->buf ||data_total_size + block->size > queue_data_len){break;}/* backup last block */last_block = block;}/* remove current block */data_total_size += last_block->size;last_block->status = RT_RBB_BLK_GET;blk_queue->blk_num++;}

23.5 rt_rbb_blk_alloc


rt_rbb_blk_trt_rbb_blk_alloc(rt_rbb_trbb, rt_size_tblk_size){new_rbb = find_empty_blk_in_set(rbb); // 找到一个空闲块// 判断申请出来的块是不是在 最大范围之内if (rt_slist_len(&rbb->blk_list) < rbb->blk_max_num && new_rbb){if (rt_slist_len(&rbb->blk_list) > 0) // 检查是不是第一次申请blk{   // 获取头节点的结构体起始地址head = rt_slist_first_entry(&rbb->blk_list, struct rt_rbb_blk, list);// 获取尾节点的结构体起始地址tail = rt_slist_tail_entry(&rbb->blk_list, struct rt_rbb_blk, list);if (head->buf <= tail->buf) // 头节点数据缓冲区的地址小于尾节点的数据缓存区的地址{/***                      head                     tail* +--------------------------------------+-----------------+------------------+* |      empty2     | block1 |   block2  |      block3     |       empty1     |* +--------------------------------------+-----------------+------------------+*                            rbb->buf*/// 求出空 block 的大小empty1 = (rbb->buf + rbb->buf_size) - (tail->buf + tail->size);empty2 = head->buf - rbb->buf;// 判断新的 block 可以存放的区域if (empty1 >= blk_size){ // 给 block 结构体赋值rt_slist_append(&rbb->blk_list, &new_rbb->list);new_rbb->status = RT_RBB_BLK_INITED;new_rbb->buf = tail->buf + tail->size;new_rbb->size = blk_size;}elseif (empty2 >= blk_size){// 给 block 结构体赋值rt_slist_append(&rbb->blk_list, &new_rbb->list);new_rbb->status = RT_RBB_BLK_INITED;new_rbb->buf = rbb->buf;new_rbb->size = blk_size;}else{/* no space */new_rbb = NULL;}}else{/***        tail                                              head* +----------------+-------------------------------------+--------+-----------+* |     block3     |                empty1               | block1 |  block2   |* +----------------+-------------------------------------+--------+-----------+*                            rbb->buf*/// 获取空闲的空间empty1 = head->buf - (tail->buf + tail->size);// 判断剩余空间是否够本次的分配if (empty1 >= blk_size){// 给 block 结构体赋值rt_slist_append(&rbb->blk_list, &new_rbb->list);new_rbb->status = RT_RBB_BLK_INITED;new_rbb->buf = tail->buf + tail->size;new_rbb->size = blk_size;}else{   /* no space */new_rbb = NULL;}}}else{/* the list is empty */rt_slist_append(&rbb->blk_list, &new_rbb->list); // 把bew_rbb 链表插入到 rbbnew_rbb->status = RT_RBB_BLK_INITED; // 修改状态为 已经初始化new_rbb->buf = rbb->buf; // 设置缓冲区new_rbb->size = blk_size;// 设置块大小}}else{new_rbb = NULL;}return new_rbb;}
http://www.lryc.cn/news/521872.html

相关文章:

  • HunyuanVideo 文生视频模型实践
  • Qt——QTableWidget 限制单元格输入范围的方法(正则表达式输入校验法、自定义代理类MyItemDelegrate)
  • 深度学习论文: CAS-ViT: Convolutional Additive Self-attention Vision Transformers
  • PyCharm文档管理
  • QNAP 上常用的几款软件
  • LabVIEW智能水肥一体灌溉控制系统
  • 提问:玩游戏输入法总弹出来咋回事哎
  • 链家房价数据爬虫和机器学习数据可视化预测
  • 【微服务】面试题 5、分布式系统理论:CAP 与 BASE 详解
  • 第十二章:算法与程序设计
  • RAG技术:是将知识库的文档和问题共同输入到LLM中
  • 持续集成 01|Gitee介绍、Pycharm使用Gitee
  • 信息安全、网络安全和数据安全的区别和联系
  • C++实现设计模式---抽象工厂模式 (Abstract Factory)
  • K8S开启/关闭审计日志
  • css盒子水平垂直居中
  • px、em 和 rem 的区别:深入理解 CSS 中的单位
  • 基于STM32设计的粮食仓库(粮仓)环境监测系统
  • 【后端面试总结】tls中.crt和.key的关系
  • 日拱一卒(20)——leetcode学习记录:大小为 K 且平均值大于等于阈值的子数组数目
  • 项目练习:若依管理系统字典功能-Vue前端部分
  • apache-skywalking-apm-10.1.0使用
  • 计算机视觉算法实战——视频分析(Video Analysis)
  • 全网首发:编译libssh,产生类似undefined reference to `EVP_aes_256_ctr@OPENSSL_1_1_0‘的大量错误
  • 用python实战excel和word自动化
  • 【云计算】OpenStack云计算平台
  • 好用的php商城源码有哪些?
  • docker安装Nginx UI
  • 为深度学习创建PyTorch张量 - 最佳选项
  • 详解数据增强中的平移shft操作