> 文档中心 > Bearpi开发板之HarmonyOS定时器管理

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 #include #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 #include #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);
  • 编译烧录运行
    Bearpi开发板之HarmonyOS定时器管理

WIFI共享精灵