HaaS EDU K1设备资源 之 定时器

1、定时器

系统定时器(timer)分为两种,一种是硬件定时器,一种是软件定时器。

  • 硬件定时器:它会产生固定的时钟节拍,作为操作系统的时钟基准,其数量是受硬件模块数量的限制的。
  • 软件定时器:通过软件模拟出来的定时器,在精度方面比硬件定时器差一些;它的优点在于只要系统资源足够,可以由一个硬件定时器模拟出成千上万个软件定时器。但由于软件定时器是通过程序实现的,其运行和维护都需要耗费一定的CPU资源,同时精度也相对硬件定时器要差一些。所以,一个好的软件定时器实现要求有较高的精度、较小的处理器开销,且占用较少的存储器资源。

本节要讲的就是软件定时器的概念。每个软件定时器都保存着自己的到期时间即时间超时处理函数。软件定时器管理模块会需要扫描所有的软件定时器设定,每个timer到期之后呼叫其预设的时间超时处理函数。

定时器按照是否重复可以分为一次性timer和周期性timer 两种。

 

2、AliOS Things Timer模块

AliOS Things操作系统对用户提供定时接口的是Timer模块。Timer模块屏蔽了硬件定时器的实现差异,它基于Tick作为最小的时间调度单元来推动自己时间轴的运行,因此 Tick的时间长度也就是Timer模块的最小定时精度。

Timer模块提供的接口包括Timer的创建、删除、启动以及单次或周期定时器。

Timer模块在操作系统默认加载的模块指引,操作系统启动的时候会自动启动。

 

2.1、Timer API列表

API名称

扫描二维码关注公众号,回复: 12808124 查看本文章

功能

aos_timer_new

创建软件定时器

aos_timer_new_ext

创建软件定时器

aos_timer_start

启动软件定时器

aos_timer_stop

停止软件定时器

aos_timer_change

修改软件定时器的定时参数

aos_timer_free

删除软件定时器

 

2.1.1、aos_timer_new

创建一个软件定时器,创建后自动运行。

  • 函数原型及参数说明

 int aos_timer_new(aos_timer_t *timer,void (*fn)(void *, void *),void *arg, int ms, int repeat);

API名称

功能

timer

软件定时器句柄

fn

定时到期处理函数

arg

定时到期处理函数被呼叫时需要Timer模块传递的参数

ms

定时器超时时间(单位ms),即间隔多少时间之后执行fn

repeat

周期定时或单次定时(1:周期,0:单次)

  • 返回值
    0表示成功,其他值表示失败。具体的返回值定义请参考k_err.h中kstat_t的定义。

 

2.1.2、aos_timer_new_ext

创建一个软件定时器,可通过入参决定创建后是否自动运行。

  • 函数原型及参数说明

int aos_timer_new_ext(aos_timer_t *timer, void (*fn)(void *, void *),void *arg, int ms, int repeat, unsigned char auto_run);

API名称

功能

timer

软件定时器句柄

fn

定时到期处理函数

arg

定时到期处理函数被呼叫时需要Timer模块传递的参数

ms

定时器超时时间(单位ms),即间隔多少时间之后执行fn

repeat

周期定时或单次定时(1:周期,0:单次)

auto_run

1表示自动运行,0表示不自动运行,需要手动调用aos_timer_start才能启动

  • 返回值
    0表示成功,其他值表示失败。具体的返回值定义请参考k_err.h中kstat_t的定义。

 

2.1.3、aos_timer_start

启动软件定时器

  • 函数原型及参数说明

int aos_timer_start(aos_timer_t *timer);

API名称

功能

timer

软件定时器句柄

  • 返回值
    0表示成功,其他值表示失败。具体的返回值定义请参考k_err.h中kstat_t的定义。

2.1.4、aos_timer_change

修改软件定时器的定时参数

  • 函数原型及参数说明

int aos_timer_change(aos_timer_t *timer, int ms);

API名称

功能

timer

软件定时器句柄

ms

新的定时器超时时间(单位ms),即间隔多少时间执行定时器到期处理函数

  • 返回值
    0表示成功,其他值表示失败。具体的返回值定义请参考k_err.h中kstat_t的定义。

 

2.1.5、aos_timer_stop

停止软件定时器。

  • 函数原型及参数说明

int aos_timer_stop(aos_timer_t *timer);

API名称

功能

timer

软件定时器句柄

  • 返回值
    0表示成功,其他值表示失败。具体的返回值见本文档返回参数定义小节。

 

2.1.6、aos_timer_free

删除软件定时器。删除定时器前需调用aos_timer_stop停止定时器。

  • 函数原型及参数说明

void aos_timer_free(aos_timer_t *timer);

API名称

功能

timer

软件定时器句柄

  • 返回值

 

3、Timer使用案例

本案例中通过创建“单词自动执行定时器”,“不自动执行周期性定时器”以及“自动执行周期性定时器”为例对AOS Timer API进行说明

3.1、需要包含的头文件

#include <aos/kernel.h>

 

3.2、创建自动执行的单次定时器

#include "aos/kernel.h"

aos_timer_t  g_single_timer;

static void g_single_timer_handler(void *arg1, void* arg2)

{

    printf("enter %s\r\n", __func__);

    return;

}


/**

 * set up a timer with timeout value of period and set timer's handler to g_single_timer_handler

 * @param period - timer timeout value, in unit of ms

 *

 * @return 0 for success; negative no. for failure

 */

int single_timer_example(int period) {

    int ret = -1;

    if (period <= 0) {

        printf("invalid period:%d\r\n", period);

        return -1;

    }

    /*setup a timer with timeout value set to period ms and disable autoload function */

    ret = aos_timer_new_ext(&g_single_timer, g_single_timer_handler, NULL, period, 0, 0);

    if (ret != 0) {

        printf("timer create failed\r\n");

        return 2;

    }

    /* start the timer */

    aos_timer_start(&g_single_timer);

    /* sleep for (period * 2) ms */

    usleep (period * 5 * 1000);

    /* stop the timer again */

    aos_timer_stop(&g_single_timer);

    /* free the timer's resource */

    aos_timer_free(&g_single_timer);

    return 0;

}

 

3.3、创建自动运行周期性定时器

aos_timer_t  g_repeat_autoload_timer;

static void repeat_autoload_timer_handler(void *arg1, void* arg2)

{

    printf("enter %s\r\n", __func__);

    return;

}



/**

 * set up an auto reload timer with timeout value of period and set timer's handler to repeat_autoload_timer_handler

 * @param period - timer timeout value, in unit of ms

 *

 * @return 0 for success; negative no. for failure

 */

int repeat_autoload_timer_example(int period) {

    int ret = -1;

    if (period <= 0) {

        printf("invalid period:%d\r\n", period);

        return -1;

    }

    /*setup a timer with timeout value set to period ms and enable autoload function */

    ret = aos_timer_new(&g_repeat_autoload_timer, repeat_autoload_timer_handler, NULL, period, 1);

    if (ret != 0) {

        printf("timer create failed\r\n");

        return 2;

    }



    /* sleep for (period * 2) ms */

    usleep (period * 5 * 1000);

    /* stop the timer again */

    aos_timer_stop(&g_repeat_autoload_timer);

    /* free the timer's resource */

    aos_timer_free(&g_repeat_autoload_timer);

    return 0;

}

   

3.4、创建不自动运行周期性定时器

aos_timer_t  g_repeat_non_autoload_timer;

static void repeat_non_autoload_timer_handler(void *arg1, void* arg2)

{

    printf("enter %s\r\n", __func__);

    return;

}


/**

 * set up an repeat timer with timeout value of period and set timer's handler to repeat_non_autoload_timer_handler

 * @param period - timer timeout value, in unit of ms

 *

 * @return 0 for success; negative no. for failure

 */

int repeat_timer_example(int period) {

    int ret = -1;

    if (period <= 0) {

        printf("invalid period:%d\r\n", period);

        return -1;

    }

    /*setup a timer with timeout value set to period ms and enable autoload function */

    ret = aos_timer_new_ext(&g_repeat_non_autoload_timer, repeat_non_autoload_timer_handler, NULL, period, 1, 0);

    if (ret != 0) {

        printf("timer create failed\r\n");

        return 2;

    }


    aos_timer_start(&g_repeat_non_autoload_timer);


    /* sleep for (period * 2) ms */

    usleep (period * 5 * 1000);

    /* stop the timer again */

    aos_timer_stop(&g_repeat_non_autoload_timer);

    /* free the timer's resource */

    aos_timer_free(&g_repeat_non_autoload_timer);

    return 0;

}

 

3.5、Timer案例测试方法

我们为Timer的测试案例添加几个CLI的测试指令,其中:

  • stimer指令:用来进行“单次定时器”的测试
  • rtimer指令:用来创建“不自动执行的周期性定时器”的测试
  • srtimer指令:用来创建“自动执行的周期性定时器”的测试
#include <aos/cli.h>

static void single_timer(char *buf, int len, int argc, char **argv)

{

    single_timer_example(1000);

    return;

}



static void repeat_timer(char *buf, int len, int argc, char **argv)

{

    repeat_timer_example(2000);

    return;

}



static void autoload_repeat_timer(char *buf, int len, int argc, char **argv)

{

    g_repeat_autoload_timer_example(3000);

    return;

}



struct cli_command timer_cli_cmds[] = {

    {"stimer",         "single timer test", single_timer},

    {"rtimer",         "non-autoload repeat timer test", repeat_timer},

    {"artimer",        "autoload repeat timer test", autoload_repeat_timer},

};



int new_comp_timer_test_cmd_init(void) {

    return aos_cli_register_commands(&timer_cli_cmds[0],

                                     sizeof(timer_cli_cmds)/sizeof(timer_cli_cmds[0]));

}

将本节中的所有代码复制到AliOS-Things/application/example/helloworld_demo/appdemo.c中,并修改appdemo.c中application_start函数实现如下:

int application_start(int argc, char *argv[])

{

    int count = 0;



    printf("nano entry here!\r\n");



    new_comp_timer_test_cmd_init();



    while(1) {

        //printf("hello world! count %d \r\n", count++);

        aos_msleep(1000);

    };

}

 

3.6、Timer案例执行结果

编译helloworld_demo@haaseduk1并将固件烧录到HaaS EDU之后,系统启动之后测试方法如下:

  • 敲help,确认为timer测试添加的cli指令是否出现

  • 敲入stimer,确认单次timer是否只执行了一次。

  • 敲入rtimer,确认timer是否执行了5次。

  • 敲入artimer,确认timer是否执行了5次。

 

开发者技术支持

如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/

猜你喜欢

转载自blog.csdn.net/HaaSTech/article/details/114738939