# FreeRTOS_消息队列 **Repository Path**: wang-jialll/free-rtos-queue ## Basic Information - **Project Name**: FreeRTOS_消息队列 - **Description**: 消息队列学习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-08-30 - **Last Updated**: 2022-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: FreeRTOS ## README # 消息队列 ​ 队列又称消息队列,是一种常用于任务间通信的数据结构, 队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。 当队列中有新消息时, 被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。 消息队列是一种异步的通信方式。 ​ 通过消息队列服务,任务或中断服务例程可以将一条或多条消息放入消息队列中。同样,一个或多个任务可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常是将先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO),但是也支持后进先出原则(LIFO) 。 # 消息队列的运作机制 1. **创建消息**队列时 FreeRTOS 会先给消息队列分配一块内存空间,这块内存的大小等于 消息队列控制块大小加上(单个消息空间大小与消息队列长度的乘积) ,接着再初始化消息队列,此时消息队列为空。 2. 任务或者中断服务程序都可以给消息队列发送消息, 当发送消息时, 如果队列未满或者允许覆盖入队, FreeRTOS 会将消息拷贝到消息队列队尾,否则,会根据用户指定的阻塞超时时间进行**阻塞**,在这段时间中,如果队列一直不允许入队,该任务将保持阻塞状态以等待队列允许入队。**优先级高的先获得控制权。** 3. 当消息队列不再被使用时,**应该删除它以释放系统资源**,一旦操作完成,消息队列将被永久性的删除。 # 消息队列的应用场景 消息队列可以应用于发送不定长消息的场合,包括任务与任务间的消息交换,队列是 FreeRTOS 主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息,发送到队列的消息是通过拷贝方式实现的, 这意味着队列存储的数据是原数据,而不是原数据的引用。 # ->代码说明------------ ## 创建消息队列 xQueueCreate()函数说明 ```C QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize ); ``` `uxQueueLength`:队列能够存储的最大消息单元数目,即队列长度。 `uxItemSize`:队列中消息单元的大小,以字节为单位。 返回值:如果创建成功则返回一个队列句柄,用于访问创建的队列。 如果创建不成功则返回NULL, 可能原因是创建队列需要的 RAM 无法分配成功。 ## 发送消息 ```C 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); } } ``` ## 接收消息 ```C 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); } } ``` # 结论 消息队列和创建任务的逻辑差不多。 创建消息句柄,利用`xQueueReceive`和`xQueueSend`即可实现对消息队列消息的发送接收 # vscode快捷键 `Ctrl+Shift+o`可查看文件中的函数