鸿蒙LiteOS软件定时器实战:多定时器周期性任务完整示例(源码+解析)

一、前言

在嵌入式鸿蒙(OpenHarmony LiteOS)开发中,软件定时器是实现周期性任务、延时任务、定时触发逻辑的核心内核工具,无需占用硬件定时器资源,支持创建多个定时器同时运行。

本文基于LiteOS内核API,手把手讲解软件定时器创建、启动、周期性运行的完整流程,提供可直接编译运行的标准源码,适合鸿蒙单片机开发入门学习。

哔站视频《06:RK2206 OpenHarmonyOS 鸿蒙 软件定时器与硬件定时器区别 软件定时器与任务区别 软件定时器实战》:https://www.bilibili.com/video/BV1w3546DEBS/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7

哔站视频《05:RK2206 OpenHarmonyOS 鸿蒙 什么是信号量 为什么需要信号量 代码演示》:https://www.bilibili.com/video/BV1to5W6pETF/?vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7

哔站视频《04:RK2206 OpenHarmonyOS 鸿蒙 任务实战》:https://www.bilibili.com/video/BV15R5E6JEHy/

哔站视频《03:RK2206 鸿蒙 LiteOS 如何通过控制编译选项编译不同案例》:https://www.bilibili.com/video/BV15e5J6QEGY/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7

哔站视频《02:RK2206 鸿蒙 LiteOS bin 文件 烧写》:https://www.bilibili.com/video/BV1pcRdBaEAt/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7

哔站视频《01:RK2206 鸿蒙 LiteOS ubuntu 开发环境 全程 安装配置》:https://www.bilibili.com/video/BV1nrRkBoEMR/?spm_id_from=333.1387.homepage.video_card.click&vd_source=3a9dd7a328acafb09dd1b8d05f3e2bf7

二、LiteOS软件定时器核心概念

1. 什么是软件定时器

软件定时器是基于系统时钟节拍实现的定时服务,由LiteOS内核提供,不依赖硬件外设,可创建多个独立定时器,分别设置不同超时时间和回调函数。

2. 软件定时器主要作用

  • 实现周期性任务(每隔1s、2s执行一段逻辑)
  • 实现延时触发功能
  • 替代硬件定时器,节省硬件资源
  • 多任务定时调度,简化业务逻辑

3. 核心工作模式

本文使用 LOS_SWTMR_MODE_PERIOD(周期性模式):
定时器超时后自动重启,循环执行回调函数,直到手动停止/删除。

三、软件定时器核心API函数

API函数 功能说明
LOS_SwtmrCreate 创建软件定时器,指定超时时间、模式、回调函数
LOS_SwtmrStart 启动已创建的定时器
LOS_SwtmrStop 停止正在运行的定时器
LOS_SwtmrDelete 删除定时器,释放内核资源

API参数说明

LOS_SwtmrCreate(
    timeout,        // 超时时间(单位:Tick,LiteOS默认1Tick=1ms)
    mode,           // 模式:单次/周期
    callback,       // 超时回调函数
    timerID,        // 定时器ID(输出)
    arg             // 回调函数参数
)

四、完整可运行源码



#include "los_swtmr.h"
#include "ohos_init.h"


void timer1_timeout(void *arg)
{
    printf("This is Timer1 Timeout function\n");
}


void timer2_timeout(void *arg)
{
    printf("This is Timer2 Timeout function\n");
}


void timer_example()
{
    unsigned int timer_id1, timer_id2;
    unsigned int ret;

    /* 创建定时器1:1000ms = 1s 周期性执行 */
    ret = LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_PERIOD, timer1_timeout, &timer_id1, NULL);
    if (ret == LOS_OK)
    {
        ret = LOS_SwtmrStart(timer_id1);
        if (ret != LOS_OK)
        {
            printf("start timer1 fail ret:0x%x\n", ret);
            return;
        }
    }
    else
    {
        printf("create timer1 fail ret:0x%x\n", ret);
        return;
    }

    /* 创建定时器2:2000ms = 2s 周期性执行 */
    ret = LOS_SwtmrCreate(2000, LOS_SWTMR_MODE_PERIOD, timer2_timeout, &timer_id2, NULL);
    if (ret == LOS_OK)
    {
        ret = LOS_SwtmrStart(timer_id2);
        if (ret != LOS_OK)
        {
            printf("start timer2 fail ret:0x%x\n", ret);
            return;
        }
    }
    else
    {
        printf("create timer2 fail ret:0x%x\n", ret);
        return;
    }
}

/* 系统自动初始化入口 */
APP_FEATURE_INIT(timer_example);

五、代码逻辑逐行解析

1. 头文件

  • los_swtmr.h:LiteOS软件定时器内核头文件
  • ohos_init.h:鸿蒙自动初始化模块头文件

2. 定时器回调函数

  • timer1_timeout:定时器1超时执行函数,1s执行一次
  • timer2_timeout:定时器2超时执行函数,2s执行一次

3. 定时器创建与启动流程

  1. 调用 LOS_SwtmrCreate 创建定时器
  2. 判断创建是否成功(返回LOS_OK)
  3. 调用 LOS_SwtmrStart 启动定时器
  4. 两个定时器独立运行,互不干扰

4. 自动初始化

APP_FEATURE_INIT(timer_example);
系统启动时自动执行定时器初始化,无需手动调用。

六、串口运行打印效果

在这里插入图片描述

  • Timer1:每隔1s打印一次
  • Timer2:每隔2s打印一次
  • 两个定时器周期性并发运行

七、常见注意事项

  1. 回调函数不能阻塞:不能在定时器回调里使用延时、死循环、阻塞API
  2. 回调函数要简洁:只处理快速逻辑,避免占用系统时钟
  3. 单位是毫秒:LiteOS默认配置 1 Tick = 1ms
  4. 多定时器互不影响:可同时创建N个软件定时器并行运行
  5. 必须先创建、再启动,否则定时器不会运行

八、对比分析 任务 与 软件定时器

对比项 任务(Task / 线程) 软件定时器(Software Timer)
运行方式 独立循环执行 只在超时时刻触发一次回调
能否阻塞 可以(延时、等待信号量、休眠) 绝对不能(一阻塞系统就崩溃)
优先级 可设置独立优先级 共享定时器任务优先级,不可单独设置
资源占用 较高(需要独立栈) 极低(共用栈)
执行时长 可长可短 必须极短(几ms内完成)
使用场景 大循环逻辑、复杂业务 定时计数、定时打印、定时触发标志
能否等待信号量 ✅ 可以 ❌ 不可以
能否延时 ✅ LOS_Msleep 可以 ❌ 绝对不可以

定时器回调函数 绝对不能做

  1. 不能延时(LOS_Msleep)
  2. 不能死循环
  3. 不能等待信号量/消息队列
  4. 不能执行耗时操作(超过10ms都危险)

任务 可以随便做

  1. 可以循环
  2. 可以阻塞
  3. 可以等待
  4. 可以运行复杂业务

九、什么时候用定时器?什么时候用任务?

✅ 用定时器的场景

  • 定时1秒打印一次日志
  • 定时刷新LED
  • 定时更新计数器
  • 定时设置一个标志位
  • 功能简单、时间短、到点触发一下

✅ 用任务的场景

  • 需要大循环
  • 需要等待信号量
  • 需要处理复杂逻辑
  • 需要阻塞、延时、休眠
  • 需要处理串口、网络、文件系统
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐