全部文档
OneOS简介 硬件支持 快速开发指南 编译构造工具 API参考文档 高级语言 用户编程手册 应用笔记 FAQ

定时器管理


简介

定时器按照执行的次数,可分为两种:一种是单次触发定时器,即只会触发一次超时,之后该定时器停止;另外一种是周期性定时器,即按照设定的时间周期性地超时,除非被手动停止。这两种模式可以在创建/初始化时通过OS_TIMER_FLAG_ONE_SHOT和OS_TIMER_FLAG_PERIODIC来指定,默认为OS_TIMER_FLAG_ONE_SHOT。

按照超时函数执行的上下文环境,可分为两种:一种是HARD_TIMER模式,在中断上下文环境中执行,使用这种定时器时需要注意超时函数应尽量短,且不应该有会导致任务挂起的操作;另外一种是SOFT_TIMER,在任务环境中执行。这两种模式可以在创建/初始化时通过OS_TIMER_FLAG_HARD_TIMER和OS_TIMER_FLAG_SOFT_TIMER来指定,默认为OS_TIMER_FLAG_HARD_TIMER。


重要定义及数据结构

宏定义

#define OS_TIMER_FLAG_ONE_SHOT          0x0             /**< one shot timer */
#define OS_TIMER_FLAG_PERIODIC          0x2             /**< periodic timer */

#define OS_TIMER_FLAG_HARD_TIMER        0x0             /**< hard timer,the timer's callback function will be called in tick isr. */
#define OS_TIMER_FLAG_SOFT_TIMER        0x4             /**< soft timer,the timer's callback function will be called in timer task. */
定义 说明
OS_TIMER_FLAG_ONE_SHOT 一次性定时器
OS_TIMER_FLAG_PERIODIC 周期性定时器
OS_TIMER_FLAG_HARD_TIMER HARD_TIMER,回调函数在tick中断服务程序中被执行
OS_TIMER_FLAG_SOFT_TIMER SOFT_TIMER,回调函数在timer task中被执行

枚举

enum os_timer_ctrl_cmd
{
    OS_TIMER_CTRL_SET_TIME = 0x0,
    OS_TIMER_CTRL_GET_TIME,
    OS_TIMER_CTRL_SET_ONESHOT,
    OS_TIMER_CTRL_SET_PERIODIC
};
定义 说明
OS_TIMER_CTRL_SET_TIME 设置定时器的超时时间
OS_TIMER_CTRL_GET_TIME 获取定时器的超时时间
OS_TIMER_CTRL_SET_ONESHOT 设置定时器为一次性定时器
OS_TIMER_CTRL_SET_PERIODIC 设置定时器为周期性定时器

结构体

struct os_timer
{
    os_object_t      parent;                            /* Inherit from os_object. */

    os_list_node_t   row[OS_TIMER_SKIP_LIST_LEVEL];

    void           (*timeout_func)(void *parameter);    /* Timeout function. */
    void            *parameter;                         /* Timeout function's parameter. */

    os_tick_t        init_tick;                         /* Timer timeout tick. */
    os_tick_t        timeout_tick;                      /* Timeout tick. */
};
struct os_timer重要参数 说明
row 跳表节点,用于将该定时器句柄添加到定时器跳表中
timeout_func 超时函数
parameter 超时函数的参数
init_tick 超时时间(以tick为单位)
timeout_tick 超时时刻的系统时间(即定时器启动时的系统时间加上init_tick)

API列表

接口 说明
os_timer_init 定时器静态方式初始化,即定时器对象由使用者提供
os_timer_deinit 定时器反初始化, os_timer_init()匹配使用
os_timer_create 定时器动态创建并初始化,与os_timer_init()达到的效果一样,区别在于内存通过动态申请的方式获得
os_timer_destroy 定时器动态销毁,与os_timer_create()匹配使用
os_timer_start 启动定时器
os_timer_stop 停止定时器
os_timer_control 控制或更改定时器的属性

os_timer_init

该函数用于以静态方式初始化定时器,即定时器对象由使用者提供,其函数原型如下:

void os_timer_init(os_timer_t    *timer,
                   const char    *name, 
                   void          (*timeout)(void *parameter), 
                   void          *parameter, 
                   os_tick_t     time, 
                   os_uint8_t    flag);
参数 说明
timer 定时器句柄(定时器控制块指针),其空间由使用者提供
name 定时器名字
timeout 超时函数,时间达到时此函数被调用
parameter 超时函数的参数
time 超时时间
flag 参数,可配置两种属性:第一种为设定单次定时器OS_TIMER_FLAG_ONE_SHOT或周期定时器OS_TIMER_FLAG_PERIODIC;第二种为设定硬件定时器OS_TIMER_FLAG_HARD_TIMER或软件定时器OS_TIMER_FLAG_SOFT_TIMER;这两种属性可以取“或”的关系
返回 说明

os_timer_deinit

该函数用于反初始化静态定时器,会把该定时器从系统容器的定时器链表中删除,其函数原型如下:

void os_timer_deinit(os_timer_t *timer);
参数 说明
timer 定时器句柄
返回 说明

os_timer_create

该函数用于以动态方式创建定时器,会为定时器控制块分配内存并初始化,与os_timer_init()达到的效果一样,函数原型如下:

os_timer_t *os_timer_create(const char    *name, 
                            void          (*timeout)(void *parameter), 
                            void          *parameter, 
                            os_tick_t     time, 
                            os_uint8_t    flag);
参数 说明
name 定时器名字
timeout 超时函数,时间达到时此函数被调用
parameter 超时函数的参数
time 超时时间
flag 参数,可配置两种属性:第一种为设定单次定时器OS_TIMER_FLAG_ONE_SHOT或周期定时器OS_TIMER_FLAG_PERIODIC;第二种为设定硬件定时器OS_TIMER_FLAG_HARD_TIMER或软件定时器OS_TIMER_FLAG_SOFT_TIMER;这两种属性可以取“或”的关系
返回 说明
非OS_NULL 定时器句柄
OS_NULL 创建失败

os_timer_destroy

该函数用于销毁动态创建的定时器,会把该定时器从定时器链表中删除,并释放定时器控制块的内存,其函数原型如下:

os_err_t os_timer_destroy(os_timer_t *timer);
参数 说明
timer 定时器句柄
返回 说明
OS_EOK 定时器销毁成功

os_timer_start

该函数用于启动定时器,函数原型如下:

os_err_t os_timer_start(os_timer_t *timer);
参数 说明
timer 定时器句柄
返回 说明
OS_EOK 启动成功

os_timer_stop

该函数用于停止定时器,函数原型如下:

os_err_t os_timer_stop(os_timer_t *timer);
参数 说明
timer 定时器句柄
返回 说明
OS_EOK 停止成功
OS_ERROR 停止失败,定时器之前已处于停止状态

os_timer_control

该函数用于控制或者修改定时器的属性,其函数原型如下:

os_err_t os_timer_control(os_timer_t *timer, enum os_timer_ctrl_cmd cmd, void *arg);
参数 说明
timer 定时器句柄
cmd 控制命令,具体参考枚举定义os_timer_ctrl_cmd
arg 若cmd为OS_TIMER_CTRL_GET_TIME,则arg为读取的超时时间;若cmd为OS_TIMER_CTRL_SET_TIME,则arg为设置的超时时间
返回 说明
OS_EOK 控制或者修改成功

使用示例

静态定时器使用示例

本例利用静态方式分别初始化了一个周期性定时器和一次性定时器,过一段时间后反初始化

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_assert.h>
#include <shell.h>
#include <os_timer.h>

#define TEST_TAG  "TEST"

static os_timer_t timer_s1;
static os_timer_t timer_s2;

void timer_s1_timeout(void *parameter)
{
    LOG_W(TEST_TAG, "timer_s1 PERIODIC");
}

void timer_s2_timeout(void *parameter)
{
    LOG_W(TEST_TAG, "timer_s2 ONE_SHOT");
}

void static_timer_sample(void)
{    
    os_timer_init(&timer_s1, "timer_s1", timer_s1_timeout, OS_NULL, 100, OS_TIMER_FLAG_PERIODIC | OS_TIMER_FLAG_SOFT_TIMER);

    LOG_W(TEST_TAG, "===timer_s1 start===");
    os_timer_start(&timer_s1);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer_s1 deinit===");
    os_timer_deinit(&timer_s1);

    os_timer_init(&timer_s2, "timer_s2", timer_s2_timeout, OS_NULL, 100, OS_TIMER_FLAG_ONE_SHOT | OS_TIMER_FLAG_SOFT_TIMER);

    LOG_W(TEST_TAG, "===timer_s2 start===");
    os_timer_start(&timer_s2);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer_s2 deinit===");
    os_timer_deinit(&timer_s2);
}

SH_CMD_EXPORT(static_timer, static_timer_sample, "test static timer");

运行结果如下:

sh />static_timer
W/TEST: ===timer_s1 start===
W/TEST: timer_s1 PERIODIC
W/TEST: timer_s1 PERIODIC
W/TEST: timer_s1 PERIODIC
W/TEST: timer_s1 PERIODIC
W/TEST: timer_s1 PERIODIC
W/TEST: ===timer_s1 deinit===
W/TEST: ===timer_s2 start===
W/TEST: timer_s2 ONE_SHOT
W/TEST: ===timer_s2 deinit===

动态定时器使用示例

本例用动态方式分别创建了一个周期性定时器和一次性定时器,过一段时间后再销毁定时器

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_assert.h>
#include <shell.h>
#include <os_timer.h>

#define TEST_TAG  "TEST"

void timer_d1_timeout(void *parameter)
{
    LOG_W(TEST_TAG, "timer_d1 PERIODIC");
}

void timer_d2_timeout(void *parameter)
{
    LOG_W(TEST_TAG, "timer_d2 ONE_SHOT");
}

void dynamic_timer_sample(void)
{   
    static os_timer_t *timer_d1;
    static os_timer_t *timer_d2;

    timer_d1 = os_timer_create("timer_d1", timer_d1_timeout, OS_NULL, 100, OS_TIMER_FLAG_PERIODIC | OS_TIMER_FLAG_SOFT_TIMER);
    if (!timer_d1)
    {
        LOG_W(TEST_TAG, "===timer_d1 create err===");
        return;
    }

    LOG_W(TEST_TAG, "===timer_d1 start===");
    os_timer_start(timer_d1);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer_d1 destroy===");
    os_timer_destroy(timer_d1);

    timer_d2 = os_timer_create("timer_d2", timer_d2_timeout, OS_NULL, 100, OS_TIMER_FLAG_ONE_SHOT | OS_TIMER_FLAG_SOFT_TIMER);
    if (!timer_d2)
    {
        LOG_W(TEST_TAG, "===timer_d2 create err===");
        return;
    }

    LOG_W(TEST_TAG, "===timer_d2 start===");
    os_timer_start(timer_d2);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer_d2 destroy===");
    os_timer_destroy(timer_d2);
}

SH_CMD_EXPORT(dynamic_timer, dynamic_timer_sample, "test dynamic timer");

运行结果如下:

sh />dynamic_timer
W/TEST: ===timer_d1 start===
W/TEST: timer_d1 PERIODIC
W/TEST: timer_d1 PERIODIC
W/TEST: timer_d1 PERIODIC
W/TEST: timer_d1 PERIODIC
W/TEST: timer_d1 PERIODIC
W/TEST: ===timer_d1 destroy===
W/TEST: ===timer_d2 start===
W/TEST: timer_d2 ONE_SHOT
W/TEST: ===timer_d2 destroy===

定时器控制命令使用示例

本例创建定时器后,通过OS_TIMER_CTRL_GET_TIME获取定时器的超时时间,通过OS_TIMER_CTRL_SET_TIME改变超时时间,通过OS_TIMER_CTRL_SET_ONESHOT/OS_TIMER_CTRL_SET_PERIODIC来设置定时器单次执行或周期执行

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_assert.h>
#include <shell.h>
#include <os_timer.h>

#define TEST_TAG  "TEST"

void timer_ctrl_timeout(void *parameter)
{
    LOG_W(TEST_TAG, "timer_ctrl_timeout");
}

void control_timer_sample(void)
{
    os_tick_t init_tick;
    static os_timer_t *timer_ctrl; 

    timer_ctrl = os_timer_create("timer_ctrl", timer_ctrl_timeout, OS_NULL, 100, OS_TIMER_FLAG_PERIODIC | OS_TIMER_FLAG_SOFT_TIMER);
    OS_ASSERT(OS_NULL != timer_ctrl);
    LOG_W(TEST_TAG, "===timer start===");
    os_timer_start(timer_ctrl);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer stop===");
    os_timer_stop(timer_ctrl);

    os_timer_control(timer_ctrl, OS_TIMER_CTRL_GET_TIME, &init_tick);
    LOG_W(TEST_TAG, "get timeout :%d", init_tick);

    init_tick += 100;
    LOG_W(TEST_TAG, "set timeout :%d", init_tick);
    os_timer_control(timer_ctrl, OS_TIMER_CTRL_SET_TIME, &init_tick);
    LOG_W(TEST_TAG, "===timer start===");
    os_timer_start(timer_ctrl);
    os_task_delay(550);

    LOG_W(TEST_TAG, "set oneshot ");
    os_timer_control(timer_ctrl, OS_TIMER_CTRL_SET_ONESHOT, OS_NULL);
    os_task_delay(550);

    LOG_W(TEST_TAG, "set periodic ");
    os_timer_control(timer_ctrl, OS_TIMER_CTRL_SET_PERIODIC, OS_NULL);    
    LOG_W(TEST_TAG, "===timer start===");
    os_timer_start(timer_ctrl);
    os_task_delay(550);

    LOG_W(TEST_TAG, "===timer destroy===");
    os_timer_destroy(timer_ctrl);
}

SH_CMD_EXPORT(control_timer, control_timer_sample, "test control timer");

执行结果如下:

sh />control_timer
W/TEST: ===timer start===
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: ===timer stop===
W/TEST: get timeout :100
W/TEST: set timeout :200
W/TEST: ===timer start===
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: set oneshot 
W/TEST: timer_ctrl_timeout
W/TEST: set periodic 
W/TEST: ===timer start===
W/TEST: timer_ctrl_timeout
W/TEST: timer_ctrl_timeout
W/TEST: ===timer destroy===

results matching ""

    No results matching ""