Bearpi开发板之HarmonyOS定时器管理

软件定时器基本概念

  • 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,LiteOS操作系统提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。
  • 软件定时器功能上支持:
    ⚫ 静态裁剪:能通过宏关闭软件定时器功能。
    ⚫ 软件定时器创建。
    ⚫ 软件定时器启动。
    ⚫ 软件定时器停止。
    ⚫ 软件定时器删除。
    ⚫ 软件定时器剩余Tick数获取。

软件定时器运作机制

软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,Huawei LiteOS会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。

实现软件定时器创建

  • cmsis_os2的API软件定时器接口简介:
  • 创建定时器:osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
  • 启动定时器:osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks);
  • 停止定时器:osStatus_t osTimerStop (osTimerId_t timer_id);
  • 删除定时器:osStatus_t osTimerDelete (osTimerId_t timer_id);

创建一个单次定时器和一个周期性定时器

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

osStatus_t timer1_status;
osStatus_t timer2_status;

void timer1_handler(void *p)
{
  char *str = p;
 printf("timer1_handler %s\r\n",str);
}

void timer2_handler(void *p)
{
  uint32_t *cnt = p;
  printf("timer2 handler %d\r\n",*cnt);
  (*cnt)++;
  if(*cnt & 0x01)
  {
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_VALUE1);
  }
  else
  {
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_VALUE0);
  }
}

void my_led_example(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);

    osTimerId_t id = osTimerNew(timer1_handler,osTimerOnce,"timer1",NULL);
    if(id != NULL)
    {
      timer1_status = osTimerStart(id,100);  // 1s
      if(timer1_status != osOK)
      {
        printf("Timer 1 could not be started\r\n");
      }
    }

    static uint32_t cnt = 10;
    id = osTimerNew(timer2_handler,osTimerPeriodic,&cnt,NULL);
    
    if(id != NULL)
    {
      timer2_status = osTimerStart(id,50);
      if(timer2_status != osOK)
      {
        printf("Timer 2 could not be started\r\n");
      }
    }
   
    
}
SYS_RUN(my_led_example);
  • 编译烧录运行,timer1为单次,运行一次打印了timer1字符串,timer2为500毫秒周期性定时器,打印计数递增值,且LED在交替亮灭

在这里插入图片描述

  • LED闪烁效果

在这里插入图片描述

扩展实验代码

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

osStatus_t timer1_status;


void timer1_handler(void *p)
{
  uint32_t *cnt = p;
 printf("timer1_handler %d\r\n",*cnt);
}



void my_led_example(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);
    
    uint32_t cnt = 1;
    osTimerId_t id = osTimerNew(timer1_handler,osTimerOnce,&cnt,NULL);
    if(id != NULL)
    {
      timer1_status = osTimerStart(id,100);  // 1s
      if(timer1_status != osOK)
      {
        printf("Timer 1 could not be started\r\n\r\n");
      }
      else
      {
         printf("Timer 1 could be started\r\n\r\n");
      }
    }

  osDelay(50);
  timer1_status = osTimerStop(id);
  if(timer1_status != osOK)
  {
    printf("stop Timer1 failed\r\n\r\n");
  } 
  else
  {
    printf("stop Timer1 success\r\n\r\n");
  }  

  timer1_status = osTimerStart(id, 100);
  if (timer1_status != osOK)
  {
     printf("start Timer1 failed\r\n\r\n");
  } 
  else
  {
    printf("start Timer1 success\r\n\r\n");
  }
  osDelay(200U);
  timer1_status = osTimerStop(id);
  if(timer1_status != osOK)
  {
    printf("stop Timer1 failed\r\n\r\n");
  } 
  else
  {
    printf("stop Timer1 success\r\n\r\n");
  }  

  timer1_status = osTimerDelete(id);
  if(timer1_status != osOK)
  {
    printf("delete Timer1 failed\r\n\r\n");
  }
  else
  {
   printf("delete Timer1 success\r\n\r\n");
  }
    
}
SYS_RUN(my_led_example);
  • 编译烧录运行
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风雨依依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值