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代理设计的新一代开发工…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
