系列文章目录
文章目录
- 系列文章目录
- 队列集简介
- 相关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才能全部运行完



















