队列 是任务到任务、任务到中断、中断到任务数据交流 的一种机制(消息传递 )使用队列的情况下如图,在写 、读队列 时,会进入临界区 ,无法触发任务调度,不会出现多任务冲突,只需要调用API函数即可 在队列中可以存储数量有限 、大小固定的数据 。队列中的每一个数据叫做“队列项目 ”,队列能够存储“队列项目”的最大数量 称为队列的长度  队列采用先进先出 (FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取,FreeRTOS也可以配置成先进后出的方式 FreeRTOS中队列采用实际值 传递,或传递地址  任何任务和中断 都可以向队列发送/读取消息当任务向一个队列发送消息时,可以指定一个阻塞时间 ,设置阻塞时间,确定是否等待或者返回  当任务A写入队列时,队列已满 的情况下,可以将该任务挂在阻塞列表 或等待发送列表 。当任务B从队列读取数据时,队列无数据 的情况下,将任务挂在阻塞列表 或等待接收列表里  typedef  struct  QueueDefinition 
{ 
    int8_t  *  pcHead; 
    int8_t  *  pcWriteTo; 
    union 
    { 
        QueuePointers_t xQueue; 
        SemaphoreData_t xSemaphore; 
    }  u; 
    List_t xTasksWaitingToSend; 
    List_t xTasksWaitingToReceive; 
    volatile  UBaseType_t uxMessagesWaiting; 
    UBaseType_t uxLength; 
    UBaseType_t uxItemSize; 
    volatile  int8_t  cRxLock; 
    volatile  int8_t  cTxLock; 
    
} xQUEUE; 
使用队列时,主要流程为:创建队列  -> 写队列  -> 读队列  创建队列 相关API函数xQueueCreate ( ) ; 
xQueueCreateStatic ( ) ; 
# define  xQueueCreate ( uxQueueLength, uxItemSize) xQueueGenericCreate (  ( uxQueueLength) , ( uxItemSize) , ( queueQUEUE_TYPE_BASE)  ) 
xQueueSend ( ) ; 
xQueueSendToBack ( ) ; 
xQueueSendToFront ( ) ; 
xQueueOverwrite ( ) ; 
xQueueSendFromISR ( ) ; 
xQueueSendToBackFromISR ( ) ; 
xQueueSendToFrontFromISR ( ) ; 
xQueueOverwriteFromISR ( ) ; 
# define  函数名	xQueueGenericSend ( ( xQueue) , ( pvItemToQueue) , ( xTicksToWait) , 位置)  # define  queueSEND_TO_BACK 		( ( BaseType_t) 0 ) # define  queueSEND_TO_FRONT 		( ( BaseType_t) 1 ) # define  queueOVERWRITE 			( ( BaseType_t) 2 ) xQueueReceive ( ) ; 
xQueuePeek ( ) ; 
xQueueReceiveFromISR ( ) ; 
xQueuePeekFromISR ( ) ; 
BaseType_t xQueueReceive ( QueueHandle_t xQueue, void  * const  pvBuffer, TickType_t xTicksToWait) 
BaseType_t xQueuePeek ( QueueHandle_t xQueue, void  * const  pvBuffer, TickType_t xTicksToWait) 
创建四个任务 start_task :创建task1、task2和task3task1 :当按键key0或key1按下,将按键键码拷贝到队列key_queue(入队 ),当key2按下,将传输大数据 ,拷贝大数据内容到队列big_data_queue 里task2 :读取队列key_queue中的消息(出队 ),打印出接收的键值task3 :从队列big_data_queue读取大数据 地址,通过地址访问大数据# define  configSUPPORT_DYNAMIC_ALLOCATION 					1 # define  INCLUDE_vTaskSuspend 								1 # define 	START_TASK_STACK_SIZE  								128 # define 	START_TASK_PRIO 										1 ; 							
# define 	TASK1_STACK_SIZE  									128 # define 	TASK1_PRIO 											2 ; 								
# define 	TASK2_STACK_SIZE  									128 # define 	TASK2_PRIO 											3 ; 								
# define 	TASK3_STACK_SIZE  									128 # define 	TASK3_PRIO 											4 ; 								
QueueHandle_t key_queue; 
QueueHandle_t big_key_queue; 
char  buff[ ]  =  "hello world" ; 
void  task1 (  void  *  pvParameters ) 
{ 
		uint8_t  KeyNum =  0 ; 
		char  * buf; 
		buf =  buff; 
		BaseType_t err =  0 ; 
		while ( 1 ) 
		{ 
			KeyNum =  Key_GetNum ( ) ; 
			if ( KeyNum== 0  ||  KeyNum== 1 ) 
			{ 
				err =  xQueueSend ( key_queue, & KeyNum, portMAX_DELAY) ; 
			} 
			else  if ( KeyNum ==  2 ) 
			{ 
				err =  xQueueSend ( big_date_queue, & buf, portMAX_DELAY) ; 
			} 
			vTaskDelay ( 10 ) ; 
		} 
} 
void  task2 (  void  *  pvParameters ) 
{ 
		uint8_t  KeyNum =  0 ; 
		BaseType_t err =  0 ; 
		while ( 1 ) 
		{ 
			err =  xQueueReceive ( key_queue, & keyNum, portMAX_DELAY) ; 
		} 
} 
void  task3 (  void  *  pvParameters ) 
{ 
		char  * buf; 
		BaseType_t err =  0 ; 
		while ( 1 ) 
		{ 
			err =  xQueueReceive ( big_date_queue, & buf, portMAX_DELAY) ; 
		} 
} 
void  Start_task (  void  *  pvParameters ) 
{ 
		taskENTER_CRITICAL ( ) ; 
		
		xTaskCreate ( task1, 
					"task1" , 
					TASK1_STACK_SIZE, 
					NULL , 
					TASK1_PRIO, 
					& task1_handle
					) ; 
		
		xTaskCreate ( task2, 
					"task2" , 
					TASK2_STACK_SIZE, 
					NULL , 
					TASK2_PRIO, 
					& task2_handle
					) ; 
		
		xTaskCreate ( task3, 
					"task3" , 
					TASK3_STACK_SIZE, 
					NULL , 
					TASK3_PRIO, 
					& task3_handle
					) ; 
		vTaskDelete ( start_task_handle) ; 
		
		taskEXIT_CRITICAL ( ) ; 
} 
void  freertos_demo ( ) 
{ 
		key_queue =  xQueueCreate ( 2 , sizeof ( uint8_t ) ) ; 
		big_date_queue =  xQueueCreate ( 1 , sizeof ( char * ) ) ; 
		xTaskCreate ( Start_task, 
					"Start_task" , 
					START_TASK_STACK_SIZE, 
					NULL , 
					START_TASK_PRIO, 
					& start_task_handle
					) ; 
		vTaskStartScheduler ( ) ; 
}