消息队列

什么是消息队列?消息队列可以分别分开理解,我们首先理解什么是消息?我们经常使用微信来发消息,那消息是发给谁?可能消息是发给你的朋友,你的朋友也可以发消息给你,
所以消息队列就类似于微信的作用,提供一个发送消息的渠道。在freeRTOS中发消息的双方可能是任务1和任务2,也可能是驱动发消息给任务。
那什么是队列,队列就是类似一个两端有开口的管子,我们从一个管子的一头扔两个球进去,先扔进去的球总是比后面扔进去的球先出来,简单来说就是先进的先出。
,队列也是类似,我们有个任务1把要发的消息放到队列中,任务2从消息队列中取出消息,先发送的消息总是先能取到,这就是消息队列。
综合来说消息队列就是操作系统给任务和任务之间或者任务和驱动之间提供的一种通讯的手段。

基本函数

xQueueCreate   //建立一个消息队列
xQueueSend     //往消息队列中发送一个消息
xQueueReceive  //从消息队列中取出一个消息

xQueueCreate

//xQueueCreate在这里是一个宏定义,实际上是使用xQueueGenericCreate这函数
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )

//xQueueGenericCreate定义的原型
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType )

QueueHandle_t: 返回值,如果成功建立新的队列,返回队列的handle,如果不成功返回NULL
const UBaseType_t uxQueueLength:队列可以最多可以保存多少个消息
const UBaseType_t uxItemSize:每个消息的长度
const uint8_t ucQueueType:消息队列的类型,我们这里选择queueQUEUE_TYPE_BASE这个宏

一个消息队列的使用例子

struct AMessage    //自定义一个消息的类型
 {
	char ucMessageID;
	char ucData[ 20 ];
 };

 void vATask( void *pvParameters )
 {
    QueueHandle_t xQueue1, xQueue2;    //用来保存返回的消息队列的handle

	//建立消息队列1,这个队列可以保存10个消息,每个消息的大小为4个字节,这里的uint32_t类型占用个字节
	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
	if( xQueue1 == NULL )
	{
		//如果返回的handle是空的(NULL),则表示无法建立消息队列,这里打印出错误log
	}

	//建立消息队列2,这个队列可以保存10个消息,每个消息的大小为sizeof( struct AMessage * )个字节,
	//因为指针都是占用4个字节,所以每个消息也是占用4字节。
	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
	if( xQueue2 == 0 )
	{
		//如果返回的handle是空的(NULL),则表示无法建立消息队列,这里打印出错误log
	}

 }

xQueueSend

xQueueSend是一个宏定义,原型其实是xQueueGenericSend
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )

//发送消息队列的真实函数
BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
                              const void * const pvItemToQueue,
                              TickType_t xTicksToWait, 
                              const BaseType_t xCopyPosition ) 
BaseType_t:返回值类型,返回0表示发送失败
QueueHandle_t xQueue:消息队列的handle,在建立消息队列的时候生成
const void * const pvItemToQueue:指向我们要发送的消息地址
TickType_t xTicksToWait:如果消息队列非空,等待多少时间到消息队列非空,如果在等待时间内消息队列空了,消息成功发送,
如果等待时间到了,队列还是非空,则消息发送失败。
const BaseType_t xCopyPosition:这里使用queueSEND_TO_BACK,我们可以先不关心这个是什么意思

xQueueReceive

//函数原型
BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )

QueueHandle_t xQueue:消息队列的handle,类似我们说的“账号”,一个handle代表一个队列,handle在建立队列的时候生成。
void * const pvBuffer:如果能获取到消息指向我们获取到的消息的地址。简单来说就是保存获取到的消息。
TickType_t xTicksToWait:如果消息队列不为空,我们马上就能读取到消息,函数直接返回了。但是消息为空的时候,我们可以等待消息的到来, 
TickType_t xTicksToWait就是我们设置的等待消息的时长,如果不愿意等待传入为0,如果愿意等待传入非0值,这时候等待消息的任务会挂起,
直到超时或者消息队列接收到消息,任务恢复运行。