14.FreeRTOS 流媒体缓存 Stream Buffer
FreeRTOS 中的 Stream Buffer(流媒体缓存)
在实时操作系统(RTOS)中,处理流媒体数据是一项非常关键的任务。FreeRTOS 提供了一种名为 Stream Buffer(流媒体缓存)的机制,用于高效地管理和传输流式数据,如音频、视频等。
什么是 Stream Buffer?
Stream Buffer 是 FreeRTOS 提供的一种数据结构,专门用于在任务之间传递和处理流式数据。与队列不同,Stream Buffer 适用于大数据块的流式传输,而不是单个数据项的传输。这使得它非常适合用于音频、视频和其他连续数据流的场景。
Stream Buffer 的工作原理
Stream Buffer 的基本操作包括创建、发送和接收数据。它通过一个环形缓冲区来存储数据,使得数据可以连续地写入和读取。以下是其主要操作:
- 创建 Stream Buffer:使用
xStreamBufferCreate函数创建一个新的 Stream Buffer。 - 发送数据到 Stream Buffer:任务使用
xStreamBufferSend将数据发送到缓冲区。 - 从 Stream Buffer 接收数据:任务使用
xStreamBufferReceive从缓冲区接收数据。
流媒体传输任务处理的示例
下面是一个示例,展示了如何使用 Stream Buffer 实现流水线式任务处理:
#include <Arduino.h>
#include <FreeRTOS.h>
#include <stream_buffer.h>#define BUFFER_SIZE 1024
#define TRIGGER_LEVEL 1StreamBufferHandle_t xStreamBuffer;// Task1: 发送数据到 Stream Buffer
void Task1(void *pvParameters) {const char *data = "Task 1 data";for (;;) {// 模拟 Task1 的工作delay(1000);Serial.println("Task 1 is sending data");xStreamBufferSend(xStreamBuffer, data, strlen(data), portMAX_DELAY);}
}// Task2: 从 Stream Buffer 接收数据并处理
void Task2(void *pvParameters) {char buffer[50];for (;;) {// 从 Stream Buffer 接收数据size_t bytesReceived = xStreamBufferReceive(xStreamBuffer, buffer, sizeof(buffer), portMAX_DELAY);if (bytesReceived > 0) {buffer[bytesReceived] = '\0'; // 确保字符串以 NULL 结尾Serial.print("Task 2 received data: ");Serial.println(buffer);// 模拟 Task2 的工作delay(1000);}}
}void setup() {Serial.begin(115200);// 创建 Stream BufferxStreamBuffer = xStreamBufferCreate(BUFFER_SIZE, TRIGGER_LEVEL);if (xStreamBuffer == NULL) {// 创建失败,处理错误while (1);}// 创建任务xTaskCreate(Task1, "Task 1", 10000, NULL, 1, NULL);xTaskCreate(Task2, "Task 2", 10000, NULL, 1, NULL);// 启动任务调度器vTaskStartScheduler();
}void loop() {// loop 函数为空,不需要额外的代码
}
API
使用 Stream Buffer 的步骤
1. 创建 Stream Buffer
要创建一个 Stream Buffer,使用 xStreamBufferCreate 函数:
StreamBufferHandle_t xStreamBufferCreate(size_t xBufferSizeBytes, size_t xTriggerLevelBytes);
参数:
xBufferSizeBytes:缓冲区的大小(字节数)。xTriggerLevelBytes:触发接收任务的最小字节数。
返回值:
- 成功时返回 Stream Buffer 的句柄(非 NULL);失败时返回 NULL。
示例:
StreamBufferHandle_t xStreamBuffer = xStreamBufferCreate(1024, 1);
if (xStreamBuffer == NULL) {// 创建失败,处理错误
}
2. 发送数据到 Stream Buffer
使用 xStreamBufferSend 将数据发送到缓冲区:
size_t xStreamBufferSend(StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait);
参数:
xStreamBuffer:Stream Buffer 的句柄。pvTxData:要发送的数据指针。xDataLengthBytes:发送的数据长度(字节数)。xTicksToWait:等待时间(滴答数)。
返回值:
- 成功发送的数据字节数。如果返回值小于
xDataLengthBytes,则表示在xTicksToWait时间内没有足够的空间发送所有数据。
示例:
const char *data = "Hello, FreeRTOS!";
size_t bytesSent = xStreamBufferSend(xStreamBuffer, data, strlen(data), portMAX_DELAY);
if (bytesSent < strlen(data)) {// 发送的数据不完整,处理错误
}
3. 从 Stream Buffer 接收数据
使用 xStreamBufferReceive 从缓冲区接收数据:
size_t xStreamBufferReceive(StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait);
参数:
xStreamBuffer:Stream Buffer 的句柄。pvRxData:接收数据的缓冲区指针。xBufferLengthBytes:接收缓冲区的大小(字节数)。xTicksToWait:等待时间(滴答数)。
返回值:
- 成功接收的数据字节数。如果返回值小于
xBufferLengthBytes,则表示在xTicksToWait时间内没有接收到足够的数据。
示例:
char buffer[50];
size_t bytesReceived = xStreamBufferReceive(xStreamBuffer, buffer, sizeof(buffer), portMAX_DELAY);
if (bytesReceived > 0) {buffer[bytesReceived] = '\0'; // 确保字符串以 NULL 结尾Serial.println(buffer);
} else {// 接收失败,处理错误
}
其他 Stream Buffer API
1. xStreamBufferCreateStatic
创建一个静态分配的 Stream Buffer。
StreamBufferHandle_t xStreamBufferCreateStatic(size_t xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t *pucStreamBufferStorageArea, StaticStreamBuffer_t *pxStaticStreamBuffer);
参数:
xBufferSizeBytes:缓冲区的大小(字节数)。xTriggerLevelBytes:触发接收任务的最小字节数。pucStreamBufferStorageArea:指向预先分配的缓冲区存储区。pxStaticStreamBuffer:指向预先分配的StaticStreamBuffer_t结构。
返回值:
- 成功时返回 Stream Buffer 的句柄(非 NULL);失败时返回 NULL。
2. xStreamBufferReset
重置 Stream Buffer,使其变为空。
BaseType_t xStreamBufferReset(StreamBufferHandle_t xStreamBuffer);
参数:
xStreamBuffer:Stream Buffer 的句柄。
返回值:
- 如果成功重置 Stream Buffer,则返回 pdPASS;如果在 Stream Buffer 上有任务阻塞,则返回 pdFAIL。
示例:
if (xStreamBufferReset(xStreamBuffer) == pdPASS) {// 重置成功
} else {// 重置失败,处理错误
}
3. xStreamBufferSpacesAvailable
获取 Stream Buffer 中可用的空闲空间(字节数)。
size_t xStreamBufferSpacesAvailable(StreamBufferHandle_t xStreamBuffer);
参数:
xStreamBuffer:Stream Buffer 的句柄。
返回值:
- Stream Buffer 中当前可用的空闲空间,以字节为单位。
示例:
size_t spaceAvailable = xStreamBufferSpacesAvailable(xStreamBuffer);
Serial.print("Space available: ");
Serial.println(spaceAvailable);
4. xStreamBufferBytesAvailable
获取 Stream Buffer 中可读取的字节数。
size_t xStreamBufferBytesAvailable(StreamBufferHandle_t xStreamBuffer);
参数:
xStreamBuffer:Stream Buffer 的句柄。
返回值:
- Stream Buffer 中当前可读取的字节数。
示例:
size_t bytesAvailable = xStreamBufferBytesAvailable(xStreamBuffer);
Serial.print("Bytes available: ");
Serial.println(bytesAvailable);
5. xStreamBufferSetTriggerLevel
设置触发接收任务的最小字节数。
BaseType_t xStreamBufferSetTriggerLevel(StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel);
参数:
xStreamBuffer:Stream Buffer 的句柄。xTriggerLevel:触发级别(字节数)。
返回值:
- 如果成功设置触发级别,则返回 pdPASS;如果提供的
xTriggerLevel超过缓冲区大小,则返回 pdFAIL。
示例:
if (xStreamBufferSetTriggerLevel(xStreamBuffer, 10) == pdPASS) {// 设置成功
} else {// 设置失败,处理错误
}
6. vStreamBufferDelete
删除 Stream Buffer,释放分配的内存。
void vStreamBufferDelete(StreamBufferHandle_t xStreamBuffer);
参数:
xStreamBuffer:Stream Buffer 的句柄。
返回值:
- 无返回值。
示例:
vStreamBufferDelete(xStreamBuffer);
结论
FreeRTOS 的 Stream Buffer 提供了一种高效的机制来处理和传输流媒体数据。通过合理使用 Stream Buffer,可以在嵌入式系统中实现稳定可靠的流媒体数据处理。在实际应用中,我们应根据具体需求调整缓冲区大小和触发级别,并优化数据处理流程,以实现最佳性能。
相关文章:
14.FreeRTOS 流媒体缓存 Stream Buffer
FreeRTOS 中的 Stream Buffer(流媒体缓存) 在实时操作系统(RTOS)中,处理流媒体数据是一项非常关键的任务。FreeRTOS 提供了一种名为 Stream Buffer(流媒体缓存)的机制,用于高效地管…...
利用ffmpeg把视频分解成图片(每秒x张图)再图片合成视频
1. 视频分解成图片 ffmpeg -i rawVideo.mp4 -r 5 -f image2 img/%04d.png-i rawVideo.mp4 输入文件 -r 5 每秒5帧(1秒5张图) 可不写,默认每秒24帧 -f image2 表示输出的格式图像 可不写,默认图像 img/ 图片放在img文件夹下 %04d.png 图片的命名…...
冯喜运:6.7今日外汇黄金原油走势分析及日内操作策略
【黄金消息面分析】:美国初请失业金人数超预期,市场对美联储9月降息预期升温,全球降息潮起,黄金市场受支撑。北京时间本周四,美国劳工部公布的数据显示,截至6月1日当周初请失业金人数增加至22.9万人&#x…...
[网络基础]——计算机网络(OSI)参考模型 详解
🏡作者主页:点击! 🌐网络通信基础TCP/IP专栏:点击! ⏰️创作时间:2024年6月2日21点59分 🀄️文章质量:93分 目录 🎟️OSI基本概念 🎄分层架构…...
使用 Java 获取图片的 MD5 编码
在许多应用场景中,我们需要验证文件的完整性或唯一性,常用的方法是计算文件的哈希值。MD5(Message Digest Algorithm 5)是一种广泛使用的哈希函数,可以生成一个128位的哈希值(32位的十六进制数字࿰…...
GO——泛型
泛型 对于强类型语言,在编写代码时不事先指定类型,在实例化的时候作为参数指明类型 参考:https://www.liwenzhou.com/posts/Go/generics/ 什么时候使用泛型? 方法中的代码实现与类型T无关参考:https://juejin.cn/p…...
TSP(Python):Qlearning求解旅行商问题TSP(提供Python代码)
一、Qlearning简介 Q-learning是一种强化学习算法,用于解决基于奖励的决策问题。它是一种无模型的学习方法,通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策,该函数表示在给定状态下采取某个动作所获…...
【精通NIO】NIO介绍
一、什么是NIO NIO,全称为New Input/Output,是Java平台中用于替代传统I/O(Blocking I/O)模型的一个功能强大的I/O API。NIO在Java 1.4版本中被引入,其设计目标是提供一种非阻塞的、低延迟的I/O操作方式,以…...
ssh远程管理
一、Openssh概述 Openssh是一种安全通道协议,用来实现字符界面的远程登录、远程复制、远程文本传输。 Openssh对通信双方的数据进行了加密。有两种方式: 用户名和密码登录:比较常用密钥对认证方式:可以实现免密登录 ssh端口&a…...
【ai】pycharm远程ssh开发
方式1: gateway的方式是远程放一个pycharm 专业版,经常下载失败 方式2: 类似vs,源码本地,同步到远程进行运行。 参考大神的分享: Pycharm远程连接服务器(2023-11-9) Pycharm远程连接服务器(windows下远程修改服务器代码)[通俗易懂] cpolar 建议同时内网穿透 选 远程开…...
leetcode 9 回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而…...
学习Python的基础知识
目录 摘要 Python 的主要特点 基本语法 1. 变量和数据类型: 2. 条件语句: 3. 循环: 4. 函数: 5. 类和对象: 6. 列表和字典: 7. 文件I/O: Python 的学习路线 如何高效使用 Python 的…...
第五届上海市青少年算法竞赛网络同步赛(小学组)
第五届上海市青少年算法竞赛网络同步赛(小学组)T1. 符号译码_网络同步赛 内存限制: 256 Mb 时间限制: 1000 ms 题目描述 小爱为标点符号设计了一套编码系统,编码规则如下: [ 的编码为 010 ] 的编码为 101 < 的编码为 00 > 编码为 11 + 的编码为 011 - 编码为 100 根…...
【区分vue2和vue3下的element UI Cascader 级联选择器组件,分别详细介绍属性,事件,方法如何使用,并举例】
在Vue 2的Element UI和Vue 3的Element Plus中,el-cascader(级联选择器)组件用于从嵌套的数据中进行选择。以下是对这两个版本下el-cascader组件的属性、事件和方法的详细介绍,并附带示例。 Vue 2的Element UI el-cascader 属性…...
pottery,一个超酷的 Python 库!
更多Python学习内容:ipengtao.com 大家好,今天为大家分享一个超酷的 Python 库 - pottery。 Github地址:https://github.com/brainix/pottery 在分布式系统和高并发环境中,Redis 作为一种高性能的键值存储数据库,被广泛…...
【Android面试八股文】在Java中重载和重写是什么意思,区别是什么?
文章目录 在Java中重载和重写是什么意思,区别是什么?这道题想考察什么 ?考察的知识点考生应该如何回答重载(Overloading)重写(Overriding)重载和重写的区别在Java中重载和重写是什么意思,区别是什么? 这道题想考察什么 ? Java基础 考察的知识点 面向对象多态的基…...
【第二篇】SpringSecurity源码详解
一、SpringSecurity中的核心组件 在SpringSecurity中的jar分为4个,作用分别为 jar作用spring-security-coreSpringSecurity的核心jar包,认证和授权的核心代码都在这里面spring-security-config如果使用Spring Security XML名称空间进行配置或Spring Security的Java configura…...
基于Python+FFMPEG环境下载B站歌曲
题主环境 WSL on Windows10 命令如下 # python3.9 pip install --pre yutto yutto --batch https://www.bilibili.com/video/BV168411o7Bh --audio-only ls | grep aac | xargs -I {} ffmpeg -i {} -acodec libmp3lame {}.mp3WinAmp...
静态 VxLAN 浅析及配置示例(头端复制)
一、概念: VxLAN:Visual eXtensible Local Area Network 虚拟扩展本地局域网,一种隧道技术,能在三层网络的基础上建立二层以太网网络隧道,从而实现跨地域的二层互连,VxLAN端口:4789EVPN&#x…...
2023年与2024年AI代理基础设施的演进:六大关键变化
随着人工智能技术的不断进步,AI代理基础设施在2023年和2024年之间经历了显著的发展和变革。本文将探讨这两年间AI代理基础设施的六大关键变化,展示如何为开发者和用户提供更加强大和集成化的解决方案。 1. 代理特定开发工具的兴起 2024年见证了专为AI代理设计的新一代开发工…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
