FreeRTOS之Stream Buffers(流缓冲区)

2023-05-16

ACFly用到了Steam Buffers,特地调了3个最常见的API查了一下,其他的API都和这些差不多。

Steam Buffers 是最近几版本Freertos出现的数据结构。

xStreamBufferCreate:

官网解释:

StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );

@param xBufferSizeBytes
The total number of bytes the stream buffer will be
able to hold at any one time.

@param xTriggerLevelBytes
The number of bytes that must be in the stream buffer before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state.  For example, if a task is blocked on a read of an empty stream buffer that has a trigger level of 1 then the task will be unblocked when a single byte is written to the buffer or the task's block time expires.  As another example, if a task is blocked on a read of an empty stream buffer that has a trigger level of 10 then the task will not be unblocked until the stream buffer contains at least 10 bytes or the task's block time expires.  If a reading task's block time expires before the trigger level is reached then the task will still receive however many bytes are actually available.  Setting a trigger level of 0 will result in a trigger level of 1 being used.  It is not valid to specify a trigger level that is greater than the buffer size.

@return If NULL is returned, then the stream buffer cannot be created because there is insufficient heap memory available for FreeRTOS to allocate the stream buffer data structures and storage area.  A non-NULL value being returned indicates that the stream buffer has been created successfully the returned value should be stored as the handle to the created stream buffer.

@param xBufferSizeBytes
流缓冲区的总字节数
任何时候都能保持。

@param xTriggerLevelBytes
在流缓冲区上阻塞的任务等待数据移出阻塞状态之前,流缓冲区中必须包含的字节数。例如,如果一个任务在读取一个触发器级别为1的空流缓冲区时被阻塞,那么当一个字节被写入缓冲区或任务的阻塞时间到期时,该任务将被解除阻塞。另一个例子是,如果一个任务在读取一个触发级别为10的空流缓冲区时被阻塞,那么该任务将不会被解除阻塞,直到流缓冲区包含至少10个字节或任务的阻塞时间到期。如果一个读任务的阻塞时间在达到触发器级别之前过期,那么该任务仍然会收到实际可用的字节。将触发器级别设置为0将导致使用触发器级别为1。指定大于缓冲区大小的触发器级别是无效的。

@return
如果返回NULL,则无法创建流缓冲区,因为没有足够的堆内存可供FreeRTOS分配流缓冲区数据结构和存储区域。返回的非null值表明流缓冲区已成功创建,返回值应存储为创建的流缓冲区的句柄。

就是比如当xTriggerLevelBytes为1的时候,任务读取流缓冲区数据,除非流缓冲区有一个字节,否则任务将会被阻塞,当一个字节被写入缓冲区或任务的阻塞时间到期时,该任务将被解除阻塞。

 

xStreamBufferSend():

官网解释:
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
                          const void *pvTxData,
                          size_t xDataLengthBytes,
                          TickType_t xTicksToWait );

Sends bytes to a stream buffer. The bytes are copied into the stream buffer.

NOTE: Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message buffer implementation, as message buffers are built on top of stream buffers) assumes there is only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt that will read from the buffer (the reader). It is safe for the writer and reader to be different tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different writers or multiple different readers. If there are to be multiple different writers then the application writer must place each call to a writing API function (such as xStreamBufferSend()) inside a critical section and use a send block time of 0. Likewise, if there are to be multiple different readers then the application writer must place each call to a reading API function (such as xStreamBufferReceive()) inside a critical section and use a receive block time of 0.

Use xStreamBufferSend() to write to a stream buffer from a task. Use xStreamBufferSendFromISR() to write to a stream buffer from an interrupt service routine (ISR).

Stream buffer functionality is enabled by including the FreeRTOS/source/stream_buffer.c source file in the build.

Parameters:
    xStreamBuffer       The handle of the stream buffer to which a stream is being sent.
    pvTxData       A pointer to the buffer that holds the bytes to be copied into the stream buffer.
    xDataLengthBytes       The maximum number of bytes to copy from pvTxData into the stream buffer.
    xTicksToWait       The maximum amount of time the task should remain in the Blocked state to wait for enough space to become available in the stream buffer, should the stream buffer contain too little space to hold the another xDataLengthBytes bytes. The block time is specified in tick periods, so the absolute time it represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out before it can write all xDataLengthBytes into the buffer it will still write as many bytes as possible. A task does not use any CPU time when it is in the blocked state.

Returns:
    The number of bytes written to the stream buffer. If a task times out before it can write all xDataLengthBytes into the buffer it will still write as many bytes as possible.

注意:流缓冲区实现的假定只有一个任务或中断,将写入缓冲区(作者),且只有一个任务或中断,将从缓冲区读取(读者)。编写器和读取器作为不同的任务或中断是安全的,但是,与其他FreeRTOS对象不同的是,拥有多个不同的编写器或多个不同的读取器是不安全的。如果有多个不同的写入器,那么应用程序写入器必须将每个对写入API函数(如xStreamBufferSend())的调用放在一个临界区中,并使用发送阻塞时间为0。同样地,如果有多个不同的读取器,那么应用程序编写器必须将对读取API函数(如xStreamBufferReceive())的每个调用放置在关键区域内,并使用0的接收阻塞时间。

也就是流缓冲区的设计主要是针对单任务写入单任务读取的,对于多任务写入器和多任务读取器,必须将阻塞时间设为0。

参数:

@param xStreamBuffer 流被发送到的流缓冲区的句柄。

@param pvTxData 一个指向缓冲区的指针,该缓冲区保存要复制到流缓冲区中的字节。

@param xDataLengthBytes 从pvTxData复制到流缓冲区的最大字节数。

@param xTicksToWait 任务保持阻塞状态以等待流缓冲区中有足够的可用空间的最大时间,如果流缓冲区包含的空间太少,不能容纳另一个xDataLengthBytes字节。块时间是在滴答周期中指定的,所以它表示的绝对时间依赖于滴答频率。宏pdMS_TO_TICKS()可用于将以毫秒为单位指定的时间转换为以滴答为单位指定的时间。设置xTicksToWait为portMAX_DELAY将导致任务无限期等待(没有超时),前提是在FreeRTOSConfig.h中将INCLUDE_vTaskSuspend设置为1。如果任务在将所有xDataLengthBytes写入缓冲区之前超时,它仍将尽可能多地写入字节。当一个任务处于阻塞状态时,它不会占用任何CPU时间。

@return 写入流缓冲区的字节数。如果任务在将所有xDataLengthBytes写入缓冲区之前超时,它仍将尽可能多地写入字节。

xStreamBufferReceive()

官网解释:

size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
                             void *pvRxData,
                             size_t xBufferLengthBytes,
                             TickType_t xTicksToWait );

Receives bytes from a stream buffer.

NOTE: Uniquely among FreeRTOS objects, the stream buffer implementation (so also the message buffer implementation, as message buffers are built on top of stream buffers) assumes there is only one task or interrupt that will write to the buffer (the writer), and only one task or interrupt that will read from the buffer (the reader). It is safe for the writer and reader to be different tasks or interrupts, but, unlike other FreeRTOS objects, it is not safe to have multiple different writers or multiple different readers. If there are to be multiple different writers then the application writer must place each call to a writing API function (such as xStreamBufferSend()) inside a critical section and use a send block time of 0. Likewise, if there are to be multiple different readers then the application writer must place each call to a reading API function (such as xStreamBufferReceive()) inside a critical section and use a receive block time of 0.

Use xStreamBufferReceive() to read from a stream buffer from a task. Use xStreamBufferReceiveFromISR() to read from a stream buffer from an interrupt service routine (ISR).

Stream buffer functionality is enabled by including the FreeRTOS/source/stream_buffer.c source file in the build.

Parameters:

xStreamBuffer  The handle of the stream buffer from which bytes are to be received.
pvRxData  A pointer to the buffer into which the received bytes will be copied.
xBufferLengthBytes  The length of the buffer pointed to by the pvRxData parameter. This sets the maximum number of bytes to receive in one call. xStreamBufferReceive will return as many bytes as possible up to a maximum set by xBufferLengthBytes.
xTicksToWait  The maximum amount of time the task should remain in the Blocked state to wait for data to become available if the stream buffer is empty. xStreamBufferReceive() will return immediately if xTicksToWait is zero. The block time is specified in tick periods, so the absolute time it represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. A task does not use any CPU time when it is in the Blocked state.

Returns:

The number of bytes read from the stream buffer. This will be the number of bytes available up to a maximum of xBufferLengthBytes. For example:

  • If the trigger level is 1 (the trigger level is set when the stream buffer is created) -
    • If xBufferLengthBytes is 10 and the stream buffer contains 5 bytes when xStreamBufferReceive() is called - then xStreamBufferReceive() will not block, read 5 bytes from the buffer, and return 5.
    • If xBufferLengthBytes is 10 and the stream buffer contains 50 bytes when xStreamBufferReceive() is called - then xStreamBufferReceive() will not block, read 10 bytes from the buffer, and return 10.
    • If xBufferLengthBytes is 10, the stream buffer contains 0 bytes when xStreamBufferReceive() is called, xTicksToWait is 100, and 5 bytes are received into the buffer after 50 ticks - then xStreamBufferReceive() will enter the blocked state for 50 ticks (which is until data arrives in the buffer), after which it will read 5 bytes from the buffer, and return 5.
    • If xBufferLengthBytes is 10, the stream buffer contains 0 bytes when xStreamBufferReceive() is called, xTicksToWait is 100, and no bytes are received into the buffer within 100 ticks - then xStreamBufferReceive() will enter the blocked state for the full block time of 100 ticks, after which it will return 0.
  • If the trigger level is 6 -
    • If xBufferLengthBytes is 10, the stream buffer contains 0 bytes when xStreamBufferReceive() is called, xTicksToWait is 100, and 10 bytes are received into the buffer after 50 ticks - then xStreamBufferReceive() will enter the blocked state for 50 ticks (which is until at least the trigger level number of bytes arrives in the buffer), after which it will read 10 bytes from the buffer, and return 10.
    • If xBufferLengthBytes is 10, the stream buffer contains 0 bytes when xStreamBufferReceive() is called, xTicksToWait is 100, and 5 bytes are received into the buffer after 50 ticks - then xStreamBufferReceive() will remain blocked for the entire 100 tick block period (because the amount of data in the buffer never reached the trigger level), after which it will read 5 bytes from the buffer, and return 5.
    • 从流缓冲区接收字节。

参数:

@param xStreamBuffer 从其中接收字节的流缓冲区句柄。

@param pvRxData 一个指向缓冲区的指针,接收到的字节将被复制到该缓冲区中。

@param xBufferLengthBytes pvRxData 参数所指向的缓冲区长度。这将设置在一个调用中接收的最大字节数。xStreamBufferReceive将返回尽可能多的字节,直到xBufferLengthBytes设置的最大字节。

@param xTicksToWait 当流缓冲区为空时,任务保持阻塞状态以等待数据可用的最大时间。如果xTicksToWait 为零,xStreamBufferReceive()将立即返回。块时间是在滴答周期中指定的,所以它表示的绝对时间依赖于滴答频率。宏pdMS_TO_TICKS()可用于将以毫秒为单位指定的时间转换为以滴答为单位指定的时间。设置xTicksToWait为portMAX_DELAY将导致任务无限期等待(没有超时),前提是在FreeRTOSConfig.h中将INCLUDE_vTaskSuspend设置为1。任务在Blocked状态下不占用CPU时间。
返回:

从流缓冲区读取的字节数。这将是xBufferLengthBytes的最大可用字节数。

官网上举例很清楚:
如果触发级别为1(创建流缓冲区时设置触发级别)

如果xBufferLengthBytes是10并且当xStreamBufferReceive()被调用时,流缓冲区包含5个字节,那么xStreamBufferReceive()将不会阻塞,从缓冲区读取5个字节,并返回5。

如果xBufferLengthBytes是10并且当xStreamBufferReceive()被调用时,流缓冲区包含50字节,那么xStreamBufferReceive()将不会阻塞,从缓冲区读取10个字节,并返回10。

如果xBufferLengthBytes是10,流缓冲区包含0字节当xStreamBufferReceive (), xTicksToWait是100,和5字节接收到缓冲后50Ticks,然后xStreamBufferReceive()将进入阻塞状态50Ticks直到数据到达缓冲区),之后,它将从缓冲区读取5个字节,并返回5。

如果xBufferLengthBytes是10,流缓冲区包含0字节当xStreamBufferReceive (), xTicksToWait是100,和100节拍内没有收到字节缓冲区,那么xStreamBufferReceive()将进入阻塞状态的完整的阻塞时间100个时钟节拍,之后,它将返回0。


如果触发级别为6

如果xBufferLengthBytes是10,流缓冲区包含0字节当xStreamBufferReceive (), xTicksToWait是100,和在50个Ticks后收到10个字节缓冲区,那么xStreamBufferReceive()将进入阻塞状态50Ticks(至少到触发水平到达缓冲区的字节数),之后,它将从缓冲区中读取10个字节,并返回10。

如果xBufferLengthBytes是10,流缓冲区包含0字节当xStreamBufferReceive (), xTicksToWait是100,和在50个Ticks后只收到5个字节缓冲区,那么xStreamBufferReceive()将继续封锁整个100Ticks(因为在缓冲的数据量没有达到触发水平),之后,它将从缓冲区中读取5个字节,并返回5。

 

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

FreeRTOS之Stream Buffers(流缓冲区) 的相关文章

随机推荐

  • linux系统连接windows系统

    linux系统连接windows系统 背景环境思路处理添加 remmina 仓库 背景 远程登录对运维人员来说是一道家常便饭了 xff0c 使用更多的是windows远程登录windows系统 xff0c windows系统登录linux系
  • ansible防火墙firewalld设置

    ansible防火墙firewalld设置 背景需求操作防火墙的开关打开验证 防火墙端口策略打开验证 防火墙服务策略打开验证 背景 防火墙 通过有机结合各类用于安全管理与筛选的软件和硬件设备 xff0c 帮助计算机网络于其内 外网之间构建一
  • linux离线安装软件

    linux离线安装软件 1 背景2 目的3 思路3 1 思路一3 1 1 操作步骤3 1 2 应用场景 xff1a 3 2 思路二3 2 1 操作步骤准备目录下载依赖 3 2 2 应用场景 3 3 思路三3 3 1 下载iso3 3 2 挂
  • 陌生环境下部署的思路

    陌生环境下部署的思路 由来场景一场景二场景三 整体的随想经验 由来 本篇的由来不是来自偶然 xff0c 但是如果说是必然又会显得很唐突 在现场实施部署工作中 xff0c 难免会遇到各种个样 突发 的情况 xff0c 原因不外乎信息的不对称
  • Ubuntu卸载WPS安装Libreoffice

    Ubuntu卸载WPS安装Libreoffice 背景环境卸载WPS安装Libreoffice下载安装卸载 背景 自从2021年10月份安装elementory操作系统以来 xff0c 办公软件一直在使用WPS xff0c 使用上跟wind
  • 我的创作纪念日

    我的创作纪念日 机缘收获日常憧憬 机缘 跟CSDN相识是在十多年前了 xff0c 当时是在上面找资料 xff0c 注册账号是为了下载上面的资源 至于写东西是从2021年开始的 xff0c 与其说是写不如说是记录 xff0c 记录下来工作中用
  • linux 单机部署rabbitmq

    linux 单机部署rabbitmq 背景环境部署下载端口开具erlang安装RabbitMQ安装 背景 rabbitmq 是指在应用间传送的数据 消息可以非常简单 xff0c 比如只包含文本字符串 xff0c 也可以更复杂 xff0c 可
  • linux 服务器时钟同步设置

    linux 服务器时钟同步设置 1 背景2 简介3 环境4 安装及配置5 配置使用5 1 服务端配置5 1 1 修改配置5 1 2 开启同步5 1 3 防火墙策略配置 5 2 客户端配置5 2 1 修改配置5 2 2 开启同步 5 3 ch
  • 电脑安装双系统-linux系统上安装windows系统

    电脑安装双系统 1 背景2 环境3 思路4 操作步骤4 1 安装gparted4 2 设置windows安装驱动器4 3 安装windows10操作系统4 4 设置开机引导 1 背景 电脑安装的elementary OS 5 1 7 基本能
  • MacOS配置iterm2漂亮实用的主题

    效果预览 注意事项 需要oh my zsh请自行安装 安装该主题需要的字体文件 cd git clone https github com powerline fonts git depth 61 1 cd fonts install sh
  • 使用python 将excel中数据批量生成word周报

    使用python 将excel中数据调用word模板批量生成word周报 背景环境功能需求程序实现 背景 日常项目中每周需要召开项目周会 xff0c 会议纪要和会议周报是必不可少的一项内容 xff0c 会议纪要要求监理方会后发送给参会方成员
  • 自动化运维-批量安装Linux操作系统

    自动化运维 批量安装Linux操作系统 1 背景2 Cobbler基础2 1 Cobbler介绍2 2 Cobbler服务 3 系统环境3 1 系统环境3 2 网络环境3 2 1 实体机网络设置3 2 2 虚拟机网络设置3 2 2 1 VM
  • linux操作系统中业务程序及服务的开机启动

    linux操作系统中业务程序及服务的开机启动设置 1 背景2 目标3 启动类型3 1 服务启动systemctl3 2 服务启动chkconfig3 2 1 查看服务3 2 2 系统自带服务的设置3 2 3 添加服务设置 3 3 开机启动脚
  • Thinkpad X201i笔记本电脑开机Fan Error

    Thinkpad X201i笔记本电脑开机Fan Error 1 背景2 现象3 更换风扇3 1 准备工具3 2 开始拆机 1 背景 家里的老笔记本电脑 xff0c thinkpad X201i笔记本电脑 xff0c 一直在使用 xff0c
  • Linux操作系统安装MySQL(rpm安装)

    Linux操作系统安装MySQL xff08 rpm安装 xff09 1 背景2 环境说明3 准备工作3 1 端口查看3 2 检查安装3 3 创建MySQL用户和组 4 MySQL安装4 1 下载MySQL4 2 解压安装包4 3 安装My
  • MySQL配置数据库审计

    MySQL配置数据库审计 1 背景2 环境3 准备工作4 安装审计4 1 解压审计包4 2 查看数据库插件目录4 3 安装数据库审计插件4 3 1 复制到插件目录4 3 2 修改插件权限4 3 3 设置审计参数4 3 4 修改数据库审计配置
  • [漏洞修复]Docker runc容器逃逸漏洞(CVE-2021-30465)

    漏洞修复 Docker runc容器逃逸漏洞CVE 2021 30465 1 背景2 漏洞描述3 影响版本4 安全版本5 修复建议6 升级影响7 修复步骤 1 背景 2021年5月31日 xff0c 阿里云应急响应中心监测到国外安全研究人员
  • linux系统挂载硬盘

    linux系统挂载硬盘 1 背景2 环境3 准备工作4 挂载分区4 1 查看分区信息4 2 创建分区4 3 设置分区格式4 4 创建挂载目录4 5 挂载分区4 6 设置开机自动挂载4 7 验证是否挂载成功 1 背景 日常使用过程中随着系统业
  • ACFLY接口定义

    E的接口在原理图中可以找到 xff0c 看上去像是I2C的接口 xff0c 其实是SPI xff0c 因为ACFLY采购的屏它就是这么标接口的 不过我想把这个SPI接口让给LORA无线通信模块 xff0c 拓展一下无线功能 ACFLY板子是
  • FreeRTOS之Stream Buffers(流缓冲区)

    ACFly用到了Steam Buffers xff0c 特地调了3个最常见的API查了一下 xff0c 其他的API都和这些差不多 Steam Buffers 是最近几版本Freertos出现的数据结构 xStreamBufferCreat