freertos- 队列及其操作API

如图1所示,相关数据类型

typedef struct xSTATIC_QUEUE
{
	void *pvDummy1[ 3 ];

	union
	{
		void *pvDummy2;
		UBaseType_t uxDummy2;
	} u;

	StaticList_t xDummy3[ 2 ];
	UBaseType_t uxDummy4[ 3 ];
	uint8_t ucDummy5[ 2 ];

} StaticQueue_t;

typedef StaticQueue_t StaticSemaphore_t;

/* 队列句柄 xQueueCreate()*/
typedef void * QueueHandle_t;

/*队列集 句柄,xQueueCreateSet()*/
typedef void * QueueSetHandle_t;

/* ??? */
typedef void * QueueSetMemberHandle_t;

 struct AMessage
 {
	char ucMessageID;
	char ucData[ 20 ];
 };
 
/* 队列标志. */
#define	queueSEND_TO_BACK		( ( BaseType_t ) 0 ) //队列后
#define	queueSEND_TO_FRONT		( ( BaseType_t ) 1 ) //队列前
#define queueOVERWRITE			( ( BaseType_t ) 2 ) // 复写

/* 6种 队列的类型标志. */
#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 )// 递归互斥锁队列

typedef struct QueueDefinition
{
	int8_t *pcHead; /*< 指向队列存储区域的开头. */
	int8_t *pcTail; /*< 指向队列存储区域末尾的字节。一旦分配了多于存储队列项所需的字节,就将其用作标记. */
	int8_t *pcWriteTo; /*< 指向存储区域中空闲的下一个位置. */

	union /* 使用union是编码标准的一个例外,以确保两个互斥结构成员不会同时出现(浪费RAM)。 */
	{
		int8_t *pcReadFrom; /*< 指向结构用作队列时读取队列项的最后一个位置. */
		UBaseType_t uxRecursiveCallCount;/*< 在结构用作互斥锁时,维护递归互斥锁被递归地“占用”的次数的计数 */
	} u;

	List_t xTasksWaitingToSend; /*< 阻塞的任务列表,这些任务等待发送到此队列。按优先顺序存储. */
	List_t xTasksWaitingToReceive;	/*< 阻塞等待从该队列读取的任务列表。按优先顺序存储. */

	volatile UBaseType_t uxMessagesWaiting;/*< 当前队列中的项数. */
	UBaseType_t uxLength;			/*< 队列的长度定义为它将持有的项的数量,而不是字节的数量. */
	UBaseType_t uxItemSize;			/*< 队列将持有的每个项目的大小。 */

	volatile int8_t cRxLock;		/*< 存储在锁定队列时从队列接收(从队列中删除)的项数。当队列未锁定时,设置为queue解锁. */
	volatile int8_t cTxLock;		/*< 存储在锁定队列时传输到队列(添加到队列)的项数。当队列未锁定时,设置为queue解锁. */

	#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
		uint8_t ucStaticallyAllocated;	
	#endif

	#if ( configUSE_QUEUE_SETS == 1 )
		struct QueueDefinition *pxQueueSetContainer;
	#endif

	#if ( configUSE_TRACE_FACILITY == 1 )
		UBaseType_t uxQueueNumber;
		uint8_t ucQueueType;
	#endif

} xQUEUE;

2,相关全局量

 #define QUEUE_LENGTH 10
 #define ITEM_SIZE sizeof( uint32_t )

 // xQueueBuffer将保存队列结构。
 StaticQueue_t xQueueBuffer;

 // ucQueueStorage将保存提交到队列的项目。至少 [(queue length) * ( queue item size)] bytes long.
 uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];

3,API接口

------------------------------------------------------------
//队列注册表是作为内核感知调试器定位队列、信号量和互斥量的一种方法提供的。调用pcQueueGetName()从队列的句柄查找并返回队列注册表中的队列名称。
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType );
//用于使用动态内存分配创建队列的函数的通用版本。这由其他函数和宏调用,这些函数和宏创建其他使用队列结构作为基的RTOS对象。
QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType );
#define xQueueCreate( uxQueueLength, uxItemSize )   xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) )
------------------------------------------------------------
//删除队列——释放为存储放置在队列上的项目而分配的所有内存。
void vQueueDelete( QueueHandle_t xQueue );
//返回存储在队列中的消息数。
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
//返回队列中可用空闲空间的数量。这等于如果没有删除任何项,则在队列满之前可以发送到队列的项数。
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
------------------------------------------------------------
//最好使用宏xQueueSend()、xQueueSendToFront()和xQueueSendToBack()来代替直接调用这个函数。
//将项目发布到队列上。这个项目是通过复制而不是引用来排队的。这个函数不能从中断服务程序中调用。可以在ISR中使用xQueueSendFromISR()作为替代。
BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition );
//将项目发布到队列前面。这个项目是通过复制而不是引用来排队的。这个函数不能从中断服务程序中调用。可以在ISR中使用xQueueSendFromISR()作为替代。
#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
//将项目发布到队列的后面。这个项目是通过复制而不是引用来排队的。这个函数不能从中断服务程序中调用。可以在ISR中使用xQueueSendFromISR()作为替代。
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
//这是一个调用xQueueGenericSend()的宏。它是为了向后兼容FreeRTOS.org的版本而包含的,这些版本不包括xQueueSendToFront()和xQueueSendToBack()宏。它等价于xQueueSendToBack()。
//将项目发布到队列上。这个项目是通过复制而不是引用来排队的。这个函数不能从中断服务程序中调用。可以在ISR中使用xQueueSendFromISR()作为替代。
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
//仅用于长度为1的队列——因此队列要么是空的,要么是满的。
//将项目发布到队列上。如果队列已满,则覆盖队列中持有的值。这个项目是通过复制而不是引用来排队的。
//这个函数不能从中断服务程序中调用。请参阅xQueueOverwriteFromISR(),了解可以在ISR中使用的替代方法。
#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
------------------------------------------------------------
//最好使用宏xQueueSendFromISR()、xQueueSendToFrontFromISR()和xQueueSendToBackFromISR()来代替直接调用这个函数。xQueueGiveFromISR()对于不复制任何数据的信号量来说是等价的。
//将项目发布到队列上。在中断服务程序中使用这个函数是安全的。
//项目是通过复制而不是引用来排队的,所以这比只对小项目排队更好,特别是在从ISR调用时。在大多数情况下,最好是存储一个指向正在排队的项目的指针。
BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition );
BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken );
//这是一个调用xQueueGenericSendFromISR()的宏。
//将项目发布到队列前面。在中断服务程序中使用这个宏是安全的。
//项目是通过复制而不是引用来排队的,所以这比只对小项目排队更好,特别是在从ISR调用时。在大多数情况下,最好是存储一个指向正在排队的项目的指针。
#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )
//这是一个调用xQueueGenericSendFromISR()的宏。
//将项目发布到队列的后面。在中断服务程序中使用这个宏是安全的。
//项目是通过复制而不是引用来排队的,所以这比只对小项目排队更好,特别是在从ISR调用时。在大多数情况下,最好是存储一个指向正在排队的项目的指针。
#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
//可以在中断服务例程(ISR)中使用的xQueueOverwrite()的一个版本。
//仅用于可以保存单个项目的队列——因此队列要么是空的,要么是满的。
//将项目发布到队列上。如果队列已满,则覆盖队列中持有的值。这个项目是通过复制而不是引用来排队的。
#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE )
//这是一个调用xQueueGenericSendFromISR()的宏。它是为了向后兼容FreeRTOS.org的版本而包含的,这些版本不包括xQueueSendToBackFromISR()和xQueueSendToFrontFromISR()宏。
//将项目发布到队列的后面。在中断服务程序中使用这个函数是安全的。
//项目是通过复制而不是引用来排队的,所以这比只对小项目排队更好,特别是在从ISR调用时。在大多数情况下,最好是存储一个指向正在排队的项目的指针。
#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
------------------------------------------------------------
//最好使用宏xQueueReceive(),而不是直接调用这个函数。
//从队列接收项目。项目通过复制接收,因此必须提供足够大小的缓冲区。创建队列时定义了复制到缓冲区中的字节数。
//这个函数不能在中断服务程序中使用。请参阅xQueueReceiveFromISR,以获得一个可行的替代方案。
BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek );
//从队列接收项目。项目通过复制接收,因此必须提供足够大小的缓冲区。创建队列时定义了复制到缓冲区中的字节数。
//成功接收到的项目将从队列中删除。这个函数不能在中断服务程序中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值