【嵌入式——FreeRTOS】队列

简介

队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递)。

特点

  1. 队列采用先进先出(FIFO)的数据存储缓冲机制,也支持后进先出(LIFO)原则
  2. 队列才有实际值传递,将数据拷贝到队列中进行传递,采用拷贝数据传递,也可以传递指针,所以在传递较大的数据的时候采用指针传递。
  3. 队列不属于某个任务,任何任务和中断都可以向队列发送/读取消息。
  4. 当任务项一个队列发送消息时,可以指定一个阻塞时间。
    1. 若阻塞时间为0,直接返回不会等待;
    2. 阻塞时间为0~port_MAX_DELAY,等待设定的阻塞时间,若在该时间内还无法入队,超时后直接返回不再等待;
    3. 若阻塞时间为port_MAX_DELAY,死等,一直等到可以入队为止,出队阻塞与入队阻塞类似。

当多个任务写入消息给一个满队列时,这些任务都会进入阻塞状态,当队列中有空间时,哪个任务会进入就绪态?

1.优先级最高的任务
2.如果任务优先级相同,那等待时间最久的任务会进入就绪态。

创建队列API

动态创建队列

使用时必须在FreeRTOSConfig.h中把configSUPPORT_DYNAMIC_ALLOCATION置为1,这是一个启动动态内存分配的宏。

//动态创建队列
xQueueCreate()

#define xQueueCreate( uxQueueLength, uxItemSize )    xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )

//uxQueueLength队列长度
//uxItemSize 队列项大小,以字节为单位
//queueQUEUE_TYPE_BASE 类型 代表队列

//返回值NULL 创建失败,其他值 创建成功,返回队列句柄
#define queueQUEUE_TYPE_BASE                  ( ( uint8_t ) 0U ) //队列
#define queueQUEUE_TYPE_SET                   ( ( uint8_t ) 0U ) //队列集
#define queueQUEUE_TYPE_MUTEX                 ( ( uint8_t ) 1U ) //互斥信号量
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE    ( ( uint8_t ) 2U ) //计数型信号量
#define queueQUEUE_TYPE_BINARY_SEMAPHORE      ( ( uint8_t ) 3U ) //二值信号量
#define queueQUEUE_TYPE_RECURSIVE_MUTEX       ( ( uint8_t ) 4U ) //递归互斥信号量

静态创建队列

//静态创建队列
xQueueCreateStatic()

#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer )    xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) )

写入队列API

函数描述
xQueueSend()往队列的尾部写入消息
xQueueSendToBack()同xQueueSend()
xQueueSendToFront往队列头部写入消息
xQueueOverwrite()覆写队列消息,只用于队列长度为1的情况
xQueueSendFromISR()在中断中往队列的尾部写入消息
xQueueSendToBackFromISR()同xQueueSendFromISR()
xQueueSendToFrontFromISR()在中断中往队列的头部写入消息
xQueueOverwriteFromISR()在中断中覆写队列消息,只用于队列长度为1的情况
//xQueue队列句柄 pvItemToQueue 发送消息内容 xTicksToWait 超时时间
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) \
    xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )

#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) \
    xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )

#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) \
    xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )

#define xQueueOverwrite( xQueue, pvItemToQueue ) \
    xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
                              const void * const pvItemToQueue,
                              TickType_t xTicksToWait,
                              const BaseType_t xCopyPosition )
{}
//xQueue 待写入队列
//pvItemToQueue 待写入消息 
//xTicksToWait 阻塞超时时间
//xCopyPosition 写入位置

//返回值 pdTrue队列写入成功,errQUEUE_FULL 队列写入失败

读取队列API

函数描述
xQueueReceive()从队列头部读取消息,并删除消息
xQueuePeek()从队列头部读取消息
xQueueReceiveFromISR()从中断中从队列头部读取消息,并删除消息
xQueuePeekFromISR()从中断中从队列头部读取消息
//xQueue 队列句柄 pvBuffer 缓存 xTicksToWait 超时时间
BaseType_t xQueueReceive( QueueHandle_t xQueue,
                          void * const pvBuffer,
		 				  TickType_t xTicksToWait) PRIVILEGED_FUNCTION;

BaseType_t xQueuePeek( QueueHandle_t xQueue,
                       void * const pvBuffer,
                       TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
                                 void * const pvBuffer,
                                 BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;


BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
                       void * const pvBuffer ) PRIVILEGED_FUNCTION;

//xQueue 读取的队列
//pvBuffer 数据读取缓冲区
//xTicksToWait 阻塞超时时间

//返回值 pdTRUE 读取成功 pdFALSE 读取失败

队列删除API

删除这个消息队列的所有信息都会被系统回收清空,而且不能再次使用这个消息队列。如果消息队列没没有被创建,是无法被删除的

//xQueue  要删除的队列
void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;

代码示例

#include "queue.h"

#define QUEUE_LEN 4		//队列长度
#define QUEUE_SIZE 4 	//队列中每个消息的大小

QueueHandle_t test_queue = NULL;

void init(){
	test_queue = xQueueCreate((UBaseType_t)QUEUE_LEN ,(UBaseType_t)QUEUE_SIZE );
}


void task1(){
	uint32_t send_data = 1;
	while(1){
		xQueueSend(test_queue , &send_data ,0);
	}
}


void task2(){
	uint32_t r_queue;
	BaseType_t xReturn = pdPASS;
	while(1){
		xReturn = xQueueReceive(test_queue ,&r_queue,portMAX_DELAY);
	}
}
  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值