系列文章目录
文章目录
- 系列文章目录
- 队列集简介
- 相关API函数
- 队列集创建函数
- 队列集中移除函数
- 队列集中获取有消息的队列
- 实验测试:
队列集简介
队列只允许传递一种数据类型,队列集可以传递多种消息。
作用:用于对多个队列或信号量进行“监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态
相关API函数
函数 | 描述 |
---|---|
xQueueCreateSet() | 创建队列集 |
xQueueAddToSet() | 队列添加到队列集中 |
xQueueRemoveFromSet() | 从队列集中移除队列 |
xQueueSelectFromSet() | 获取队列集中有有效消息的队列 |
xQueueSelectFromSetFromISR() | 在中断中获取队列集中有有效消息的队列 |
队列集创建函数
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore , QueueSetHandle_t xQueueSet);
往队列集中添加队列,在被添加到队列集之前,队列中不能有有效的消息。
形参:
xQueueOrSemaphore:待添加的队列句柄
xQueueSet :队列集
返回值:
pdPASS :队列集添加队列成功
pdFAIL :队列集添加队列失败
队列集中移除函数
BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore ,QueueSetHandle_t xQueueSet );
从队列集中移除队列,在从队列集移除之前,必须没有有效的消息
形参:
xQueueOrSemaphore:待移除的队列句柄
xQueueSet :队列集
返回值:
pdPASS :队列集移除队列成功
pdFAIL :队列集移除队列失败
队列集中获取有消息的队列
QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,TickType_t const xTicksToWait )
用于在任务中获取队列集中有有效消息的队列
形参:
xQueueSet:队列集
xTicksToWait:阻塞超时时间
返回值:
NULL:获取消息失败
其他值 :获取到消息的队列句柄
实验测试:
将宏configUSE_QUEUE_SETS置1
#include "semphr.h"
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
return ch;
}
TaskHandle_t task1_handler;
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1( void * pvParameters );
/* TASK2 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2( void * pvParameters );
QueueSetHandle_t queueset_handle;
QueueHandle_t queue_handle;
QueueHandle_t semphr_handle;
void vTaskCode( void * pvParameters )
{
taskENTER_CRITICAL(); /* 进入临界区 */
xTaskCreate((TaskFunction_t ) task1,
(char * ) "task1",
(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(TaskHandle_t * ) &task1_handler );
xTaskCreate((TaskFunction_t ) task2,
(char * ) "task2",
(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(TaskHandle_t * ) &task2_handler );
vTaskDelete(NULL);
taskEXIT_CRITICAL(); /* 退出临界区 */
}
QueueHandle_t mutex_semphore_handle;
// Function that creates a task.
void vOtherFunction( void )
{
queueset_handle = xQueueCreateSet( 2 ); /* 创建队列集,可以存放2个队列 */
if(queueset_handle != NULL)
{
printf("队列集创建成功!!\r\n");
}
queue_handle = xQueueCreate( 1, sizeof(uint8_t) ); /* 创建队列 */
semphr_handle = xSemaphoreCreateBinary(); /* 创建二值信号量 */
xQueueAddToSet( queue_handle,queueset_handle);
xQueueAddToSet( semphr_handle,queueset_handle);
xTaskCreate( vTaskCode, "tak1", 128, NULL, 1, &task1_handler );
vTaskStartScheduler();
}
//实现队列发送和信号量释放
void task1( void * pvParameters )
{
BaseType_t err = 0;
BaseType_t err1 = 0;
uint8_t key=1;
err = xQueueSend( queue_handle, &key, portMAX_DELAY );
if(err == pdPASS)
{
printf("往队列queue_handle写入数据成功!!\r\n");
}
err1 = xSemaphoreGive(semphr_handle);
if(err1 == pdPASS)
{
printf("释放信号量成功!!\r\n");
}
while(1)
{
vTaskDelay(100);
}
}
void task2( void * pvParameters )
{
QueueSetMemberHandle_t member_handle;
uint8_t key;
while(1)
{
member_handle = xQueueSelectFromSet( queueset_handle,portMAX_DELAY);
if(member_handle == queue_handle)
{
xQueueReceive( member_handle,&key,portMAX_DELAY);
printf("获取到的队列数据为:%d\r\n",key);
}else if(member_handle == semphr_handle)
{
xSemaphoreTake( member_handle, portMAX_DELAY );
printf("获取信号量成功!!\r\n");
}
vTaskDelay(10);
}
}
实验说明:由于task1的优先级比task2低,所以先执行task2,获取任务列中有消息的队列,此时没有,进入等待消息阻塞,之后task1执行,先写入队列1,之后回到task2进行了数据获取,之后才回到task1去printf(“往队列queue_handle写入数据成功!!\r\n”);,之后信号量是因为task2进入vTaskDelay阻塞,所以task1才能全部运行完