良许Linux教程网 干货合集 FreeRTOS 任务间通信,怎么实现?

FreeRTOS 任务间通信,怎么实现?

FreeRTOS是一个灵活可裁剪、可抢占的多任务内核,非常易用,并且没有任务数量的限制。在之前的分析中,我们已经讨论了很多内容,简单来说,FreeRTOS实时操作系统可以创建多个独立的任务,并且这些任务之间相互独立,互不干扰。为了实现这一点,每个任务都需要有自己的堆栈空间。当任务切换时,执行环境会保存到该任务的堆栈中,这样当一段时间后再切换回该任务时,它能够准确地恢复到上次工作的状态。

之前我们也整理了一些教程,可以参考精选汇总 | freertos从基础到高级篇系列

FreeRTOS提供了实时操作系统所需的所有功能,包括资源管理、同步、任务通信等。本文主要介绍任务通信,创建的任务并不是同时运行的,而是根据优先级顺序进行任务调度。

此外,我们还可以直接使用一些现成的轮子,例如ARM Cortex微控制器的软件接口标准CMSIS。CMSIS-RTOS是实时操作系统的通用API,它是与供应商无关的硬件抽象层。简而言之,它是对FreeRTOS、RtThread等操作系统进行进一步封装,形成通用的API函数,以方便移植。在这里,我们选择使用的是CMSIS_V2接口。之前我们也讨论过stm32CubeIDE中CMSIS_V1和CMSIS_V2选项的区别

image-20240105193159509
image-20240105193159509

首先创建两个任务myTask01和myTask02,如下图所示:

image-20240105193203896
image-20240105193203896

创建2个事件myEvent01,myEvent02,如下图所示:

image-20240105193208156
image-20240105193208156

拉下来也可以配置以下信息,在此我们默认配置计数信号量、分配方式、控制块名称等配置信息。

生成代码之后任务和事件如下代码:

/* Definitions for myTask01 */
osThreadId_t myTask01Handle;
const osThreadAttr_t myTask01_attributes = {
  .name = "myTask01",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
...
/* Definitions for myEvent02 */
osEventFlagsId_t myEvent02Handle;
const osEventFlagsAttr_t myEvent02_attributes = {
  .name = "myEvent02"
};

这个是创建任务的句柄,代码如下:

  /* creation of myTask01 */
  myTask01Handle = osThreadNew(StartTask01, NULL, &myTask01_attributes);

  /* creation of myTask02 */
  myTask02Handle = osThreadNew(StartTask02, NULL, &myTask02_attributes);

我们改写代码,实现task2往task发送信号,实现简单的任务通信,代码如下。

/* USER CODE END Header_StartTask01 */
void StartTask01(void *argument)
{
    /* USER CODE BEGIN StartTask01 */
    /* Infinite loop */
    osStatus_t os_Status;

   while(1)
   {
    os_Status = osEventFlagsWait(myTask02Handle,   /* 事件标志组ID */
            COMM2_EVENT,       /* 等待事件标志位0与事件标志位1 */
            osFlagsWaitAny,    /* 逻辑或 */
               osWaitForever      /* 一直等待 */
            );
    if(os_Status == COMM1_EVENT)
    {
       printf("startTask02 is running.\r\n");
    }
   }
    /* USER CODE END StartTask01 */
}

/* USER CODE BEGIN Header_StartTask02 */

osEventFlagsWait函数的具体实现以及定义如下图所示:

image-20240105193212873
image-20240105193212873

osEventFlagsSet就是往某个任务的句柄发送一个信号,实现如下

/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 for(;;)
 {
   osEventFlagsSet(myEvent01Handle, COMM1_EVENT);
   osDelay(1);
 }
 /* USER CODE END StartTask02 */
}

最后就可以实现多个任务间的通信了。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300

本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部