热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FreeRTOS消息队列总结

一、消息队列的应用场景消息队列可以应用于发送不定长消息的场合;队列是FreeRTOS主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息&#x

一、消息队列的应用场景

        消息队列可以应用于发送不定长消息的场合;队列是FreeRTOS 主要的任务间通讯方式,可以在任务与任务间、中断和任务间传送信息;

二、消息队列相关的函数

1、xQueueCreate()       //动态创建消息队列函数

2、xQueueCreateStatic()         //静态创建消息队列函数

3、vQueueDelete()        //消息队列删除函数

4、xQueueSend()        //向队列尾部发送一个队列消息

5、xQueueSendToBack()        //向队列尾部发送一个队列消息  等同于4

6、xQueueSendToFront()        //向队列头部发送一个消息

7、xQueueSendFromISR()        //向队列头部发送一个消息  用在中断中

8、xQueueSendToBackFromISR()              //向队列头部发送一个消息  用在中断中 等同于7

9、xQueueGenericSend()           //发送消息函数的原型

 

10、xQueueReceive()        //从一个队列中接收消息并把消息从队列中删除 决不能再中断中使用

11、xQueuePeek()           //从一个队列中接收消息 把消息从队列中删除

12、xQueueReceiveFromISR ()      //从一个队列中接收消息并把消息从队列中删除 用在中断中

13、xQueuePeekFromISR()        //从一个队列中接收消息 把消息从队列中删除 用在中断中

14、xQueueGenericReceive()        //接收消息函数的原型

三、注意事项

1、必须在FreeRTOSConfig.h 把 configSUPPORT_DYNAMIC_ALLOCATION 定义为 1。

2、队列是内核对象,具有自己独立权限;

3、如果消息过于庞大,可以将消息的地址作为消息进行发送、接收。

4、获取队列消息时,要定义一个大于或等于消息的大小。

5、队列读取采用的是先进先出(FIFO)模式,也支持后进先出(LIFO)模式

四、实验数据

//FreeRTOS 库
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"//硬件库
#include "stm32f10x.h"
#include "bsp_usart.h"//C库
#include
#include
#include
/******************** 说 明 ************************
任务优先级: 数值越大 优先级高
****************************************************/
//堆栈大小
#define AppTaskCreate_Size 512 //创建任务的堆栈大小
#define ReceiveTask_Size 512 // 堆栈大小
#define SendTask_Size 512//任务优先级 priority
#define AppTaskCreate_priority 1
#define ReceiveTask_priority 2
#define SendTask_priority 3//申请任务句柄
static TaskHandle_t AppTaskCreate_Handle = NULL;
static TaskHandle_t Receive_Task_Handle = NULL;
static TaskHandle_t SendTask_Handle = NULL;//内核对象句柄
QueueHandle_t Test_Queue =NULL;#define QUEUE_LEN 4 //队列的长度
#define QUEUE_SIZE 1 //队列中每个消息的大小//全局变量 串口部分
extern u8 USART1_BUFF[64];
extern u16 USART1_ReceiveLength;
extern u8 USART1_ReceiveEndFlag;//任务声明
static void AppTaskCreate(void); //用于创建任务
static void Receive_Task(void* pvParameters);//LED 任务的实现
static void Send_Task(void* pvParameters);static void BSP_Init(void);//用于初始化板载相关资源/******************主函数***********************/
int main(void)
{ BaseType_t xReturn = pdPASS;BSP_Init();printf(" usart send 1 or 2. task send queue data \r\n");printf(" Receive task receive data in usart displey \r\n");xReturn =xTaskCreate((TaskFunction_t ) AppTaskCreate, //任务函数入口(const char* ) "AppTaskCreate", //任务名字(uint16_t ) AppTaskCreate_Size, //任务栈大小(void* ) NULL, //任务入口函数参数(UBaseType_t ) AppTaskCreate_priority, //任务优先级(TaskHandle_t* ) &AppTaskCreate_Handle); //任务控制块指针//启动任务调度if(pdPASS == xReturn)vTaskStartScheduler();//启动任务调度elsereturn -1;while(1);//正常 不会执行到这里
}
//创建任务
static void AppTaskCreate(void)
{BaseType_t xReturn = pdPASS;taskENTER_CRITICAL();//进入临界区//创建 消息队列 Test_QueueTest_Queue =xQueueCreate((UBaseType_t )QUEUE_LEN,(UBaseType_t )QUEUE_SIZE);if(NULL != Test_Queue)printf("Create Test_Queue data queue ok!\r\n");xReturn = xTaskCreate((TaskFunction_t ) Receive_Task, //任务函数(const char*) "Receive_Task", //任务名称(uint32_t ) ReceiveTask_Size, //任务堆栈大小(void* ) NULL, //传递给任务函数的参数(UBaseType_t ) ReceiveTask_priority, //任务优先级(TaskHandle_t*) &Receive_Task_Handle); //任务控制块if(pdPASS == xReturn )printf("Receive_Task 创建任务成功\r\n");xReturn = xTaskCreate((TaskFunction_t ) Send_Task, //任务函数(const char*) "Send_Task", //任务名称(uint32_t ) SendTask_Size, //任务堆栈大小(void* ) NULL, //传递给任务函数的参数(UBaseType_t ) SendTask_priority, //任务优先级(TaskHandle_t*) &SendTask_Handle); //任务控制块if(pdPASS == xReturn )printf("Send_Task 创建任务成功\r\n");vTaskDelete(AppTaskCreate_Handle);taskEXIT_CRITICAL();
}//接收打印任务
static void Receive_Task(void* parameter)
{BaseType_t xReturn = pdTRUE;//定义一个创建信息返回值,默认为pdTRUEu8 r_queue;//定义一个接收消息的变量while(1){xReturn = xQueueReceive(Test_Queue, //消息队列的句柄&r_queue, //发送的消息内容portMAX_DELAY);//等待时间 一直等if(pdTRUE == xReturn)printf("Receive data is %d\r\n\r\n",r_queue);elseprintf("Data receive error:0x%1x \r\n",xReturn);}
}
//发送任务
static void Send_Task(void* pvParameters)
{BaseType_t xReturn = pdPASS;//定义一个创建信息返回值u8 sendData1 = 1;u8 sendData2 = 2;while(1){if(USART1_ReceiveEndFlag == USART1ReceiveOk){if(strstr((const char *)USART1_BUFF,"1") != NULL){printf("send data is sendData1\r\n");xReturn = xQueueSend(Test_Queue,&sendData1,0);if(pdPASS == xReturn)printf("send sendData1 data OK!\r\n\r\n");}else if(strstr((const char *)USART1_BUFF,"2") != NULL){printf("send data is sendData2\r\n");xReturn = xQueueSend(Test_Queue,&sendData2,0);if(pdPASS == xReturn)printf("send sendData2 data OK!\r\n\r\n ");}else{printf("Please enter 1 or 2! \r\n");}USART1_ReceiveEndFlag=0; //清标志位USART1_ReceiveLength =0; //清长度memset(USART1_BUFF, 0, sizeof(USART1_BUFF));//清缓存}vTaskDelay(20);// 延时 20 个 tick }
}
//硬件初始化函数
static void BSP_Init(void)
{NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );USART_Config();
} // 串口中断服务函数
u8 USART1_BUFF[64];
u16 USART1_ReceiveLength;
u8 USART1_ReceiveEndFlag=0;
void DEBUG_USART_IRQHandler(void)
{uint8_t ucTemp;if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET){ ucTemp = USART_ReceiveData(DEBUG_USARTx);USART1_BUFF[USART1_ReceiveLength]=ucTemp;if(USART1_BUFF[USART1_ReceiveLength]== 0x0a)//\n{if(USART1_BUFF[USART1_ReceiveLength-1] == 0x0d)//\r{USART1_ReceiveEndFlag=USART1ReceiveOk;//接收完成} }else{++USART1_ReceiveLength;}//USART_SendData(DEBUG_USARTx,ucTemp); }
}

 


推荐阅读
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • BZOJ1233 干草堆单调队列优化DP
    本文介绍了一个关于干草堆摆放的问题,通过使用单调队列来优化DP算法,求解最多可以叠几层干草堆。具体的解题思路和转移方程在文章中进行了详细说明,并给出了相应的代码示例。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 本文介绍了SPOJ2829题目的解法及优化方法。题目要求找出满足一定条件的数列,并对结果取模。文章详细解释了解题思路和算法实现,并提出了使用FMT优化的方法。最后,对于第三个限制条件,作者给出了处理方法。文章最后给出了代码实现。 ... [详细]
  • 本文介绍了如何通过维持两个堆来获取一个数据流中的中位数。通过使用最大堆和最小堆,分别保存数据流中较小的一半和较大的一半数值,可以保证两个堆的大小差距为1或0。如果数据流中的数量为奇数,则中位数为较大堆的最大值;如果数量为偶数,则中位数为较大堆的最大值和较小堆的最小值的平均值。可以使用优先队列来实现堆的功能。本文还提供了相应的Java代码实现。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
author-avatar
吾爱九-九九
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有