Ctimer 提供和Etimer类似的功能,只是Ctimer是在一段时间后调用回调函数,没有和特定进程相关联。

而Etimer是在一段时间后发送PROCESS_EVENT_TIMER事件给特定的进程。

一、Ctimer数据结构

struct ctimer {
struct ctimer *next;//使用LIST时,要求第一个一定是指向本类型的指针
struct etimer etimer;//etimer作为底层通知
struct process *p;//对应的process
void (*f)(void *);//回调函数
void *ptr;//回调函数数据
};

全局变量ctimer_list:

LIST(ctimer_list);

采用库LIST来实现链表的各种操作。

二、Ctimer API

void ctimer_init(void);//Initialize the callback timer library.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr); // Start the timer.
void ctimer_reset(struct ctimer *t); // Restart the timer from the previous expiration time.
void ctimer_restart(struct ctimer *t); // Restart the timer from current time.
void ctimer_stop(struct ctimer *t); // Stop the timer.
int ctimer_expired(struct ctimer *t); // Check if the timer has expired.

这些API基本和之前讨论的差不多,只是数据结构更改了。

这里多了一个ctimer_init,在main函数刚启动时,就得调用这个函数。

/**
* \brief Initialize the callback timer library.
*
* This function initializes the callback timer library and
* should be called from the system boot up code.
*/

以下是各个函数的源代码:

void
ctimer_init(void)
{
initialized = ;//初始化为0
list_init(ctimer_list);//ctimer_list初始化
process_start(&ctimer_process, NULL);//启动ctimer_process进程
}
void
ctimer_set(struct ctimer *c, clock_time_t t,
void (*f)(void *), void *ptr)
{
PRINTF("ctimer_set %p %u\n", c, (unsigned)t);
c->p = PROCESS_CURRENT();//设置对应的p为process_current
c->f = f;//设置回调函数
c->ptr = ptr;//设置回调函数的参数
if(initialized) {//如果ctimer_process初始化完成
PROCESS_CONTEXT_BEGIN(&ctimer_process);//更改process_current为ctimer_process,因为etimer需要通知ctimer_process而不是调用ctimer_set的process
etimer_set(&c->etimer, t);//设置etimer,底层通知机制
PROCESS_CONTEXT_END(&ctimer_process);//恢复process_current
} else {//如果还没,则先设置etimer.timer.iinterval
//等ctimer_process初始化时,会etimer_set这些
c->etimer.timer.interval = t;
} list_remove(ctimer_list, c);//先从list中移出
list_add(ctimer_list, c);//添加到list的尾部
}
void
ctimer_reset(struct ctimer *c)
{
if(initialized) {//ctimer_process初始化完成
PROCESS_CONTEXT_BEGIN(&ctimer_process);//更改process_current
etimer_reset(&c->etimer);
PROCESS_CONTEXT_END(&ctimer_process);//恢复
} list_remove(ctimer_list, c);
list_add(ctimer_list, c);
}
void
ctimer_restart(struct ctimer *c)
{
if(initialized) {
PROCESS_CONTEXT_BEGIN(&ctimer_process);
etimer_restart(&c->etimer);
PROCESS_CONTEXT_END(&ctimer_process);
} list_remove(ctimer_list, c);
list_add(ctimer_list, c);
}
void
ctimer_stop(struct ctimer *c)
{
if(initialized) {
etimer_stop(&c->etimer);
} else {
c->etimer.next = NULL;
c->etimer.p = PROCESS_NONE;
}
list_remove(ctimer_list, c);
}
int
ctimer_expired(struct ctimer *c)
{
struct ctimer *t;
if(initialized) {//如果初始化完
return etimer_expired(&c->etimer);//判断是否处理过?
} //还没初始化完,则判断是否在list中,是,返回0
//没在list中,返回1
for(t = list_head(ctimer_list); t != NULL; t = t->next) {
if(t == c) {
return ;
}
}
return ;
}

三、ctimer_process

PROCESS(ctimer_process, "Ctimer process");
PROCESS_THREAD(ctimer_process, ev, data)
{
struct ctimer *c;
PROCESS_BEGIN(); //处理在initialized之前,就ctimer_set的ctimer
for(c = list_head(ctimer_list); c != NULL; c = c->next) {
etimer_set(&c->etimer, c->etimer.timer.interval);
}
initialized = ;//标志ctimer_process已经初始化完成了 while() {
//等待PROCESS_EVENT_TIMER事件
//ctimer到期时,是由etimer触发,发送一个PROCESS_EVENT_TIMER事件给ctimer_process
//ctimer_process再进行处理(调用相应的回调函数)
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER);
for(c = list_head(ctimer_list); c != NULL; c = c->next) {//遍历
if(&c->etimer == data) {//etimer匹配
list_remove(ctimer_list, c);//从ctimer_list中移出
PROCESS_CONTEXT_BEGIN(c->p);//改变当前进程process_current为c->p,因为要开始调用回调函数了
if(c->f != NULL) {//回调函数不空
#if WITH_GUARD
if (memcmp(ctimer_token, &node_UID[], ) == )
c->f(c->ptr);
#else
c->f(c->ptr);//调用
#endif
}
PROCESS_CONTEXT_END(c->p);//恢复当前进程process_current
break;//跳出循环
}
}
}
PROCESS_END();
}

 The Ctimer library cannot safely be used from interrupts.

Contiki Ctimer模块的更多相关文章

  1. Contiki Etimer 模块

    一.Etimer概述 Etimer提供产生时间事件(timed event)的机制,当设定好的timer到期时,将会给设定etimer的process发送一个PROCESS_EVENT_TIMER 事 ...

  2. Contiki Rtimer 模块

    一.rtimer概述 The Contiki rtimer library provides scheduling and execution of real-time tasks (with pre ...

  3. Contiki clock模块

    一.functions for handling system time clock_time_t clock_time(void);//return the current system time ...

  4. [置顶] STM32移植contiki进阶之三(中):timer 中文版

    鉴于自己英语水平不高,在这里,将上一篇关于contiki 的timer的文章翻译为中文,让自己在学习的时候,更方便点.文中有许多不是很通顺的地方,将就吧. Timers Contiki系统提供了一套时 ...

  5. Contiki-Timer 概述

    Contiki有一个clock模块和一系列timer模块:timer,stimer,ctimer,etimer,和rtimer. 一.clock模块 clock模块提供一些处理系统时间的函数,还有一些 ...

  6. Contiki Timer & Stimer 模块

    一.Timer API struct timer { clock_time_t start; clock_time_t interval; }; CCIF void timer_set(struct ...

  7. Contiki 2.7 Makefile 文件(四)

    3.第三部分 这里我们假设TARGET为native (1) OBJECTDIR = obj_$(TARGET) LOWERCASE = -abcdefghijklmnopqrstuvwxyz UPP ...

  8. Contiki源码结构

    Contiki源码结构 apps目录下,用于存放Application,也就是我们的应用程序放在这个目录下.如webserver,webrowser等,如下图所示. core目录是contiki操作系 ...

  9. cc2530 makefile简略分析 <contiki学习之三>

    前面将contiki的makefile框架都理了下,这篇就以cc2530为收篇吧,也即makefile分析就该到此为止了. contiki/examples/cc2530dk 打开Makefile如下 ...

随机推荐

  1. AngularJS的添加操作和列表操作

    代码下载:https://files.cnblogs.com/files/xiandedanteng/agsAddList.rar 添加成员页面图示: 添加成员页面代码: <%@ page la ...

  2. C 递归 递归指的是在函数的定义中

    C 递归 递归指的是在函数的定义中使用函数自身的方法. 举个例子:从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚,正在给 ...

  3. IOS知识点收集

    17  duplicate symbols for architecture armv7s 用cocoapods 的时候出现,这种错误一般是由重复引用库文件引起. 原因:自己尝试添加Reachabil ...

  4. iOS开发 - &quot;Cast from pointer to smaller type &#39;int&#39; loses information” 解决的方法

    今天要写一个联系人搜索算法. 百度了下, 在code4App中找到相关代码. 可是自己跑了下, 发现报错. 错误内容例如以下: "Cast from pointer to smaller t ...

  5. DataTable行处理

    DataTable dt=new DataTable(); 新增行: DataRow addDR= mydatatable.NewRow();addDR["ID"] = " ...

  6. cnBlogs windows LIves Writes 安装

    1. 官网下载安装 http://group.cnblogs.com/topic/8550.html   参照这个网址下载并安装软件,顺利的话,就万事大吉.但是,如果报错的话,比如我出现的报错的代码是 ...

  7. LeetCode Hash Table 3. Longest Substring Without Repeating Characters

    HashMap的应用可以提高查找的速度,键key,值value的使用拜托了传统数组的遍历查找方式,对于判断一个字符或者字符串是否已经存在的问题可以非常好的解决.而本题需要解决的问题就是判断新遍历到的字 ...

  8. oracle中字符串类似度函数实測

    转载请注明出处:http://blog.csdn.net/songhfu/article/details/40074795 主要利用:oracle函数-SYS.UTL_MATCH.edit_dista ...

  9. ARM内核和架构

    转:深入浅谈,CPU设计原理          CPU的内部架构和工作原理 推荐一本书:编码的奥秘 一.ARM内核和架构 ARM产品越来越丰富,命名也越来越多.很多朋友提问: ARM内核和架构都是什么 ...

  10. LVS + KEEPALIVED + WINDOWS SERVER 2008 R2 ------高可用负载均衡(转)

    工作原理此处不作讲解,自己去官方网站学习(http://www.linuxvirtualserver.org),这里重点讲如何配置!注:最好从官方网站对其进行了解,不至于会对某些问题产生误解,尽管是英 ...