串口缓冲区管理分析

2023-05-16


 

一、 概述:

串口使用时一般包含两个缓冲区,即发送缓冲区和接收缓冲区。发送数据时,先将数据存在发送缓冲区,然后通过串口发送;接收数据时,先将接收的数据存在接收缓冲区,然后再进行读取。

 

合理恰当的使用缓冲区,不仅可以使不同设备间正常通信,而且还有助于节约内存,提高效率。

 

二、缓冲区分配管理:

方法一:

通过内存池实现

 

1、数据结构:

 

struct _CHN_POOL_MGR

{

    u8 buffer[BUF_SZ];

    u32 free_bitmap;

};

 

参数含义:struct _CHN_POOL_MGR:内存池的数据类型

 

buffer:缓冲区,大小为BUF_SZ  192

 

free_bitmap:标志位。

 

注意:缓冲区又分为若干块,每块大小BLK_SZ

 

 

 

free_bitmap标志缓冲区块中的空闲块和被使用块,1表示空闲,0表示被使用

 

 

 

注:阴影部分表示存放着数据

 

free_bitmap初始化为(1 << (sizeof(chn_pool_mgr.buffer) / BLK_SZ)) -1即(1 << (2^10/2^6)) -1,即二进制数11111...11111b,共16个1,缓冲区块全部空闲

 

alloc_a_slot()函数分配缓冲区块:检测free_bitmap值,将空闲的缓冲区块标号较小的块分配,返回分配的缓冲区块的标号

 

free_bitmap值

分配的缓冲区块标号

alloc_a_slot()返回值

1111...111111

0

0

1111...111100

2

2

1111...110010

1

1

1111...000100

2

2

//不是太明白????

 

 

struct _CHN_SLOT

{

    s16 tx; 

    s16 rx;

    /*the current count of this channel */

    s16 data_cnt; 

    s16 data_max;

};

 

参数含义:struct _CHN_SLOT:记录缓冲区读写状态的结构体

 

tx:记录缓冲区块标号和数据的写入位置(具体存放如图所示)

rx:记录缓冲区块标号和数据的读取位置(具体存放如图所示)

 

data_cnt:记录缓冲区中未读取的数据量

data_max:向缓冲区中写入数据时,缓冲区中允许存在的最大数据量

 

 

tx,rx数据含义:

 

 

 

 

 

2,实例分析

 

1)向缓冲区中写数据:

 

向缓冲区中写数据,每次写90个字节,写两次。

 

初始状态:

假设struct _CHN_SLOT结构体中各参数均为初始状态:tx = rx = INVALID_PTR,即(INVALID_BLK_NO << BLK_NO_SHIFT),data_cnt为0,data_max为UART_MAX_LEN

 

内存池的状态如下:

 

 

写数据:

 

alloc_a_slot()分配缓冲区块:

 

检测free_bitmap,分配缓冲区块标号为2的块;

tx记录缓冲区块标号及写入数据位置(0x80);

缓冲区块最后一个字节置为INVALID_BLK_NO;

 

变为如下状态:

 

 

写入90个数据:

由于90 > BLK_SZ-1(一个块存放数据的最大字节数),所以再次调用alloc_a_slot()分配缓冲区块

 

检测free_bitmap,分配缓冲区块标号为4的块;

tx记录缓冲区块标号及写入数据位置(0x100);

缓冲区块最后一个字节置为INVALID_BLK_NO;

此外,还要使标号为2的块的最后一个字节记录下一块的标号(4),最后将剩余的数据写入,tx记录数据位置(0x11B)

 

 

写入完成后,各参数状态如下:

 

 

第二次写入数据:

 

与上面类似,根据tx记录的缓冲区块标号及数据位置继续向后写。

 

 

最终变为如下状态:

 

 

 

 

 

3)从缓冲区中读数据

从缓冲区中读数据,每次读40个,读完为止。

 

假设此时缓冲区状态,及各参数如下:

 

 

 

 

data_cnt为180

 

 

此时开始读取数据,rx记录缓冲区标号及数据位置,成功读取40个数据后变为:

 

 

继续读数据,标号为2的缓冲区块内的数据读完,由该块内最后一个字节得知下一缓冲区块的标号,rx记录,此时,各参数状态如下:

 

 

 

 

继续读取,data_cnt变为0,读取结束。

 

 

小结:

由以上分析可知,使用内存池的方法,通过检测free_bitmap可使缓冲区被多个任务共同使用,节约空间。

 

 

 

方法二:

利用循环队列实现

 

1、数据类型:

struct _CHN_SLOT

{

int tx, rx;

u8 buf[BUFFER_LEN];

};

 

参数含义:

tx:记录缓冲区写入位置

rx:记录缓冲区读取位置

buf:缓冲区

 

 

2、方法实现:

 

每存入一个字节,tx后移一位,每取走一个字节,rx后移一位

 

 

 

当tx移至缓冲区结尾时,若缓冲区头部已读取,则tx会继续在头部存放数据,如下:

 

 

当(rx + 1) % BUFFER_LEN == tx时,缓冲区存满

 

 

 

三、两种方法的比较:

比较内容

方法一

方法二(循环队列式)

使用缓冲区的任务数

允许多任务

只能单任务

空间利用率

缓冲区的使用顺序

优先使用低地址处的缓冲区块

由低地址到高地址循环使用

不能存放数据的字节数

缓冲区块数

1B

编程复杂度

略微复杂

简单

 

注:方法一不能存放数据的字节数用于记录下一缓冲区块的位置;循环队列式,不能存放数据的字节数用于循环使用缓冲区

 

 

方法一最大的好处在于可同时被多个任务共同使用,互不影响,有助于节约内存;而且每次分配空间时,会优先使用低地址处的空闲块,数据集中,有利于减少内存池的占用;某一任务释放的空间可被另一任务使用,提高了利用率,但编程略微复杂。

 

循环队列式编程简单,容易理解,特别适合单任务的使用,但缓冲区的利用率不是很高,且无法多任务使用。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口缓冲区管理分析 的相关文章

  • 小小鉴赏(闹着玩)

    when you believe xff1a 作曲 Stephen Schwartz 作词 Stephen Schwartz Many xff08 span class hljs attribute 39 meni span xff09 n
  • 技术分享 | GPS无人机集群

    随着人工智能的发展 xff0c 机器人行业也进入了高速发展的阶段 xff0c 在今年春晚 xff0c 也出现了无人机的身影 xff0c 在高速发展的同时 xff0c 也让人们逐渐体会到单机器人能做的事情是有限的 xff0c 多机器人 编队
  • 技术分享 | 开源不稳?试试DJI N3飞控呢

    原创阿木实验室 1 DJI N3飞控简介 N3内置双IMU冗余设置 xff0c 结合在线故障检测算法 xff0c 可实现双IMU数据实时互为备份 xff0c 极大地提高了飞行器可靠性 集成8GB工业级SD卡的 黑匣子 数据记录系统 xff0
  • 技术分享 | P450-详解室内外指点飞行来啦

    原理说明 PX4飞控控制系统图 定点飞行就是由传感器 xff08 T265 GPS xff09 获得当前位置数据 xff0c 并且把当前位置作为期望位置 xff0c 即可实现定点飞行 xff0c 此时飞控处于position模式 指点飞行为
  • 技术分享 | P450-圆框跟踪的干货分享

    圆检测流程 xff1a 1 xff0c 利用高斯滤波做预处理 2 xff0c 边界检测部分用到了自适应Canny检测 3 xff0c 将边界分为凹弧和凸弧 xff0c 根据输入参数筛选弧段 4 xff0c 利用弧段来估计椭圆参数 xff0c
  • Linux Xampp 下安装PHP Redis扩展

    cd usr local wget http pecl php net get redis 4 0 1 tgz tar zxvf redis 4 0 1 tgz cd usr local wget http mirrors kernel o
  • 技术分享 | Prometheus(P450)-室内外避障

    原理说明 Astar进行全局路径规划 全局路径规划 1 全局算法和局部算法 全局路径规划是在已知的环境中 xff0c 给机器人规划一条路径 xff0c 路径规划的精度取决于环境获取的准确度 xff0c 全局路径规划可以找到最优解 xff0c
  • PX4官方动态 | 基于FPGA和px4的精准自主降落

    近期Ramon Roche在Twitter上发布了关于使用FPGA实现无人机在目标物体上能够进行精准自主着陆的推文 这次的功能实现是一个在读博士的学生所做的项目 xff0c 希望能在开源社区中得到推广并吸引其余有意向的开发者能一起进行研究
  • 技术分享 | 带你具体部署VINS_FUSION_GPU版本

    前期准备工作已经完成 xff0c 接下来我们就准备VINS在NX的落地 1 下载源码编译 首先VINS gpu版本需要引入OpenCV CUDA版本的加速 xff0c 由于我们的NX镜像已经安装好CUDA xff0c 这里就不在赘叙 xff
  • PX4官方动态 | 带你走进官方教学(二)

    本期是我们第二期官方教学 xff0c 不知道大家有没有跟着我们一起学习第一期的教学呢 xff0c 如果没有看过的同学可以点击链接进行第一期的学习后再来看我们第二期内容 在第一期我们告诉了大家学习方法 xff0c 以及如果从零开始使用PX4自
  • 吊舱追踪 | 车机协同作战小实验

    大家好 xff0c 我是阿木实验室的梓衡 xff0c 今天为大家带来的是我们最新研发的智能吊舱的测试 首先 xff0c 我们会把小吊舱挂载在P450无人机上 xff0c 我们所选择的地面追踪目标是我们的R300无人车 这个吊舱搭载了200W
  • 工实小报 | P450室外首飞教学

    本文将给大家介绍我们P450无人机在进行室外首次飞行时 xff0c 一些常见的注意事项及正确的使用方法 我们在使用这种PX4开源无人机时 xff0c 一定要有一个清楚的认识 它和大疆那种消费级无人机在使用和操作上 xff0c 是有非常大的不
  • 5G时代,将为无人机通讯传输带来哪些新变化?

    众所周知 xff0c 我们正在大步迈向5G时代 xff0c 在近几年的各类媒体关于5G的报道也络绎不绝 与此同时 xff0c 无人机作为空中人工智能领域的 智慧眼 xff0c 其行业应用迅速发展 xff0c 应用需求不断增加 xff0c 对
  • 超小型吊舱它来了,轻松适配多种移动机器人使用场景

    一 设计理念 在无人机 无人车 机器狗等移动机器人场景中 xff0c 往往需要一款小巧 重量轻 成本可控的三轴云台吊舱来实现无人机的航拍 机器人搜寻以及图像识别等功能 而市面上的云台吊舱体积都比较大 xff0c 一些小型增稳云台也不支持角度
  • P600旗舰视觉款正式发布,重新定义视觉追踪与精准定位!

    P600旗舰视觉款无人机是一款准行业级无人机 xff0c 搭载RTK定位系统 xff0c 定位精度可达厘米级 xff0c 飞行路径更精准 姿态更稳定 xff1b 机身搭载Allspark机载计算机 xff0c 算力可达21TOPS xff0
  • [STM32学习笔记1]GPIO初始化,点亮LED

    一 使用STM32cubeMX新建工程并初始化 1 打开STM32cubeMX并新建工程 xff0c 芯片输入STM32F103C8T6 双击芯片进入配置界面 xff0c 首先选择调试方式SYS gt debug gt serial wir
  • 开发人员调试IE9默认IE7模式打开

    IE9的默认就是IE9标准模式啊 xff0c 你可能是启用了组策略里的 打开Internet Explorer 7标准模式 功能 禁用就行 开始菜单 运行 输入gpedit msc后确定 用户设置 管理模板 Windows组件 Intern
  • visual studio屏蔽掉一段代码的组合键

    注释 xff1a Ctrl 43 k 43 c 取消注释 xff1a Ctrl 43 k 43 u

随机推荐