哈尔滨营销网站制作,国家示范校建设网站,做彩票网站收费标准,饰品公司网站建设方案1.简介
在使用队列进行任务之间的“沟通交流”时#xff0c;一个队列只允许任务间传递的消息为同一种数据类型#xff0c;如果需要在任务间传递不同数据类型的消息时#xff0c;那么就可以使用队列集。FreeRTOS提供的队列集功能可以对多个队列进行“监听”#xff0c;只要…1.简介
在使用队列进行任务之间的“沟通交流”时一个队列只允许任务间传递的消息为同一种数据类型如果需要在任务间传递不同数据类型的消息时那么就可以使用队列集。FreeRTOS提供的队列集功能可以对多个队列进行“监听”只要被监听的队列中有一个队列有有效的消息那么队列集的读取任务都可以读取到消息如果读取任务因读取队列集而被阻塞那么队列集将解除读取任务的阻塞。使用队列集的好处在于队列集可以是的任务可以读取多个队列中的消息而无需遍历所有待读取的队列以确定具体读取哪一个队列。
使用队列集功能需要在 FreeRTOSConfig.h 文件中将配置项 configUSE_QUEUE_SETS 配 置为 1来启用队列集功能。
2.相关API函数 1. 函数 xQueueCreateSet()
此函数用于创建队列集该函数在 queue.c 文件中有定义函数的原型如下所示
QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength);QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
{QueueSetHandle_t pxQueue;/* 创建一个队列作为队列集* 队列长度为队列集可容纳的队列数量* 队列项目的大小为队列控制块的大小* 队列的类型为队列集*/pxQueue xQueueGenericCreate( uxEventQueueLength,( UBaseType_t ) sizeof( Queue_t * ),queueQUEUE_TYPE_SET );return pxQueue;
}2. 函数 xQueueAddToSet()
此函数用于往队列集中添加队列要注意的时队列在被添加到队列集之前队列中不能 有有效的消息该函数在 queue.c 文件中有定义函数的原型如下所示
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);函数 xQueueAddToSet()的具体代码如下所示
BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet)
{BaseType_t xReturn;/* 进入临界区 */taskENTER_CRITICAL();{if( ( ( Queue_t * ) xQueueOrSemaphore )-pxQueueSetContainer ! NULL ){xReturn pdFAIL;}/* 队列中要求没有有效消息 */else if( ( ( Queue_t * ) xQueueOrSemaphore )-uxMessagesWaiting !( UBaseType_t ) 0 ){xReturn pdFAIL;}else{/* 将队列所在队列集设为队列集 */( ( Queue_t * ) xQueueOrSemaphore )-pxQueueSetContainer xQueueSet;xReturn pdPASS;}}/* 退出临界区 */taskEXIT_CRITICAL();return xReturn;
}
3. 函数 xQueueRemoveFromSet()
此函数用于从队列集中移除队列要注意的时队列在从队列集移除之前必须没有有效 的消息该函数在 queue.c 文件中有定义函数的原型如下所示
BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);函数 xQueueRemoveFromSet()的具体代码如下所示
BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet)
{BaseType_t xReturn;Queue_t * const pxQueueOrSemaphore ( Queue_t * ) xQueueOrSemaphore;/* 队列需在队列集中才能移除 */if( pxQueueOrSemaphore-pxQueueSetContainer ! xQueueSet ){xReturn pdFAIL;}/* 队列中没有有效消息时才能移除 */else if( pxQueueOrSemaphore-uxMessagesWaiting ! ( UBaseType_t ) 0 ){xReturn pdFAIL;}else{/* 进入临界区 */taskENTER_CRITICAL();{/* 将队列所在队列集设为空 */pxQueueOrSemaphore-pxQueueSetContainer NULL;}/* 退出临界区 */taskEXIT_CRITICAL();xReturn pdPASS;}return xReturn;
}4. 函数 xQueueSelectFromSet()
此函数用于在任务中获取队列集中有有效消息的队列该函数在 queue.c 文件中有定义函 数的原型如下所示
QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,TickType_t const xTicksToWait);函数 xQueueSelectFromSet()的具体代码如下所示
QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,TickType_t const xTicksToWait)
{QueueSetMemberHandle_t xReturn NULL;/* 读取队列集的消息* 读取到的消息* 即为队列集中有空闲消息的队列*/( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet,xReturn,xTicksToWait);return xReturn;
}5. 函数 xQueueSelectFromSetFromISR()
此函数用于在中断中获取队列集中有有效消息的队列该函数在 queue.c 文件中有定义函 数的原型如下所示
QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet );QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet )
{QueueSetMemberHandle_t xReturn NULL;/* 在中断中读取队列集的消息* 读取到的消息* 即为队列集中有空闲消息的队列*/( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet,xReturn,NULL);return xReturn;
}3.相关实验 #include freertos_demo.h
#include ./SYSTEM/usart/usart.h
#include ./BSP/LED/led.h
#include ./BSP/LCD/lcd.h
#include ./BSP/KEY/key.h
#include ./SYSTEM/delay/delay.h
#include ./MALLOC/malloc.h
/*FreeRTOS*********************************************************************************************/
#include FreeRTOS.h
#include task.h
#include queue.h
#include semphr.h
/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#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;
/*** brief FreeRTOS例程入口函数* param 无* retval 无*/
void freertos_demo(void)
{ xTaskCreate((TaskFunction_t ) start_task,(char * ) start_task,(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL(); /* 进入临界区 */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((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(); /* 退出临界区 */
}/* 任务一实现队列发送以及信号量释放 */
void task1( void * pvParameters )
{uint8_t key 0;BaseType_t err 0;while(1) {key key_scan(0);if(key KEY0_PRES){err xQueueSend( queue_handle, key, portMAX_DELAY );if(err pdPASS){printf(往队列queue_handle写入数据成功\r\n);}}else if(key KEY1_PRES){err xSemaphoreGive(semphr_handle);if(err pdPASS){printf(释放信号量成功\r\n);}}vTaskDelay(10);}
}/* 任务二获取队列集的消息 */
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);}}
}