基于STM32F407的FreeRTOS学习笔记(5)

描述

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

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

STM32F407

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

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

STM32F407

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

STM32F407

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

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

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

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

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

STM32F407
STM32F407

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

STM32F407

我们接着在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("%srn",informationbuff);
    }

    if(key==2)
    {
      printf("Key_2 Pressrn");
      if(KeyNumberHandler!=NULL)//队列句柄有效
      {

        err = xQueueSend(KeyNumberHandler,&p,10);
        p++;
        if(err!=pdTRUE)
        {
          printf("Send Fail rn");

        }
        else
        {
          printf("Send %c Successrn",p);

        }

      }
    }
    if(key==3)
    {
      printf("Key 3 Pressrn");
      if(KeyNumberHandler!=NULL)//队列句柄有效
      {

        xQueueReceive(KeyNumberHandler,&r,10);
        printf("Queue Receive:%c rn",r);
        r = '�';//清空
      }
    }
    vTaskDelay(10);
  }
}

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

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

STM32F407

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

STM32F407

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

STM32F407

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

STM32F407

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

STM32F407

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

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

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分