HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)事件管理

Posted Leung_ManWah

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)事件管理相关的知识,希望对你有一定的参考价值。

一、简介

1.1 事件基本概念

事件是一种实现任务间通信的机制,可用于实现任务间的同步,但事件通信只能是事件类型的通信,无数据传输,一个任务可以等等多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理。事件集合用32位无符号整型变量来表示,每一位代表一个事件。

多任务环境下,任务之间往往需要同步操作。事件可以提供一对多、多对多的同步操作。一对多同步模型:一个任务等待多个事件的触发;多对多同步模型:多个任务等待多个事件的触发。

任务可以通过创建事件控制块来实现对事件的触发和等待操作。LiteOS的事件仅用于任务间的同步。

1.2 事件运作机制

读事件时,可以根据入参事件掩码类型uwEventMask读取事件的单个或者多个事件类型。事件读取成功后,如果设置LOS_WAITMODE_CLR会清除已读取到的事件类型,反之不会清除已读取到的事件类型,需显式清除。可以通过入参选择读取模式,读取事件掩码类型中所有事件还是读取事件掩码类型中任意事件。

写事件时,对指定事件写入指定的事件类型,可以一次同时写多个事件类型。写事件会触发任务调度。

清除事件时,根据入参事件和待清除的事件类型,对事件对应位进行清0操作。

二、API说明

以下任务管理接口位于 kernel/liteos_m/components/cmsis/2.0/cmsis_os2.h

业务BUILD.gn中包含路径

include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
    ]

2.1 osEventFlagsNew

功能创建事件标记对象,不能在中断服务调用该函数
函数定义osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr)
参数att:事件标志属性;空:默认值
返回事件ID

2.2 osEventFlagsSet

功能设置事件标记
函数定义int32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags)
参数ef_id:事件标志由osEventFlagsNew获得的ID
flags:指定设置的标志
返回事件标记

2.3 osEventFlagsWait

功能等待事件标记触发,直到设置了由参数ef_id指定的事件对象中的任何或所有由参数flags指定的事件标志。当这些事件标志被设置,函数立即返回。否则,线程将被置于阻塞状态。
函数定义uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
参数ef_id:事件标志由osEventFlagsNew获得的ID
flags:指定要等待的标志
options:指定标记选项
timeout:超时时间,0表示不超时
返回触发事件标记

2.4 osEventFlagsDelete

功能删除事件标记对象
函数定义osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id)
参数ef_id:事件标志由osEventFlagsNew获得的ID
返回0 - 成功,非0 - 失败

三、创建及启动定时器

编译时在业务BUILD.gn中包含路径

include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
    ]

在Event_example函数中,通过osEventFlagsNew()函数创建了事件标记ID,Thread_EventReceiver()函数中通过osEventFlagsWait()函数一直将线程置于阻塞状态,等待事件标记。在Thread_EventSender()函数中通过osEventFlagsSet()函数每隔1S设置的标志,实现任务间的同步。

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#define FLAGS_MSK1 0x00000001U

osEventFlagsId_t evt_id; // event flags id

/***** 发送事件 *****/
void Thread_EventSender(void *argument)
{
  (void)argument;
  while (1)
  {
    osEventFlagsSet(evt_id, FLAGS_MSK1);

    //suspend thread
    osThreadYield();

    osDelay(100);
  }
}

/***** 接收事件 *****/
void Thread_EventReceiver(void *argument)
{
  (void)argument;
  uint32_t flags;

  while (1)
  {
    flags = osEventFlagsWait(evt_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
    printf("Receive Flags is %d\\n", flags);
  }
}

/***** 创建事件 *****/
static void Event_example(void)
{
  evt_id = osEventFlagsNew(NULL);
  if (evt_id == NULL)
  {
    printf("Falied to create EventFlags!\\n");
  }

  osThreadAttr_t attr;

  attr.attr_bits = 0U;
  attr.cb_mem = NULL;
  attr.cb_size = 0U;
  attr.stack_mem = NULL;
  attr.stack_size = 1024 * 4;
  attr.priority = 25;

  attr.name = "Thread_EventSender";
  if (osThreadNew(Thread_EventSender, NULL, &attr) == NULL)
  {
    printf("Falied to create Thread_EventSender!\\n");
  }
  attr.name = "Thread_EventReceiver";
  if (osThreadNew(Thread_EventReceiver, NULL, &attr) == NULL)
  {
    printf("Falied to create Thread_EventReceiver!\\n");
  }
}

APP_FEATURE_INIT(Event_example);

示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,会每隔1S输出一次日志。

Receive Flags is 1
Receive Flags is 1
Receive Flags is 1
Receive Flags is 1
Receive Flags is 1

• 由 Leung 写于 2021 年 7 月 4 日

• 参考:【鸿蒙2.0设备开发教程】小熊派HarmonyOS 鸿蒙·季 开发教程

以上是关于HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)事件管理的主要内容,如果未能解决你的问题,请参考以下文章

HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)信号量

HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)事件管理

HI3861学习笔记(10)——HarmonyOS(CMSIS-RTOS2)消息队列

HI3861学习笔记——HarmonyOS(CMSIS-RTOS2)软件定时器

HI3861学习笔记(11)——GPIO输出接口使用

HI3861学习笔记(12)——GPIO输入接口使用