3.5.6 定时器

定时器允许我们在一个给定的时间触发事件,加快了从一个状态到另一个状态的转变,自动处理一个给定的进程或任务。例如,不需要按键就能每隔5秒闪烁一次LED灯。

Contiki OS包含4种定时器:

  • 简单定时器:一个简单的滴答。应用程序需要手动检查定时器是否到期了。更多信息请看core/sys/timer.h
  • 回调定时器:当一个定时器到期时,它能回调一个给定的函数。更多信息请看core/sys/ctimer.h
  • 事件定时器:与上面的基本相同,只是定时器到期时它不是回调一个函数,而是邮寄一个事件信号。更多信息请看core/sys/etimer.h
  • 实时定时器:实时模块处理实时任务的调度和执行。在同一时刻只允许一个这样的定时器。更多信息请看core/sys/rtimer.h

为了实现我们的目的,我们选择事件定时器,因为我们需要定时器到达一个给定周期时改变应用程序的行为。

我们创建一个定时器,并设定定时器超过给定秒数后所做的事。当定时器到期后,我们执行相应代码,并重置定时器。

创建一个例程文件,命名为test-timer.c

  1. #include "contiki.h"
  2. #include "dev/leds.h"
  3. #include <stdio.h>
  4. /*-------------------------------------------------*/
  5. #define SECONDS 2
  6. /*-------------------------------------------------*/
  7. PROCESS(test_timer_process, "Test timer");
  8. AUTOSTART_PROCESSES(&test_timer_process);
  9. /*-------------------------------------------------*/
  10. PROCESS_THREAD(test_timer_process, ev, data)
  11. {
  12. PROCESS_BEGIN();
  13. static struct etimer et;
  14. while(1) {
  15. etimer_set(&et, CLOCK_SECOND*SECONDS); <1>
  16. PROCESS_WAIT_EVENT():<2>
  17. if(etimer_expired(&et)) {
  18. printf("Hello world!\n");
  19. etimer_reset(&et);
  20. }
  21. }
  22. PROCESS_END();
  23. }

<1>CLOCK_SECOND是与微控制器每秒滴答数相关的数目。由于Contiki运行在不同的平台、不同的硬件上,CLOCK_SECOND也是各不相同的。

<2>PRCESS_WAIT_EVENT()用于等待如何事件发生


练习:你可以打印CLOCK_SECOND的值来计算1秒有多少个滴答吗?尝试在某个确定的秒数时闪烁LED。写一个新的应用程序,当按下按键时才开始闪烁LED,当再次按键时才停止闪烁LED。