【FreeRTOS】小白进阶之如何使用FreeRTOS消息队列发送和接收数据(二)

创建两个发送队列数据任务和一个接收队列数据任务。

1、头文件声明和任务定义

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "supporting_functions.h"

static void vSenderTask( void *pvParameters );
static void vReceiverTask( void *pvParameters );

// 创建队列变量
QueueHandle_t xQueue;

typedef enum
{
	eSender1,
	eSender2
} DataSource_t;

// 数据结构
typedef struct
{
	uint8_t ucValue;
	DataSource_t eDataSource;
} Data_t;

// 要发送的队列数据
static const Data_t xStructsToSend[ 2 ] =
{
	{ 100, eSender1 },
	{ 200, eSender2 }
};

2、创建任务

int main( void )
{
    xQueue = xQueueCreate( 3, sizeof( Data_t ) );

	if( xQueue != NULL )
	{
		xTaskCreate( vSenderTask, "Sender1", 1000, ( void * ) &( xStructsToSend[ 0 ] ), 2, NULL );
		xTaskCreate( vSenderTask, "Sender2", 1000, ( void * ) &( xStructsToSend[ 1 ] ), 2, NULL );

		// 任务优先级较低,队列满时才会接收数据
		xTaskCreate( vReceiverTask, "Receiver", 1000, NULL, 1, NULL );

		vTaskStartScheduler();
	}
	
	for( ;; );
	return 0;
}

3、队列数据发送任务

static void vSenderTask( void *pvParameters )
{
    BaseType_t xStatus;
    const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );

	for( ;; )
	{
		/* The first parameter is the queue to which data is being sent.  The
		queue was created before the scheduler was started, so before this task
		started to execute.

		The second parameter is the address of the structure being sent.  The
		address is passed in as the task parameter.

		// 队列满时会 block xTicksToWait 时间长度,此时执行接收任务
		xStatus = xQueueSendToBack( xQueue, pvParameters, xTicksToWait );

		if( xStatus != pdPASS )
		{
			vPrintString( "Could not send to the queue.\r\n" );
		}
	}
}

4、队列数据接收任务

static void vReceiverTask( void *pvParameters )
{
    Data_t xReceivedStructure;
    BaseType_t xStatus;

	for( ;; )
	{
		// 队列是否满
		if( uxQueueMessagesWaiting( xQueue ) != 3 )
		{
			vPrintString( "Queue should have been full!\r\n" );
		}

		xStatus = xQueueReceive( xQueue, &xReceivedStructure, 0 );

		if( xStatus == pdPASS )
		{
			if( xReceivedStructure.eDataSource == eSender1 )
			{
				vPrintStringAndNumber( "From Sender 1 = ", xReceivedStructure.ucValue );
			}
			else
			{
				vPrintStringAndNumber( "From Sender 2 = ", xReceivedStructure.ucValue );
			}
		}
		else
		{
			vPrintString( "Could not receive from the queue.\r\n" );
		}
	}
}

 

你可能感兴趣的:(FreeRTOS系统开发)