Contiki 2.6

ctimer.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup ctimer
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006, Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the Institute nor the names of its contributors
00019  *    may be used to endorse or promote products derived from this software
00020  *    without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * This file is part of the Contiki operating system.
00035  *
00036  * $Id: ctimer.c,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Callback timer implementation
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #include "sys/ctimer.h"
00047 #include "contiki.h"
00048 #include "lib/list.h"
00049 
00050 LIST(ctimer_list);
00051 
00052 static char initialized;
00053 
00054 #define DEBUG 0
00055 #if DEBUG
00056 #include <stdio.h>
00057 #define PRINTF(...) printf(__VA_ARGS__)
00058 #else
00059 #define PRINTF(...)
00060 #endif
00061 
00062 /*---------------------------------------------------------------------------*/
00063 PROCESS(ctimer_process, "Ctimer process");
00064 PROCESS_THREAD(ctimer_process, ev, data)
00065 {
00066   struct ctimer *c;
00067   PROCESS_BEGIN();
00068 
00069   for(c = list_head(ctimer_list); c != NULL; c = c->next) {
00070     etimer_set(&c->etimer, c->etimer.timer.interval);
00071   }
00072   initialized = 1;
00073 
00074   while(1) {
00075     PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER);
00076     for(c = list_head(ctimer_list); c != NULL; c = c->next) {
00077       if(&c->etimer == data) {
00078         list_remove(ctimer_list, c);
00079         PROCESS_CONTEXT_BEGIN(c->p);
00080         if(c->f != NULL) {
00081           c->f(c->ptr);
00082         }
00083         PROCESS_CONTEXT_END(c->p);
00084         break;
00085       }
00086     }
00087   }
00088   PROCESS_END();
00089 }
00090 /*---------------------------------------------------------------------------*/
00091 void
00092 ctimer_init(void)
00093 {
00094   initialized = 0;
00095   list_init(ctimer_list);
00096   process_start(&ctimer_process, NULL);
00097 }
00098 /*---------------------------------------------------------------------------*/
00099 void
00100 ctimer_set(struct ctimer *c, clock_time_t t,
00101            void (*f)(void *), void *ptr)
00102 {
00103   PRINTF("ctimer_set %p %u\n", c, (unsigned)t);
00104   c->p = PROCESS_CURRENT();
00105   c->f = f;
00106   c->ptr = ptr;
00107   if(initialized) {
00108     PROCESS_CONTEXT_BEGIN(&ctimer_process);
00109     etimer_set(&c->etimer, t);
00110     PROCESS_CONTEXT_END(&ctimer_process);
00111   } else {
00112     c->etimer.timer.interval = t;
00113   }
00114 
00115   list_remove(ctimer_list, c);
00116   list_add(ctimer_list, c);
00117 }
00118 /*---------------------------------------------------------------------------*/
00119 void
00120 ctimer_reset(struct ctimer *c)
00121 {
00122   if(initialized) {
00123     PROCESS_CONTEXT_BEGIN(&ctimer_process);
00124     etimer_reset(&c->etimer);
00125     PROCESS_CONTEXT_END(&ctimer_process);
00126   }
00127 
00128   list_remove(ctimer_list, c);
00129   list_add(ctimer_list, c);
00130 }
00131 /*---------------------------------------------------------------------------*/
00132 void
00133 ctimer_restart(struct ctimer *c)
00134 {
00135   if(initialized) {
00136     PROCESS_CONTEXT_BEGIN(&ctimer_process);
00137     etimer_restart(&c->etimer);
00138     PROCESS_CONTEXT_END(&ctimer_process);
00139   }
00140 
00141   list_remove(ctimer_list, c);
00142   list_add(ctimer_list, c);
00143 }
00144 /*---------------------------------------------------------------------------*/
00145 void
00146 ctimer_stop(struct ctimer *c)
00147 {
00148   if(initialized) {
00149     etimer_stop(&c->etimer);
00150   } else {
00151     c->etimer.next = NULL;
00152     c->etimer.p = PROCESS_NONE;
00153   }
00154   list_remove(ctimer_list, c);
00155 }
00156 /*---------------------------------------------------------------------------*/
00157 int
00158 ctimer_expired(struct ctimer *c)
00159 {
00160   struct ctimer *t;
00161   if(initialized) {
00162     return etimer_expired(&c->etimer);
00163   }
00164   for(t = list_head(ctimer_list); t != NULL; t = t->next) {
00165     if(t == c) {
00166       return 0;
00167     }
00168   }
00169   return 1;
00170 }
00171 /*---------------------------------------------------------------------------*/
00172 /** @} */