Hi3861 OpenHarmony嵌入式应用入门--LiteOS Timer

LiteOS Timer(定时器)是LiteOS操作系统中的一个重要组件,它提供了一种基于软件模拟的定时器功能,用于满足在硬件定时器数量不足时的定时需求。

软件定时器:基于系统Tick时钟中断,由软件来模拟的定时器。当经过设定的Tick时钟计数值后,会触发用户定义的回调函数。

定时精度:与系统Tick时钟周期有关。

功能:包括静态裁剪、软件定时器创建、启动、停止、删除、剩余Tick数获取等。

资源使用:软件定时器使用了系统的一个队列和一个任务资源。

触发规则:遵循队列规则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。

基本计时单位:以Tick为基本计时单位。

当用户创建并启动一个软件定时器时,LiteOS会根据当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。

当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时。

若有超时的定时器,则记录下来,并在Tick中断处理函数结束后唤醒软件定时器任务(优先级最高)。

在软件定时器任务中调用之前记录下来的定时器的超时回调函数。

支持的定时器模式

单次触发定时器:启动后只会触发一次定时器事件,然后定时器自动删除。

周期触发定时器:周期性地触发定时器事件,直到用户手动停止定时器。

单次触发但不自动删除定时器:超时触发后不会自动删除,需要调用定时器删除接口删除定时器。

Timer API

|------------------|--------------|
| API名称 | 说明 |
| osTimerNew | 创建和初始化定时器 |
| osTimerGetName | 获取指定的定时器名字 |
| osTimerStart | 启动或者重启指定的定时器 |
| osTimerStop | 停止指定的定时器 |
| osTimerIsRunning | 检查一个定时器是否在运行 |
| osTimerDelete | 删除定时器 |

函数介绍

osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)

参数

|----------|---------------------------------------------|
| 名字 | 描述 |
| func | 定时器回调函数. |
| type | 定时器类型,osTimerOnce表示单次定时器,ostimer周期表示周期性定时器. |
| argument | 定时器回调函数的参数 |
| attr | 定时器属性 |

代码编写

修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件

# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#    http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. 

import("//build/lite/config/component/lite_component.gni")

lite_component("demo") {
  features = [
    #"base_00_helloworld:base_helloworld_example",
    #"base_01_led:base_led_example",
    #"base_02_loopkey:base_loopkey_example",
    #"base_03_irqkey:base_irqkey_example",
    #"base_04_adc:base_adc_example",
    #"base_05_pwm:base_pwm_example",
    #"base_06_ssd1306:base_ssd1306_example",
    #"kernel_01_task:kernel_task_example",
    "kernel_02_timer:kernel_timer_example",
  ]
}

创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_02_timer文件夹

文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_02_timer\kernel_timer_example.c文件D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_02_timer\BUILD.gn文件

# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. 

static_library("kernel_timer_example") {
    sources = [
        "kernel_timer_example.c",
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/kal/cmsis",
        "//base/iot_hardware/peripheral/interfaces/kits",
        "//vendor/hqyj/fs_hi3861/common/bsp/include"
    ]
}

/*
 * Copyright (C) 2023 HiHope Open Source Organization .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

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

#define STACK_SIZE      (1024)
#define DELAY_TICKS_100 (100)
#define TEST_TIMES      (3)
static int times = 0;

void cb_timeout_periodic(void)
{
    times++;
}

void timer_periodic(void)
{
    osTimerId_t periodic_tid = osTimerNew(cb_timeout_periodic, osTimerPeriodic, NULL, NULL);
    if (periodic_tid == NULL) {
        printf("[Timer Test] osTimerNew(periodic timer) failed.\r\n");
        return;
    } else {
        printf("[Timer Test] osTimerNew(periodic timer) success, tid: %p.\r\n", periodic_tid);
    }
    osStatus_t status = osTimerStart(periodic_tid, DELAY_TICKS_100);
    if (status != osOK) {
        printf("[Timer Test] osTimerStart(periodic timer) failed.\r\n");
        return;
    } else {
        printf("[Timer Test] osTimerStart(periodic timer) success, wait a while and stop.\r\n");
    }

    while (times < TEST_TIMES) {
        printf("[Timer Test] times:%d.\r\n", times);
        osDelay(DELAY_TICKS_100);
    }

    status = osTimerStop(periodic_tid);
    printf("[Timer Test] stop periodic timer, status :%d.\r\n", status);
    status = osTimerDelete(periodic_tid);
    printf("[Timer Test] kill periodic timer, status :%d.\r\n", status);
}

static void TimerTestTask(void)
{
    osThreadAttr_t attr;

    attr.name = "timer_periodic";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)timer_periodic, NULL, &attr) == NULL) {
        printf("[TimerTestTask] Falied to create timer_periodic!\n");
    }
}
APP_FEATURE_INIT(TimerTestTask);

代码分析

定时器的回调函数

void cb_timeout_periodic(void *arg) {
    (void)arg;
    times++;
}

使用osTimerNew创建一个100个时钟周期调用一次回调函数cb_timeout_periodic定时器,每隔100个时钟周期检查一下全局变量times是否小于3,若不小于3则停止时钟周期

void timer_periodic(void)
{
    // 创建一个周期性定时器
    osTimerId_t periodic_tid = osTimerNew(cb_timeout_periodic, osTimerPeriodic, NULL, NULL);
    // 如果创建失败,打印错误信息
    if (periodic_tid == NULL) {
        printf("[Timer Test] osTimerNew(periodic timer) failed.\r\n");
        return;
    // 如果创建成功,打印成功信息
    } else {
        printf("[Timer Test] osTimerNew(periodic timer) success, tid: %p.\r\n", periodic_tid);
    }
    // 启动周期性定时器,延时100个tick
    osStatus_t status = osTimerStart(periodic_tid, DELAY_TICKS_100);
    // 如果启动失败,打印错误信息
    if (status != osOK) {
        printf("[Timer Test] osTimerStart(periodic timer) failed.\r\n");
        return;
    // 如果启动成功,打印成功信息
    } else {
        printf("[Timer Test] osTimerStart(periodic timer) success, wait a while and stop.\r\n");
    }

    // 循环等待测试次数达到
    while (times < TEST_TIMES) {
        // 打印测试次数
        printf("[Timer Test] times:%d.\r\n", times);
        // 延时100个tick
        osDelay(DELAY_TICKS_100);
    }

    // 停止周期性定时器
    status = osTimerStop(periodic_tid);
    // 打印停止状态
    printf("[Timer Test] stop periodic timer, status :%d.\r\n", status);
    // 删除周期性定时器
    status = osTimerDelete(periodic_tid);
    // 打印删除状态
    printf("[Timer Test] kill periodic timer, status :%d.\r\n", status);
}

使用build,编译成功后,使用upload进行烧录。

相关推荐
qq_459730032 小时前
4-3 MCU中ARM存储器的作用
arm开发·单片机·嵌入式硬件
重生之我是数学王子5 小时前
点亮核心板小灯 STM32U575
stm32·单片机·嵌入式硬件
end_SJ5 小时前
初学stm32 --- 定时器中断
stm32·单片机·嵌入式硬件
南城花随雪。6 小时前
单片机:实现数码管动态显示(0~99999999)74hc138驱动(附带源码)
单片机·嵌入式硬件
南城花随雪。8 小时前
单片机:实现信号发生器(附带源码)
单片机·嵌入式硬件
三月七(爱看动漫的程序员)10 小时前
HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录
人工智能·单片机·嵌入式硬件·物联网·机器学习·语言模型·自然语言处理
新晨单片机设计11 小时前
【087】基于51单片机智能宠物喂食器【Proteus仿真+Keil程序+报告+原理图】
嵌入式硬件·51单片机·proteus·宠物·ad原理图
大风起兮1211 小时前
STM32HAL库中RTC闹钟设置时分秒,年月日
stm32·嵌入式硬件
超能力MAX12 小时前
IIC驱动EEPROM
单片机·嵌入式硬件·fpga开发
QQ54717605212 小时前
stm32实现回调功能
stm32·单片机·嵌入式硬件