FreeRTOS队列详解(上)

本文详细解析FreeRTOS中的队列机制,包括队列的基本特点如FIFO/LIFO操作、数据传递方式,以及队列的创建过程,重点介绍了xQueueGenericCreate()函数和初始化函数prvInitialiseNewQueue()的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:
本文分析一下FreeRTOS队列相关知识,队列可以存储有限个数、大小固定的数据,用于任务与任务之间、任务与中断之间传消息,也称消息队列。FreeRTOS中信号量也是由队列实现的。所以熟悉队列是非常有必要的。本文分5部分讲解队列:队列简介、队列创建、队列上锁和解锁、给队列发消息、从队列读消息。

一、队列简介

1.1 FreeRTOS队列基本特点

  1. 数据入队出队方式:队列通常采用“先进先出”(FIFO)的数据存储缓冲机制,即先入队的数据会先从队 列中被读取,FreeRTOS中也可以配置为“后进先出”LIFO方式;
  2. 数据传递方式:FreeRTOS中队列采用值传递,即将数据拷贝到队列中进行传递。有的RTOS只能传递指针而不是拷贝原始数据传递,按指针传递效率较高,但是不能传递局部变量(局部变量可能被修改或者被删除)。FreeRTOS采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递,传递局部变量的时候采用拷贝数据传递;
  3. 队列消息存储区大小是变长的,队列结构体中使用一个指针指向队列存储区首地址,根据创建队列时传入的队列长度以及队列项数据大小两个参数,计算队列消息存储区实际所需的内存大小;
  4. 多任务访问:队列不属于某个任务,任何任务都可以向队列发送消息 以及 读取消息;
  5. 出队、入队阻塞:当任务向一个队列发送消息时,可以指定一个阻塞时间,此时当队列已满无法入队,若阻塞时间为0:直接返回不会等待;若阻塞时间为0~port_MAX_DELAY:等待设定的阻塞时间,若在该时间内还无法入队,超时后直接返回不再等待;阻塞时间为port_MAX_DELAY:死等,一直等到可以入队为止。出队阻塞与入队阻塞类似;
  6. 中断服务函数与任务函数API单独分开,使用更简单。

1.2 队列结构体

队列结构体用于描述队列,里面包括了队列的全部属性,后续会讲解,相关注释如下:
typedef struct QueuePointers
{
   
   
	int8_t *pcTail;					/*< 用作队列时,指向队列存储区最后一个字节 */
	int8_t *pcReadFrom;				/*< 用作队列时,指向最后一个出队的队列项的首地址 */
} QueuePointers_t;

typedef struct SemaphoreData
{
   
   
	TaskHandle_t xMutexHolder;		 /*< 用作信号量时,表示持有互斥量任务的句柄*/
	UBaseType_t uxRecursiveCallCount;/*< 用作信号量时,记录递归互斥量被调用的次数 */
} SemaphoreData_t;

typedef struct QueueDefinition 		
{
   
   
	int8_t *pcHead;					/*< 指向队列存消息储区的开始位置 */
	int8_t *pcWriteTo;				/*< 指向队列存储区域下一个空闲的位置*/

	union
	{
   
   
		QueuePointers_t xQueue;		/*< 当队列用来传递数据进行通信 */
		SemaphoreData_t xSemaphore; /*< 当队列用作信号量*/
	} u;

	List_t xTasksWaitingToSend;		/*<等待发送列表,队列满导致发送消息失败而进入阻塞态的任务按任务优先级排序挂接到该列表 */
	List_t xTasksWaitingToReceive;	/*<等待接收列表,队列空导致读取消息失败而进入阻塞态的任务按优先级排序挂接到该列表*/

	volatile UBaseType_t uxMessagesWaiting;/*< 当前队列中消息数目 */
	UBaseType_t uxLength;			/*< 队列存储队列项(消息)的最大数目*/
	UBaseType_t uxItemSize;			/*< 队列中每个队列项的数据大小,单位字节 */

	volatile int8_t cRxLock;		/*< 存储队列被锁定时从队列接收(从队列中删除)的项目数,队列未锁定时设置为queueUNLOCKED*/
	volatile int8_t cTxLock;		/*<存储队列被锁定时向队列发送(添加到队列)的项目数,队列未锁定时设置为queueUNLOCKED*/

	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
		uint8_t ucStaticallyAllocated;	/*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */
	#endif

	#if ( configUSE_QUEUE_SETS == 1 )
		struct QueueDefinition *pxQueueSetContainer
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值