基于STM32F407的FreeRTOS学习笔记(5)——消息队列(任务间通信与同步)

图片

在数据结构中有一种很重要的数据结构叫做队列,其特点是数据先进先出。在FreeRTOS中也有一类队列,我们利用这类队列在FreeRTOS中实现任务与任务间的消息传递,所以也可以称之为消息队列。

队列是任务间通信的主要形式。它们可以用于在任务之间以及中断和任务之间发送消息。在大多数情况下,它们作为线程安全的 FIFO(先进先出)缓冲区使用,新数据被发送到队列的后面, 尽管数据也可以发送到前面。(拷贝自FreeRTOS开发者文档)

图片

队列通过这样子的结构在任务间单方向传递消息。

在FreeRTOS的API引用文档中我们可以看到队列的控制函数。

图片

我们在文档中找到队列创建函数(动态)

图片

首先我们需要在程序中包含入queue.h文件才能使用队列。

其次和之前几期的操作一样,我们需要在FreeRTOSConfig.h文件中需要配置相对应的宏以激活该创建队列的构造函数。

xQueueCreate的参数有两个,首先是uxQueueLength队列可同时容纳的最大项目数简而言之也就是:这个队列有多长。

其次是uxItemSize,顾名思义是每一个项目(每个小块块)能存储多少数据(字节)

最后要强调的是,这个函数的返回值是QueueHandle_t,即以句柄的形式返回,因此我们创建任务的时候也需要以句柄变量接收其返回值。

图片




图片

我们在启动函数中加入我们创建队列的函数,其长度为1,每个项目的大小为一个字节。

图片

我们接着在API引用文档中找到关于队列发送的函数(如上)。

发送的函数平平无奇,但是有几点需要注意;

首先是发布项目按副本排队而不是引用指针,指的是我们传入的数据是先拷贝的临时变量传入,而并非我们传入数据的地址,我想这样子是为了避免在接收端时对数据进行修改导致错误。

其次是该函数不能在中断函数中调用(有专门的函数是在中断中发布项目的)

函数参数中的第三项xTicksWait简单的理解就是可等待的最大时间,我们如果我们的队列已满则尝试等待,超过一定周期认为超时则项目发布失败。

我们在按钮检测任务中编写:按下按钮2时向队列中放入字符p(p初始值为‘a’),每按下这个按钮,p的值递增。

还有一个按钮3,按下按钮3则在队列中读取一则消息,并打印出来。

void Get_info(void * pvParameters){  unsigned char p = 'a';    unsigned char r;  while(1)  {        unsigned char key = KEY_Scan(0);    BaseType_t err;    if(key==1)    {      memset(informationbuff,0,400);      vTaskGetRunTimeStats(informationbuff);      printf("%s\r\n",informationbuff);    }        if(key==2)    {      printf("Key_2 Press\r\n");      if(KeyNumberHandler!=NULL)//队列句柄有效      {                err = xQueueSend(KeyNumberHandler,&p,10);        p++;        if(err!=pdTRUE)        {          printf("Send Fail \r\n");                  }        else        {          printf("Send %c Success\r\n",p);                  }              }    }    if(key==3)    {      printf("Key 3 Press\r\n");      if(KeyNumberHandler!=NULL)//队列句柄有效      {                xQueueReceive(KeyNumberHandler,&r,10);        printf("Queue Receive:%c \r\n",r);        r = '\0';//清空      }    }    vTaskDelay(10);  }}

我们在按钮检测任务中加入按钮2和按钮3的情况,并且定义了一个变量err来检测我们的队列是否添加成功,我们观察串口并看看打印情况。

可以看到,我们按下按钮2,成功将 ‘b’ 消息送入队列(我们是先p++再送入队列的)

图片

我们再继续按下按钮2,由于队列的长度为1,且队列的项目并没有出队列,因此串口会提示送入队列失败。

图片

此时p等于 ' c ',我们按下按钮3,让数据出队列,并且再按下一次按钮3读取是否有数据。 

可以看到,读取队列之后队列的内容将被释放,后续的内容将前进。之后我们再按下按钮2 ,此时就可以向队列中送入数据(我多按了一下)。

图片

除此之外,FreeRTOS中还有一个函数为xQueueOverwrite,传入参数除了没有阻塞时间之外和xQueueSend一样,它的作用为将消息送入队列,如果没有空间则覆盖最后一个空间,我们将按钮2中的函数换为该函数再试试。

图片

我们每次送入队列都成功,因为它会把队列的最后一个项目覆盖掉。

关于队列的介绍就到此啦,具体的API可以上FreeRTOS的官网查看参考文档。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值