欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > FreeRTOS学习笔记-基于stm32(8)消息队列

FreeRTOS学习笔记-基于stm32(8)消息队列

2024/10/25 12:16:58 来源:https://blog.csdn.net/m0_74800695/article/details/139436213  浏览:    关键词:FreeRTOS学习笔记-基于stm32(8)消息队列

一、什么是消息队列

        队列是不同任务、中断中数据传递的一种机制,又称消息队列。就类似于全局变量,将数据传输到不同的任务中。但全局变量没有写保护,容易造成数据受损。而消息队列中加入了进入临界区的写保护

        队列类似于数组,可以存储数量有限,大小固定的数据。队列中的每个数据叫做队列项目,能存储最大队列项目的数量交队列的长度。

二、队列的特点

        1、入队出对的方式通常为先进先出,也可配置为后进先出;

        2、数据的传递可以采用值传递,也可以是传递指针;

        3、入队出队阻塞:当队列满了无法入队或队列空了无法出队时,称为入队和出队阻塞。可在任务向队列发送消息的时候设置阻塞时间。

        如果阻塞时间为0,直接继续执行下面代码,不等待;

        如果阻塞时间为0~FFFFFFFF,等待设定的时间,如果在这段时间内还无法入队/出队,则不等待;

        如果阻塞时间为FFFFFFFF,一直等到可以入队/出队为止。

        4、在等待(即阻塞)过程中,该任务的状态列表项被挂在到阻塞列表中(pxDelayedTaskLits),事件列表项被挂在在等待接收(xTasksWaitingToReceive)/发送列表(xTasksWaitingToSend)中;

        5、多个任务写入满队列时,优先级高的优先写入,如果优先级相同,等待久的优先写入。

三、队列的相关API函数

1、队列结构体

typedef struct QueueDefinition
{int8_t *pcHead;						/*< 指向队列存储区的开头。 */int8_t *pcTail;						/*< 指向队列存储区的末尾字节。比实际需要的队列项多分配一个字节,用作标记。 */int8_t *pcWriteTo;					/*< 指向存储区的下一个可用位置。 */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;			/*< 存储在队列被锁定时从队列接收的项数(从队列中移除)。当队列未被锁定时,设置为 queueUNLOCKED。 */volatile int8_t cTxLock;			/*< 存储在队列被锁定时传输到队列的项数(添加到队列中)。当队列未被锁定时,设置为 queueUNLOCKED。 */#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )uint8_t ucStaticallyAllocated;	/*< 如果队列的内存是静态分配的,则设置为 pdTRUE,以确保不会尝试释放内存。 */#endif#if ( configUSE_QUEUE_SETS == 1 )struct QueueDefinition *pxQueueSetContainer;#endif#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t uxQueueNumber;uint8_t ucQueueType;#endif} xQUEUE;

2、创建队列

函数描述
xQueueCreate()动态方式创建队列
xQueueCreateStatic()静态方式创建队列
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( 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 )    /*< 递归互斥锁队列类型。 */

3、写入消息

        前四个为任务级,后四个为中断级。

函数描述
xQueueSend()往队列的尾部写入消息
xQueueSendToBack()同xQueueSend()
xQueueSendToFront()往队列的头部写入消息
xQueueOverwrite()覆盖队列消息(只用于队列长度为1的情况)

xQueueSendFromISR()

在中断中往队列的尾部写入消息
xQueueSendToBackFromISR()同xQueueSendFromISR()
xQueueSendToFrontFromISR()在中断中往队列的头部写入消息
xQueueOverwriteFromISR()在中断中覆盖队列消息(只用于队列长度为1的情况)
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )

        队列写入消息都调用的是此函数,只是第四个参数不同。

        函数写入成功返回pdTRUE,写入失败返回errQUEUE_FULL。

        第一个参数表示要写入的队列,第二个参数表示要写入的消息,第三个参数表示阻塞时间,第四个参数是写入方式,有下面三种:

#define queueSEND_TO_BACK		( ( BaseType_t ) 0 )   /*< 将项目发送到队列的后面。 */
#define queueSEND_TO_FRONT		( ( BaseType_t ) 1 )   /*< 将项目发送到队列的前面。 */
#define queueOVERWRITE			( ( BaseType_t ) 2 )   /*< 覆盖队列中已有的项目。 */

4、读取消息

        前两个为任务级,后两个为中断级。

函数描述
xQueueReceive()从队列头部读取消息,删除消息
xQueuePeek()从队列头部读取消息
xQueueReceiveFromISR()在中断中从队列头部读取消息,删除消息
xQueuePeekFromISR()在中断中从队列头部读取消息
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )

        该函数有三个参数,分别是待读取的队列,信息读取缓冲区,阻塞时间。

        读取成功返回pdTRUE,失败返回pdFALSE

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com