FreeRTOS学习笔记 & FreeRTOS队列集

队列集简介

一个队列只允许任务间传递的消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集!

队列集用于对多个队列或信号量进行“监听”其中不管哪一个消息到来,都可让任务退出阻塞状态

队列集API函数

xQueueCreateSet 创建一个队列集

必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1xQueueCreateSet() API 函数才可用

#define configUSE_QUEUE_SETS  1

QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength);

参数:
uxEventQueueLength  	队列集存储集合中包含的队列和 信号量上发生的事件。 uxEventQueueLength 指定一次可以排队的最大事件数 。

要绝对确定事件不会丢失, 必须将 uxEventQueueLength 设置为 添加到集合中的队列长度之和,其中二进制信号量和 互斥体长度为 1,计数信号量的 长度由其最大计数值设置。 例如:

如果队列集要保存一个长度为 5 的队列, 另一个长度为 12 的队列和一个二进制信号量, 则 uxEventQueueLength 应设置为 (5 + 12 + 1)18。
如果队列集要容纳三个二进制信号量, 则 uxEventQueueLength 应设置为 (1 + 1 + 1)3。
如果队列集要保持最大计数为 5 的计数信号量 和最大计数为 3 的计数信号量, 则 uxEventQueueLength 应设置为 (5 + 3)8。

Returns:
如果成功创建队列集,则返回所创建队列集的句柄 。 否则返回 NULL。

用法示例:
/* Define the lengths of the queues that will be added to the queue set. */
#define QUEUE_LENGTH_1		10
#define QUEUE_LENGTH_2		10

/* Binary semaphores have an effective length of 1. */
#define BINARY_SEMAPHORE_LENGTH	1

/* 分别定义队列1和队列2要容纳的项目的大小。 此处使用的值仅用于演示目的s. */
#define ITEM_SIZE_QUEUE_1	sizeof( uint32_t )
#define ITEM_SIZE_QUEUE_2	sizeof( something_else_t )

/* 两个队列和二进制信号量的组合长度 添加到队列集. */
#define COMBINED_LENGTH ( QUEUE_LENGTH_1 +
                          QUEUE_LENGTH_2 +
                          BINARY_SEMAPHORE_LENGTH )

void vAFunction( void )
{
	static QueueSetHandle_t xQueueSet;//创建一个队列集句柄
	
	QueueHandle_t xQueue1, xQueue2, xSemaphore;//创建,2个消息队列和一个信号量
	
	QueueSetMemberHandle_t xActivatedMember;//以就绪队列句柄缓存
	
	uint32_t xReceivedFromQueue1;
	
	something_else_t xReceivedFromQueue2;

    /* 创建队列集. */
    xQueueSet = xQueueCreateSet( COMBINED_LENGTH );

    /* 创建队列. */
    xQueue1 = xQueueCreate( QUEUE_LENGTH_1, ITEM_SIZE_QUEUE_1 );
    xQueue2 = xQueueCreate( QUEUE_LENGTH_2, ITEM_SIZE_QUEUE_2 );

    /* 创建二值信号量. */
    xSemaphore = xSemaphoreCreateBinary();

    /* 将队列和信号量添加到队列集. */
    xQueueAddToSet( xQueue1, xQueueSet );
    xQueueAddToSet( xQueue2, xQueueSet );
    xQueueAddToSet( xSemaphore, xQueueSet );

    for( ;; )
    {
        /* 等待队列集中就绪队列或信号量,可设置阻塞. */
        /* 读取到则解除阻塞并返回相应队列句柄*/
        xActivatedMember = xQueueSelectFromSet( xQueueSet,200 / portTICK_PERIOD_MS );

        /* 选择了哪个集合成员?接收/接收可以使用分段时间 因为xQueueSelectFromSet() 除非有可用的东西,否则不会返回句柄. */
        if( xActivatedMember == xQueue1 )
        {
            xQueueReceive( xActivatedMember, &xReceivedFromQueue1, 0 );
            vProcessValueFromQueue1( xReceivedFromQueue1 );
        }
        else if( xActivatedMember == xQueue2 )
        {
            xQueueReceive( xActivatedMember, &xReceivedFromQueue2, 0 );
            vProcessValueFromQueue2( &xReceivedFromQueue2 );
        }
        else if( xActivatedMember == xSemaphore )
        {
            /* Take the semaphore to make sure it can be "given" again. */
            xSemaphoreTake( xActivatedMember, 0 );
            vProcessEventNotifiedBySemaphore();
            break;
        }
        else
        {
            /* The 200ms block time expired without an RTOS queue or semaphore
            being ready to process. */
        }
    }
}

xQueueAddToSet 添加以创建的信号量或队列到队列集

将 RTOS 队列或信号量添加至先前由 xQueueCreateSet() 调用创建的队列集

必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1xQueueAddToSet () API 函数才可用

#define configUSE_QUEUE_SETS  1

BaseType_t xQueueAddToSet
                      (
                          QueueSetMemberHandle_t xQueueOrSemaphore,
                          QueueSetHandle_t xQueueSet
                      );

参数:
xQueueOrSemaphore  	正在添加到队列集的队列或信号量的句柄 (转换为 QueueSetMemberHandle_t 类型)。
xQueueSet  	正在添加队列或信号量的队列集句柄 。

Returns:
如果队列或信号量成功添加到队列集 那么返回 pdPASS。 如果队列无法成功添加到 队列集,因为它已经是其他队列集的成员,那么返回 pdFAIL 

用法示例:
/* 将队列和信号量添加到队列集. */
    xQueueAddToSet( xQueue1, xQueueSet );
    xQueueAddToSet( xQueue2, xQueueSet );
    xQueueAddToSet( xSemaphore, xQueueSet );

xQueueRemoveFromSet 从队列集中删除队列

仅当队列或信号量为空时,才能从队列集中删除 RTOS 队列或信号量

必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1xQueueRemoveFromSet() API 函数才可用

#define configUSE_QUEUE_SETS  1

 BaseType_t xQueueRemoveFromSet
                      (
                          QueueSetMemberHandle_t xQueueOrSemaphore,
                          QueueSetHandle_t xQueueSet
                      );

参数:
xQueueOrSemaphore  	从队列集中删除的队列或信号量的句柄 (转换为 QueueSetMemberHandle_t 类型)。
xQueueSet  	包含队列或信号量的队列集的句柄 。

Returns:
如果队列或信号量已成功从队列集中删除, 则返回 pdPASS。 如果队列不在队列集中,或者 队列(或信号量)不为空,则返回 pdFAIL。

用法示例:
此示例假定 xQueueSet 是已创建的队列集, 而 xQueue 是已创建并添加到 xQueueSet 中的队列。


    if( xQueueRemoveFromSet( xQueue, xQueueSet ) != pdPASS )
    {
        /* Either xQueue was not a member of the xQueueSet set, or xQueue is
        not empty and therefore cannot be removed from the set. */
    }
    else
    {
        /* The queue was successfully removed from the set. */
    }

xQueueSelectFromSet 从队列集中选择以就绪的队列(任务中使用)

必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1xQueueSelectFromSet () API 函数才可用

#define configUSE_QUEUE_SETS  1

 QueueSetMemberHandle_t xQueueSelectFromSet
                       (
                             QueueSetHandle_t xQueueSet,
                             const TickType_t xTicksToWait
                        );

参数:
xQueueSet  	任务(可能)阻塞的队列集。
xTicksToWait  	调用任务保持阻塞状态(其他任务正在执行), 等待队列集成员做好准备 以便成功读取队列或获取信号量所需的最长时间, 以滴答为单位。

Returns:
xQueueSelectFromSet() 将返回 队列集中包含数据的队列的句柄(转换为 QueueSetMemberHandle_t 类型) 或队列集中可用信号量的句柄(转换为 QueueSetMemberHandle_t 类型), 如果在指定的阻塞时间到期之前不存在这样的队列或信号量, 则返回 NULL

用法示例:
for( ;; )
    {
        /* 等待队列集中就绪队列或信号量,可设置阻塞. */
        /* 读取到则解除阻塞并返回相应队列句柄*/
        xActivatedMember = xQueueSelectFromSet( xQueueSet,200 / portTICK_PERIOD_MS );

        /* 选择了哪个集合成员?接收/接收可以使用分段时间 因为xQueueSelectFromSet() 除非有可用的东西,否则不会返回句柄. */
        if( xActivatedMember == xQueue1 )
        {
            xQueueReceive( xActivatedMember, &xReceivedFromQueue1, 0 );
            vProcessValueFromQueue1( xReceivedFromQueue1 );
        }
        else if( xActivatedMember == xQueue2 )
        {
            xQueueReceive( xActivatedMember, &xReceivedFromQueue2, 0 );
            vProcessValueFromQueue2( &xReceivedFromQueue2 );
        }
        else if( xActivatedMember == xSemaphore )
        {
            /* Take the semaphore to make sure it can be "given" again. */
            xSemaphoreTake( xActivatedMember, 0 );
            vProcessEventNotifiedBySemaphore();
            break;
        }
        else
        {
            /* The 200ms block time expired without an RTOS queue or semaphore
            being ready to process. */
        }
    }
}

xQueueSelectFromSetFromISR(中断中使用)

必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1xQueueSelectFromSetFromISR() API 函数才可用

#define configUSE_QUEUE_SETS  1

 QueueSetMemberHandle_t xQueueSelectFromSetFromISR
                       (
                             QueueSetHandle_t xQueueSet
                        );

参数:
xQueueSet  	正在查询的队列集。 因为此函数设计为从中断中使用, 所以无法在读取时阻塞 。

Returns:
xQueueSelectFromSetFromISR() 将返回一个队列的句柄(被转换为 QueueSetMemberHandle_t 类型), 该队列包含在包含数据的队列集中, 或队列集中可用信号量的句柄(转换为 QueueSetMemberHandle_t 类型), 该信号量包含在可用的队列集中;如果不存在这样的队列或信号量,则返回 NULL
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值