21-FreeRTOS队列集API函数

简介: 21-FreeRTOS队列集API函数

1-xQueueCreateSet()


1queue.h
2QueueSetHandle_t xQueueCreateSet
3(
4const UBaseType_t uxEventQueueLength
5);


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

队列集提供7了一种机制,允许 RTOS 任务从多个 RTOS 队列或信号量同时进行读取操作后阻塞(挂起)。请注意, 除了使用队列集之外,还有更简单的替代方法。有关详细信息,请参阅 阻塞多个对象页面 。

必须使用调用 xQueueCreateSet() 显式创建队列集, 然后才能使用它。创建后,可以将标准 FreeRTOS 队列和信号量添加到集合中 (通过调用 xQueueAddToSet())。然后,使用 xQueueSelectFromSet() 确定集合中包含的队列或信号量中的哪些(如果有) 处于队列读取或信号量获取操作将成功的状态。

注意:
队列和信号量在添加到队列集时必须为空 。在添加对象时要特别小心, 比如使用已经可用的信号量创建的二进制信号量 [如果使用 vSemaphoreCreateBinary() 宏创建信号量,则属于这种情况, 但如果信号量是使用首选的 xSemaphoreCreateBinary() 函数创建的,则不是这种情况]。
阻塞包含互斥锁的队列集不会导致 互斥锁持有者继承已阻塞任务的优先级。
添加到队列集的每个队列中的每个空格都需要额外的 4 个字节 RAM 。因此,不应将具有较高最大计数值的计数信号量 添加到队列集中。
不得对队列集的成员执行接收(若为队列)或获取(若为 信号量)操作,除非 调用 xQueueSelectFromSet() 先返回了队列集成员的句柄。


1.1 参数:


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

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



1.2 Returns:


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


1.3用法示例:


1/* 定义添加到队列集中的队列的长度。 */
 2#define QUEUE_LENGTH_1    10
 3#define QUEUE_LENGTH_2    10
 4
 5/* Binary semaphores have an effective length of 1. */
 6#define BINARY_SEMAPHORE_LENGTH    1
 7
 8/* Define the size of the item to be held by queue 1 and queue 2 respectively.
 9The values used here are just for demonstration purposes. */
10#define ITEM_SIZE_QUEUE_1    sizeof( uint32_t )
11#define ITEM_SIZE_QUEUE_2    sizeof( something_else_t )
12
13/* The combined length of the two queues and binary semaphore that will be
14added to the queue set. */
15#define COMBINED_LENGTH ( QUEUE_LENGTH_1 +
16QUEUE_LENGTH_2 +
17BINARY_SEMAPHORE_LENGTH )
18
19void vAFunction( void )
20{
21static QueueSetHandle_t xQueueSet;
22QueueHandle_t xQueue1, xQueue2, xSemaphore;
23QueueSetMemberHandle_t xActivatedMember;
24uint32_t xReceivedFromQueue1;
25something_else_t xReceivedFromQueue2;
26
27/* Create the queue set large enough to hold an event for every space in
28every queue and semaphore that is to be added to the set. */
29xQueueSet = xQueueCreateSet( COMBINED_LENGTH );
30
31/* Create the queues and semaphores that will be contained in the set. */
32xQueue1 = xQueueCreate( QUEUE_LENGTH_1, ITEM_SIZE_QUEUE_1 );
33xQueue2 = xQueueCreate( QUEUE_LENGTH_2, ITEM_SIZE_QUEUE_2 );
34
35/* Create the semaphore that is being added to the set. */
36xSemaphore = xSemaphoreCreateBinary();
37
38/* Check everything was created. */
39configASSERT( xQueueSet );
40configASSERT( xQueue1 );
41configASSERT( xQueue2 );
42configASSERT( xSemaphore );
43
44/* Add the queues and semaphores to the set. Reading from these queues and
45semaphore can only be performed after a call to xQueueSelectFromSet() has
46returned the queue or semaphore handle from this point on. */
47xQueueAddToSet( xQueue1, xQueueSet );
48xQueueAddToSet( xQueue2, xQueueSet );
49xQueueAddToSet( xSemaphore, xQueueSet );
50
51for( ;; )
52{
53/* Block to wait for something to be available from the queues or
54semaphore that have been added to the set. Don't block longer than
55200ms. */
56xActivatedMember = xQueueSelectFromSet( xQueueSet,
57200 / portTICK_PERIOD_MS );
58
59/* Which set member was selected? Receives/takes can use a block time
60of zero as they are guaranteed to pass because xQueueSelectFromSet()
61would not have returned the handle unless something was available. */
62if( xActivatedMember == xQueue1 )
63{
64xQueueReceive( xActivatedMember, &xReceivedFromQueue1, 0 );
65vProcessValueFromQueue1( xReceivedFromQueue1 );
66}
67else if( xActivatedMember == xQueue2 )
68{
69xQueueReceive( xActivatedMember, &xReceivedFromQueue2, 0 );
70vProcessValueFromQueue2( &xReceivedFromQueue2 );
71}
72else if( xActivatedMember == xSemaphore )
73{
74/* Take the semaphore to make sure it can be "given" again. */
75xSemaphoreTake( xActivatedMember, 0 );
76vProcessEventNotifiedBySemaphore();
77break;
78}
79else
80{
81/* The 200ms block time expired without an RTOS queue or semaphore
82being ready to process. */
83}
84}
85}


2-xQueueAddToSet()

1queue.h
2BaseType_t xQueueAddToSet
3(
4QueueSetMemberHandle_t xQueueOrSemaphore,
5QueueSetHandle_t xQueueSet
6);


必须在 FreeRTOSConfig.h 中将 configUSE_QUEUE_SETS 设置为 1,这样 xQueueAddToSet

() API 函数才可用。

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

接收(如果是队列)或获取(如果是 信号量)操作,除非 调用 xQueueSelectFromSet() 先返回了队列集成员的句柄。


2.1参数:


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

xQueueSet 正在添加队列或信号量的队列集句柄 。



2.2Returns:


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


3 - xQueueRemoveFromSet()

1queue.h
2BaseType_t xQueueRemoveFromSet
3(
4QueueSetMemberHandle_t xQueueOrSemaphore,
5QueueSetHandle_t xQueueSet
6);


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

从队列集中删除 RTOS 队列或信号量。

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


3.1参数:


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

xQueueSet 包含队列或信号量的队列集的句柄 。


3.2 Returns:


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


3.3 用法示例:


1此示例假定 xQueueSet 是已创建的队列集, 而 xQueue 是已创建并添加到 xQueueSet 中的队列。
 2if( xQueueRemoveFromSet( xQueue, xQueueSet ) != pdPASS )
 3{
 4/* Either xQueue was not a member of the xQueueSet set, or xQueue is
 5not empty and therefore cannot be removed from the set. /
 6}
 7else
 8{
 9/ The queue was successfully removed from the set. */
10}


4- xQueueSelectFromSet()


1queue.h
2QueueSetMemberHandle_t xQueueSelectFromSet
3(
4QueueSetHandle_t xQueueSet,
5const TickType_t xTicksToWait
6);

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

xQueueSelectFromSet() 从队列集成员中选择队列或信号量, 它们要么包含数据(若选择队列),要么可供获取 (若选择信号量)。xQueueSelectFromSet() 能有效 允许任务同时读取一个队列集中的所有 队列和信号量后阻塞(挂起)。

注意:

阻塞包含互斥锁的队列不会导致 互斥锁持有者继承被阻塞任务的优先级。

除非 xQueueSelectFromSet() 信号量)操作,除非 调用 xQueueSelectFromSet() 先返回了队列集成员的句柄。


4.1参数:


xQueueSet 任务(可能)阻塞的队列集。

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


4.2Returns:


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


5 xQueueSelectFromSetFromISR()

1queue.h
2QueueSetMemberHandle_t xQueueSelectFromSetFromISR
3(
4QueueSetHandle_t xQueueSet
5);

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

xQueueSelectFromSet() 的一个版本, 可以从中断服务程序 (ISR) 中使用。


5.1参数:


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



5.2 Returns :


xQueueSelectFromSetFromISR() 将返回一个队列的句柄(被转换为 QueueSetMemberHandle_t 类型), 该队列包含在包含数据的队列集中, 或队列集中可用信号量的句柄(转换为 QueueSetMemberHandle_t 类型), 该信号量包含在可用的队列集中;如果不存在这样的队列或信号量,则返回 NULL 。


相关文章
|
1月前
|
存储 JavaScript API
活用 Composition API 核心函数,打造卓越应用(上)
活用 Composition API 核心函数,打造卓越应用(上)
|
1月前
|
缓存 JavaScript 算法
活用 Composition API 核心函数,打造卓越应用(下)
活用 Composition API 核心函数,打造卓越应用(下)
|
1月前
|
人工智能 关系型数据库 Serverless
Serverless 应用引擎常见问题之API生成的函数镜像改为自定义的镜像如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
Qt 窗口常用位置API函数 & 绘图原理 & 双缓冲机制 总结
Qt 窗口常用位置API函数 & 绘图原理 & 双缓冲机制 总结
|
1月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
116 3
|
1月前
|
JavaScript API
Vue3 API函数及功能
Vue3 API函数及功能
13 0
|
1月前
|
存储 安全 Linux
【Linux 创建临时文件 API】编程中的瞬息之光:临时文件的艺术与智慧 tmpnam,tmpfile,mkstemp,mkdtemp等函数解析...
【Linux 创建临时文件 API】编程中的瞬息之光:临时文件的艺术与智慧 tmpnam,tmpfile,mkstemp,mkdtemp等函数解析...
39 0
|
1月前
|
数据库连接 API 数据库
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
96 0
|
1月前
|
编译器 API C++
【C++ 动态库设计】动态库中的模板函数:解决如果将模板函数封装成API库
【C++ 动态库设计】动态库中的模板函数:解决如果将模板函数封装成API库
109 0
|
1月前
|
存储 API 数据安全/隐私保护
FreeRTOS入门教程(信号量的概念及API函数使用)
FreeRTOS入门教程(信号量的概念及API函数使用)
187 0