物联网开发——TencentOS Tiny 软件定时器

本文深入探讨了软件定时器的工作原理,对比了软件定时器与硬件定时器的区别,介绍了如何在系统中创建和配置软件定时器,以及如何通过调整配置节省内存资源。同时,提供了编程实例,展示了如何使用API创建一次性及周期性定时器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

软件定时器提供了一套从软件层次实现的定时器机制,相对应的概念是硬件定时器。用户可以创建一系列的软件定时器,并指定软件定时器到期的条件以及执行回调,当软件定时器到期时会执行注册的回调。

通常来说,用户注册的软件定时器回调中很可能包含延迟动作或同步等待操作,或者回调函数本身逻辑复杂执行耗时较长,因此系统将软件定时器管理逻辑设计成一个任务,在这个任务中扫描定时器是否过期并执行定时器回调。但是如你所知,创建一个任务是需要消耗系统内存资源的(任务的栈、任务句柄本身的内存空间等等),而如果用户注册的软件定时器回调中并不包含延迟动作也不包含同步等待操作,或者回调本身执行耗时很短,这种情况下软件定时器管理逻辑无需被设计成任务,而是可以被设计成时钟中断中被调用的一个函数。当软件定时器管理逻辑被设计成一个函数时,就可以节省创建任务所需的资源。

系统默认采用的实现是将定时器管理逻辑设计为任务,当用户的定时器回调都是耗时极短的操作时,用户可以通过将软件定时器管理逻辑配置为函数来节省内存资源。通过在tos_config.h中打开TOS_CFG_TIMER_AS_PROC开关来讲软件定时器管理逻辑配置为函数:

#define TOS_CFG_TIMER_AS_PROC 1u

API讲解

k_err_t tos_timer_create(k_timer_t *tmr,
                         k_tick_t delay,
                         k_tick_t period,
                         k_timer_callback_t callback,
                         void *cb_arg,
                         k_opt_t opt)

这里详细讲解此api参数意义:

  • tmr

    软件定时器句柄。

  • delay

    该定时器延迟多久后执行。

  • period

    一个定时器的执行周期。

  • callback

    定时器到期后的执行回调。

  • cb_arg

    执行回调的入参。

  • opt

    此opt的传入主要是界定tmr的属性,如果传入的是TOS_OPT_TIMER_ONESHOT,表明此tmr是一次性的,当delay时间到期,tmr的执行回调调用完毕后此tmr生命周期就结束了;如果传入的是TOS_OPT_TIMER_PERIODIC,表明此tmr是周期性定时器,当tmr定时时间到期,tmr的执行回调调用完毕后,系统会重新按period参数为到期时间将tmr加入到定时队列,开启下一个周期。

编程实例

1、在tos_config.h中,配置软件定时器组件开关TOS_CFG_TIMER_EN:

#define TOS_CFG_TIMER_EN 1000u

2、编写main.c示例代码:

#include "tos.h"
#include "mcu_init.h"

#define STK_SIZE_TASK_DEMO      512

k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO];

k_task_t task_demo;

extern void entry_task_demo(void *arg);

void oneshot_timer_cb(void *arg)
{
    printf("this is oneshot timer callback, current systick: %lld\n", tos_systick_get());
}

void periodic_timer_cb(void *arg)
{
    printf("this is periodic timer callback, current systick: %lld\n", tos_systick_get());
}

void entry_task_demo(void *arg)
{
    k_timer_t oneshot_tmr;
    k_timer_t periodic_tmr;

    // 这是一个一次性的timer,且超时时间是3000个tick之后
    tos_timer_create(&oneshot_tmr, 3000, 0, oneshot_timer_cb, K_NULL, TOS_OPT_TIMER_ONESHOT);
    // 这是一个周期性的timer,第一次超时时间是2000个tick之后,之后按3000个tick为周期执行回调
    tos_timer_create(&periodic_tmr, 2000, 3000, periodic_timer_cb, K_NULL, TOS_OPT_TIMER_PERIODIC);

    printf("current systick: %lld\n", tos_systick_get());
    tos_timer_start(&oneshot_tmr);
    tos_timer_start(&periodic_tmr);

    while (K_TRUE) {
        tos_task_delay(1000);
    }
}

int main(void)
{
    board_init();
    tos_knl_init();
    (void)tos_task_create(&task_demo, "receiver_higher_prio", entry_task_demo, NULL,
                            4, stack_task_demo, STK_SIZE_TASK_DEMO, 0);
    tos_knl_start();
}

运行效果

current systick: 0 this is periodic timer callback, current systick: 2001 this is oneshot timer callback, current systick: 3001 this is periodic timer callback, current systick: 5001 this is periodic timer callback, current systick: 8001 this is periodic timer callback, current systick: 11001 this is periodic timer callback, current systick: 14001

[实例代码](./code/2.6 timer/main.c)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值