四、FreeRTOS学习之 队列

本文详细介绍了FreeRTOS中的队列操作,包括队列的创建(动态与静态)、删除、数据的写入(尾部、头部与覆盖写入)以及读取。队列作为一种任务通信机制,采用FIFO方式,提供了多种在不同场景下使用的函数。文章还给出了实际示例,演示了如何创建队列以及在两个任务间进行数据传递。
摘要由CSDN通过智能技术生成

目录

1、定义

 2、函数介绍

1、队列创建

2、队列删除

3、写队列

4、读队列

3、实例


1、定义

队列是freertos所有任务通信或同步之外的机制,队列包含多个数据称为长度,每个数据大小相同,创建队列时需要用到长度和数据大小。数据的读写方法采用先进先出的方式(FIFO),一般使用时,写数据,数据放到尾部;读数据,从队列头部开始读。

 2、函数介绍

1、队列创建

队伍创建分为:动态创建和静态创建,区别在于创建时内存分配情况。

动态创建函数:队伍内存动态分配(任务动态创建时使能的宏相同,具体上一篇文章)

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, //队列长度
                           
                             UBaseType_t uxItemSize //数据大小
                           )
//返回值:成功,返回队列句柄;失败,返回NULL

静态创建函数:队伍内存需要事先分配好。

QueueHandle_t xQueueCreateStatic(
                           UBaseType_t uxQueueLength,      //队列长度
                           UBaseType_t uxItemSize,         //数据大小
                           uint8_t *pucQueueStorageBuffer, //uxItemSize非零,数组大小至少为长度乘以数据大小
                                                           //uxItemSize为零,数组为NULL
                           StaticQueue_t *pxQueueBuffer    //该变量用于保存队列的数据结构。
                       )
//返回值:成功,返回队列句柄;失败,返回 0

2、队列删除

函数:

void vQueueDelete( QueueHandle_t xQueue );

/*
    功能:删除先前通过调用xQueueCreate()或xQueueCreateStatic()创建的队列。vQueueDelete()也可用   
         于删除信号量
    参数:句柄
*/

3、写队列


//往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait,两个函数等价

BaseType_t xQueueSend(
                           QueueHandle_t    xQueue,       //目标队列句柄
                           const void      *pvItemToQueue,//写入数据的地址
                           TickType_t       xTicksToWait  //阻塞时间
                     )


BaseType_t xQueueSendToBack(
                                QueueHandle_t    xQueue,
                                const void      *pvItemToQueue,
                                TickType_t       xTicksToWait
                            )

 
//往队列头部写入数据,如果没有空间,阻塞时间为xTicksToWait

BaseType_t xQueueSendToFront(
                                QueueHandle_t    xQueue,
                                const void       *pvItemToQueue,
                                TickType_t       xTicksToWait
                            )

//返回值:返回PDPASS,数据成功发送到队列;返回errQUEUE_FULL,队列已满无法将数据写入

/********************************************************************************/

//xQueueSendToBack()的一个版本,即使队列已满,它也会写入队列,覆盖队列中已经保存的数据
//xQueueOverwrite()用于长度为1的队列,这意味着队列要么为空,要么为满。

BaseType_t xQueueOverwrite(
                               QueueHandle_t xQueue,//目标队列句柄
                               const void * pvItemToQueue//写入数据的地址
                          )

//返回值:pdPASS是唯一可以返回的值,因为即使队列已经满了



/***********************************************************************************/
 *                                中断函数写入数据
/***********************************************************************************/


//往队列尾部写入数据,此函数可以在中断函数中使用,不可阻塞
BaseType_t xQueueSendToBackFromISR(
                                      QueueHandle_t xQueue,//目标队列句柄
                                      const void *pvItemToQueue,//写入数据的地址
                                      BaseType_t *pxHigherPriorityTaskWoken
                                      //                      
                                   )


 
//往队列头部写入数据,此函数可以在中断函数中使用,不可阻塞
BaseType_t xQueueSendToFrontFromISR(
                                      QueueHandle_t xQueue,
                                      const void *pvItemToQueue,
                                      BaseType_t *pxHigherPriorityTaskWoken
                                   )
//返回值:返回PDTRUE,数据成功发送到队列;errQUEUE_FULL无法将数据发送到队列,队列已满。




//即使队列已满,也会写入队列,覆盖队列中已经保存的数据。
//xQueueOverwriteFromISR()用于长度为1的队列,这意味着队列要么为空,要么为满。

BaseType_t xQueueOverwriteFromISR(
                                       QueueHandle_t xQueue,
                                       const void * pvItemToQueue,
                                       BaseType_t *pxHigherPriorityTaskWoken
                                  )

//返回值:pdPASS是唯一可以返回的值,覆盖写入队列,即使队列已满。

4、读队列

BaseType_t xQueueReceive( 
                            QueueHandle_t xQueue,//目标队列句柄
                            void * const pvBuffer,//接收数据存储的指针
                            TickType_t xTicksToWait 
                            //阻塞时间,如果被设为portMAX_DELAY,则会一直阻塞直到有数据可写
                        )
//返回值:返回pdPASS,成功地从队列读取数据;返回errQUEUE_EMPTY,由于队列为空无法从队列读取数据



//从队列中读取数据,但不从队列中移除数据。

BaseType_t xQueuePeek(
                          QueueHandle_t xQueue,
                          void * const pvBuffer,
                          TickType_t xTicksToWait
                      )
//返回值:返回pdPASS,成功地从队列读取数据;返回errQUEUE_EMPTY,由于队列为空无法从队列读取数据




BaseType_t xQueuePeekFromISR(
                                 QueueHandle_t xQueue,
                                 void *pvBuffer,
                             )
//返回值:返回pdPASS,成功地从队列读取数据;返回errQUEUE_EMPTY,由于队列为空无法从队列读取数据



BaseType_t xQueueReceiveFromISR(
                                    QueueHandle_t xQueue,
                                    void       *pvBuffer,
                                    BaseType_t *pxTaskWoken
                                )
//返回值:返回pdPASS,成功地从队列读取数据;返回pdFAIL,由于队列为空而无法从队列读取数据

3、实例

/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
 
QueueHandle_t xQueue;//设置队列句柄
 
TaskHandle_t xHandleTask1 = NULL;//任务句柄,用于删除

TaskHandle_t xHandleTask2 = NULL;

void Task1_write(void *param)
{
    BaseType_t xStatus=pdPASS;//接收返回值
    int Senddata=100;

	while(1)
	{
		xStatus = xQueueSendToBack( xQueue, &Senddata, 0 );
        
        if(xStatus != pdPASS)
        {    
            printf("send failure");
        }
	}	
}
 
void Task2_read(void *param)
{

    int recydata=0;//用于存取接收到的数据
	BaseType_t xStatus=pdPASS;//接收返回值
      
	while(1)
	{
		xStatus = xQueueReceive( xQueue, &recydata, 100);

		if( xStatus == pdPASS )
		{
			printf( "Received = %d\r\n", recydata);
		}
	}	
}
 
 
int main( void )
{

    xQueue = xQueueCreate( 5, sizeof( int32_t ));

	xTaskCreate(Task1_write,"Task1",100,NULL,1,&xHandleTask1);
	xTaskCreate(Task2_read,"Task2",100,NULL,1,&xHandleTask2);
    
    vTaskStartScheduler();  // 启动任务,开启调度
 
    while(1);   // 正常不会执行到这里 
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值