消息队列学习

消息队列

​ 队列又称消息队列,是一种常用于任务间通信的数据结构, 队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。 当队列中有新消息时, 被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。 消息队列是一种异步的通信方式。

​ 通过消息队列服务,任务或中断服务例程可以将一条或多条消息放入消息队列中。同样,一个或多个任务可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常是将先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO),但是也支持后进先出原则(LIFO) 。

消息队列的运作机制

  1. 创建消息队列时 FreeRTOS 会先给消息队列分配一块内存空间,这块内存的大小等于
    消息队列控制块大小加上(单个消息空间大小与消息队列长度的乘积) ,接着再初始化消息队列,此时消息队列为空。
  2. 任务或者中断服务程序都可以给消息队列发送消息, 当发送消息时, 如果队列未满或者允许覆盖入队, FreeRTOS 会将消息拷贝到消息队列队尾,否则,会根据用户指定的阻塞超时时间进行阻塞,在这段时间中,如果队列一直不允许入队,该任务将保持阻塞状态以等待队列允许入队。优先级高的先获得控制权。
  3. 当消息队列不再被使用时,应该删除它以释放系统资源,一旦操作完成,消息队列将被永久性的删除。

消息队列的应用场景

消息队列可以应用于发送不定长消息的场合,包括任务与任务间的消息交换,队列是
FreeRTOS 主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息,发送到队列的消息是通过拷贝方式实现的, 这意味着队列存储的数据是原数据,而不是原数据的引用。

->代码说明------------

创建消息队列

xQueueCreate()函数说明

QueueHandle_t xQueueCreate(
              UBaseType_t uxQueueLength,
              UBaseType_t uxItemSize );

uxQueueLength:队列能够存储的最大消息单元数目,即队列长度。

uxItemSize:队列中消息单元的大小,以字节为单位。
返回值:如果创建成功则返回一个队列句柄,用于访问创建的队列。 如果创建不成功则返回NULL, 可能原因是创建队列需要的 RAM 无法分配成功。

发送消息


void Send_Task(void *parameter)
{
	BaseType_t xReturn = pdPASS;
	uint32_t send_data1 = 1;
    uint32_t send_data2 = 2;
	while (1)
	{
		
		if (Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )
		{
			printf("发送消息send_data1\r\n");
			xReturn = xQueueSend(Text_Queue,//消息队列的内容
								&send_data1,//发送的信息内容
								0           //等待时间 0
			);
			if( xReturn == pdPASS ) 
				printf("消息send_data1发送成功\r\n");

		}
		if (Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )
		{
			printf("send_data2\r\n");
			xReturn = xQueueSend(Text_Queue,//消息队列的内容
								&send_data2,//发送的信息内容
								0           //等待时间 0
			);
			if( xReturn == pdPASS ) 
				printf("消息send_data2发送成功\r\n");
		}
		vTaskDelay(20);
	}
}

接收消息

void Receive_Task(void *parameter)
{
	BaseType_t xReturn = pdTRUE;
	uint32_t r_queue;
	while (1)
	{
		xReturn = xQueueReceive(Text_Queue,  //消息队列的句柄
								&r_queue,    //接受的消息内容
								portMAX_DELAY//等待时间:一直等

		);
		if(xReturn == pdTRUE)
		  printf("Received message is %d\r\n",r_queue);
		else
		  printf("数据接收错误,错误代码0x%1x\r\n",xReturn);
	}
}

结论

消息队列和创建任务的逻辑差不多。

创建消息句柄,利用xQueueReceivexQueueSend即可实现对消息队列消息的发送接收

vscode快捷键

Ctrl+Shift+o可查看文件中的函数

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值