学习一下freertos streambuffer

2023-05-16

学习一下freertos stream buffer

最近在自己从0到1写rtos,主要是为了学习rtos,并没有其他卵用,光学会调API是不够的,看源码又恼火,所以学习的最好办法还是根据自己的理解自己动手撸代码,虽然大部分思路都是抄的freertos或者rt thread(主要是抄思路,代码还是自己按理解写的),抄完调通的时候rtos也就基本掌握了。

  • 废话不多说,直接分析代码吧,先从StreamBuffer_t这个控制块或者说handle
    说起。
typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */
{
	volatile size_t xTail;				/* 相当于队列尾部,从这取数据. */
	volatile size_t xHead;				/* 队列头,从这个地址存数据. */
	size_t xLength;						/* The length of the buffer pointed to by pucBuffer. */
	size_t xTriggerLevelBytes;			/* 存多少个bytes数据后通知消费者来取. */
	volatile TaskHandle_t xTaskWaitingToReceive; /* 因为接收失败而挂起的任务,由于是一对一的方式,所以不需要链表 */
	volatile TaskHandle_t xTaskWaitingToSend;	/*同上 */
	uint8_t *pucBuffer;					/* 存放数据的内存*/
	uint8_t ucFlags;
} StreamBuffer_t;
  • 接下来就是喜闻乐见的分析xStreamBufferGenericCreateStatic这个函数了,因为我通常用静态内存分配,所以是这个函数。
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
														   size_t xTriggerLevelBytes,
														   BaseType_t xIsMessageBuffer,
														   uint8_t * const pucStreamBufferStorageArea,
														   StaticStreamBuffer_t * const pxStaticStreamBuffer )
	{
	StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
	StreamBufferHandle_t xReturn;
	uint8_t ucFlags;
  • StaticStreamBuffer_t StreamBuffer_t 其实是一样的(自己跳转看定义),StreamBufferHandle_t是上面两个的指针,不知道freertos搞这么多定义干什么,跳来跳去,一点也不干净。
if( xTriggerLevelBytes == ( size_t ) 0 )
		{
			xTriggerLevelBytes = ( size_t ) 1;
		}

		if( xIsMessageBuffer != pdFALSE )
		{
			/* Statically allocated message buffer. */
			ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
		}
		else
		{
			/* Statically allocated stream buffer. */
			ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED;
		}
  • 其实这里还可以搞成message buffer,根据传入的参数xIsMessageBuffer不同而复用。
configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
  • 如果是message buffer,每条消息大小不能小于4bytes。
if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
		{
			prvInitialiseNewStreamBuffer( pxStreamBuffer,
										  pucStreamBufferStorageArea,
										  xBufferSizeBytes,
										  xTriggerLevelBytes,
										  ucFlags );

			/* Remember this was statically allocated in case it is ever deleted
			again. */
			pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;

			traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );

			xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
		}
		else
		{
			xReturn = NULL;
			traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
		}

		return xReturn;
	}
  • 实际上是调用prvInitialiseNewStreamBuffer进行真正的stream buffer(message buf)初始化。
static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
										  uint8_t * const pucBuffer,
										  size_t xBufferSizeBytes,
										  size_t xTriggerLevelBytes,
										  uint8_t ucFlags )
{
	/* Assert here is deliberately writing to the entire buffer to ensure it can
	be written to without generating exceptions, and is setting the buffer to a
	known value to assist in development/debugging. */
	#if( configASSERT_DEFINED == 1 )
	{
		/* The value written just has to be identifiable when looking at the
		memory.  Don't use 0xA5 as that is the stack fill value and could
		result in confusion as to what is actually being observed. */
		const BaseType_t xWriteValue = 0x55;
		configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
	} /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */
	#endif

	( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
	pxStreamBuffer->pucBuffer = pucBuffer;
	pxStreamBuffer->xLength = xBufferSizeBytes;
	pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
	pxStreamBuffer->ucFlags = ucFlags;
}
  • 就是给结构体赋值,注意一下pucBuffer是正真存储数据的内存,应该是个uint8_t 或者void *指针。
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
BaseType_t xReturn = pdFAIL;

#if( configUSE_TRACE_FACILITY == 1 )
	UBaseType_t uxStreamBufferNumber;
#endif

	configASSERT( pxStreamBuffer );

	#if( configUSE_TRACE_FACILITY == 1 )
	{
		/* Store the stream buffer number so it can be restored after the
		reset. */
		uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
	}
	#endif

	/* Can only reset a message buffer if there are no tasks blocked on it. */
	taskENTER_CRITICAL();
	{
		if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
		{
			if( pxStreamBuffer->xTaskWaitingToSend == NULL )
			{
				prvInitialiseNewStreamBuffer( pxStreamBuffer,
											  pxStreamBuffer->pucBuffer,
											  pxStreamBuffer->xLength,
											  pxStreamBuffer->xTriggerLevelBytes,
											  pxStreamBuffer->ucFlags );
				xReturn = pdPASS;

				#if( configUSE_TRACE_FACILITY == 1 )
				{
					pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
				}
				#endif

				traceSTREAM_BUFFER_RESET( xStreamBuffer );
			}
		}
	}
	taskEXIT_CRITICAL();

	return xReturn;
}
  • 重置stream buf, 仅当没有发送和接收任务阻塞在这个stream buf上时。
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
BaseType_t xReturn;

	configASSERT( pxStreamBuffer );

	/* It is not valid for the trigger level to be 0. */
	if( xTriggerLevel == ( size_t ) 0 )
	{
		xTriggerLevel = ( size_t ) 1;
	}

	/* The trigger level is the number of bytes that must be in the stream
	buffer before a task that is waiting for data is unblocked. */
	if( xTriggerLevel <= pxStreamBuffer->xLength )
	{
		pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
		xReturn = pdPASS;
	}
	else
	{
		xReturn = pdFALSE;
	}

	return xReturn;
}
  • 通过这里分析pxStreamBuffer->xLength应该是这个stream buf能存下的最大bytes数,xTriggerLevel就是说当达到多少个bytes后去通知挂起的任务(stream buffer都是用的通知的形式,所以基本上是用于一对一的任务同步用)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习一下freertos streambuffer 的相关文章

  • IPv4地址、IPv6地址和Mac地址的位数

    xff08 1 xff09 IPv4的地址是32位 xff0c 用点分十进制表示 xff0c 每八位划分 xff0c 也就是四个0 255的十进制数 xff0c 这是很常见的 xff08 2 xff09 IPv6的地址是128位 xff0c
  • 用C#连接数据库的方法

    连接SQL Server数据库的方法 xff1a 1 在程序中引用System Data SqlClient命名空间 2 编写连接字符串 xff0c 格式为 xff1a Data Source 61 服务器名称 Initial Catalo
  • gcc 不支持 //注释的解决

    这段时间用slickedit写代码 xff08 windows平台下 xff0c 装了Cygwin xff09 xff0c 编译器用的gcc xff0c 但是有个问题就是用 34 34 写注释的时候 xff0c 编译的时候有错 xff1a
  • python实现按照文件名称进行文件分类

    问题 xff1a 大量名称中带有数字的图片 视频 xff0c 根据名称中数字按照一定的等差数列来排序 xff0c 并且放入指定对应的文件夹中 span class token keyword import span os span clas
  • 【深度学习】Yolov3详解笔记及Pytorch代码

    Yolov3详解笔记及Pytorch代码 预测部分网络结构backbone xff1a Darknet 53output预测结果的解码 训练部分计算loss所需参数pred是什么target是什么loss的计算过程 预测部分 网络结构 DB
  • 【深度学习】各种卷积的理解笔记(2D,3D,1x1,可分离卷积)

    卷积 1 2D卷积单通道版本多通道版本 2 3D卷积3 1x1卷积作用应用 4 卷积算法5 可分离卷积空间可分离卷积深度可分离卷积 1 2D卷积 卷积的目的是从输入中提取有用的特征 在图像处理中 xff0c 卷积可以选择多种不同的滤波器 每
  • 【深度学习】(2+1)D模型框架结构笔记

    xff08 2 43 1 xff09 D 模型框架结构笔记 SpatioTemporalConv模块结构SpatioTemporalResBlock模块结构SpatioTemporalResLayer模块结构2Plus1DNet Spati
  • 【机器学习】LR回归(逻辑回归)和softmax回归

    LR回归 xff08 逻辑回归 xff09 和softmax回归 1 LR回归Logistic回归的函数形式Logistic回归的损失函数Logistic回归的梯度下降法Logistic回归防止过拟合Multinomial Logistic
  • 【深度学习】时间注意力模块与空间注意力模块

    注意力模块 通道 xff08 时间 xff09 注意力模块空间注意力模块 通道 xff08 时间 xff09 注意力模块 为了汇总空间特征 xff0c 作者采用了全局平均池化和最大池化两种方式来分别利用不同的信息 输入是一个 H W C 的
  • 【机器学习】机器学习与统计分布的关系

    这里写目录标题 1 常见的统计学分布1 xff09 离散分布a 伯努利分布b 二项分布c 泊松分布 2 xff09 连续分布a 正态分布 xff08 高斯分布 xff09 b 均匀分布 为什么我们喜欢用 sigmoid 这类 S 型非线性变
  • AKKA入门

    1 Guardian java package com example demo import akka actor typed javadsl ActorContext import akka actor typed ActorRef i
  • 【深度学习】深入理解Batch Normalization批标准化

    Batch Normalization 1 Internal Covariate Shift 问题2 BatchNorm的本质思想1 xff09 函数图像说明2 xff09 算法3 xff09 引入参数恢复表达能力4 xff09 公式 3
  • Autolabelimg自动标注工具

    目录 前言 一 工具原理和功能 1 原理 2 功能列表 二 实战 1 下载与安装 2 配置环境 3 开始使用 4 导入模型 5 选择标注类别 6 进行自动标注 三 总结 前言 在做机器视觉有监督方面 通常会面对很多数据集 xff0c 然后去
  • anchor base,anchor free和基于分割的图像检测

    目录 1 anchor base 2 anchor free 3 基于分割 reference 1 anchor base 什么是anchor based的目标检测方法呢 如果要让你定一个规则去一个图片上框一个物体 xff0c 你会怎么做呢
  • 我的2013:从北京到石家庄的软件开发历程

    记得是正月初八那天早上离开了老家 xff0c 坐上了开往北京的大巴车去北京准备新 的一年的奋斗 xff0c 车票120元了 涨价了20 xff0c 而且还没有地方报销去了 gt lt 因为年底的时候已经离职了 考虑到各公司部门人员 xff0
  • [机器学习] ML重要概念:梯度(Gradient)与梯度下降法(Gradient Descent)

    引言 机器学习栏目记录我在学习Machine Learning过程的一些心得笔记 xff0c 涵盖线性回归 逻辑回归 Softmax回归 神经网络和SVM等等 xff0c 主要学习资料来自网上的免费课程和一些经典书籍 xff0c 免费课程例
  • TPMS胎压芯片选择:英飞凌SP370、英飞凌SP40、飞思卡尔FXTH87

    简介TPMS Tire Pressure Monitoring System xff08 TPMS xff09 xff0c 轮胎压力监测系统 xff0c TPMS的作用是在汽车行驶过程中对轮胎气压进行实时自动监测 xff0c 并对轮胎漏气和
  • 2014年计算机求职总结--准备篇

    版权所有 xff0c 转载请注明出处 xff0c 谢谢 xff01 http blog csdn net walkinginthewind article details 13000431 找工作是一个长期准备的过程 xff0c 突击是没什
  • Code::Blocks之设置字体

    设置 S gt 编辑器 D gt 常规设置 gt 编辑器设置 xff1b 在 34 字体 34 中选择 34 选择 34 按钮 xff0c 进行字体 字形 大小的选择 xff1b 确定
  • 嵌入式软件面试问题总结

    1 DCS 答 xff1a DCS一般指分散控制系统 分散控制系统是以微处理器为基础 xff0c 采用控制功能分散 显示操作集中 兼顾分而自治和综合协调的设计原则的新一代仪表控制系统 集散控制系统简称DCS 也可直译为 分散控制系统 或 分

随机推荐