FreeRTOS学习:8.消息队列

一、基本介绍

        队列在算法中是一种数据结构,其基本特点是先进先出(FIFO),与栈这种是刚好相反的(FILO)。在FreeRTOS中,队列这种数据结构主要是是用于在任务和任务,任务和中断直接进行消息传递的机制,其可以避免在使用全局变量时,多个任务同时访问到时数据受损的情况发生。在FreeRTOS中,基于队列实现了多种功能,其中包括了队列集、二值信号量、互斥信号量、计数型信号量、递归互斥信号量,很好的实现了任务之间协同。

        FreeRTOS队列的特点是:1.数据先进先出,但也可配置为后进先出的数据缓存方式2.传递进队列的值可以是实际值(拷贝一份,修改数据,缓存进队列的值不会改变),也可以是地址(修改数据,队列存储的地址对应的数据也发生改变)。3.队列是全局变量(内存申请在堆上),不属于任何一个任务,所有任务和中断都可以对队列进行操作。4.出队和入队都可以设置阻塞时间(队列满和队列空),当设置为0时,直接返回不等待,当设置0-portMAX_DELAY,等待设定的阻塞时间,超时返回不再等待,当设置时间为portMAX_DELAY,则死等。

        多个任务阻塞在入队和出队时,优先级最高的任务会先入队或出队(从阻塞态进入就绪态),优先级相同时,已经等待时间最长的任务会进行就绪态

        队列的基本操作是:1、创建队列;2、入队;3、出队。

        队列的结构体如下所示:

typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{
    int8_t * pcHead;           /*< Points to the beginning of the queue storage area. */
    int8_t * pcWriteTo;        /*< Points to the free next place in the storage area. */

    union
    {
        QueuePointers_t xQueue;     /*< Data required exclusively when this structure is used as a queue. */
        SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */
    } u;

    List_t xTasksWaitingToSend;             /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */
    List_t xTasksWaitingToReceive;          /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */

    volatile UBaseType_t uxMessagesWaiting; /*< The number of items currently in the queue. */
    UBaseType_t uxLength;                   /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
    UBaseType_t uxItemSize;                 /*< The size of each items that the queue will hold. */

    volatile int8_t cRxLock;                /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */
    volatile int8_t cTxLock;                /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */

    #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;
    #endif

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

其中的联合体是区分使用队列或者信号量的。

二、函数介绍

1.队列创建函数

队列的创建分为动态创建-xQueueCreate()和静态创建xQueueCreateStatic(),

xQueueCreate ( uxQueueLength, uxItemSize )--形参分别是是队列长度,和队列项大小,返回值为NULL,队列创建失败,其他值(队列句柄)则队列创建成功。

xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer )--形参分别是队列长度,队列项大小,队列项存储空间大小和队列句柄

2.写入队列函数

队列的写入函数主要有以下几个:

这些函数的本质都是一个宏定义,对应的是函数如下函数:

BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
                              const void * const pvItemToQueue,
                              TickType_t xTicksToWait,
                              const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;

根据最后一个参数xCopyPosition确定写入位置。

3.读取队列函数

队列的读取函数主要有以下几个:

三、问题与总结

1.创建队列时,不能直接 按照以下语句创建QueueHandle_t  q = xQueueCreate(length, size);

需要分两步进行。

2.传入比较大的数据的指针时,要注意传入的指针是可变的,而不能传入一个指针常量,例如数组名。

3.队列创建是由FreeRTOS使用类似于malloc函数分配空间的,所以可以再函数内部调用,函数调用结束不会被释放。

4.在写入队列(读取队列时)时,写入(读取)后会判断是否有任务读取(写入)队列并被阻塞,如果有的话,会将该任务从阻塞态移出,进入就绪态。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值