From cdf0b2fd2bf82a9ecc22b18763585006e2d41ef6 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 17 Jun 2006 22:41:10 +0000 Subject: [PATCH 001/146] Import of the contiki-2.x development code from the SICS internal CVS server --- arg.c | 133 ++++++++++++ arg.h | 43 ++++ autostart.c | 63 ++++++ autostart.h | 62 ++++++ cc.h | 111 ++++++++++ clock.h | 97 +++++++++ dsc.h | 128 ++++++++++++ etimer.c | 260 ++++++++++++++++++++++++ etimer.h | 242 ++++++++++++++++++++++ lc-addrlabels.h | 82 ++++++++ lc-switch.h | 76 +++++++ lc.h | 131 ++++++++++++ loader.h | 132 ++++++++++++ log.h | 46 +++++ mt.c | 221 ++++++++++++++++++++ mt.h | 366 +++++++++++++++++++++++++++++++++ process.c | 402 ++++++++++++++++++++++++++++++++++++ process.h | 526 ++++++++++++++++++++++++++++++++++++++++++++++++ procinit.c | 49 +++++ procinit.h | 45 +++++ pt-sem.h | 228 +++++++++++++++++++++ pt.h | 323 +++++++++++++++++++++++++++++ service.c | 111 ++++++++++ service.h | 195 ++++++++++++++++++ timer.c | 128 ++++++++++++ timer.h | 100 +++++++++ 26 files changed, 4300 insertions(+) create mode 100644 arg.c create mode 100644 arg.h create mode 100644 autostart.c create mode 100644 autostart.h create mode 100644 cc.h create mode 100644 clock.h create mode 100644 dsc.h create mode 100644 etimer.c create mode 100644 etimer.h create mode 100644 lc-addrlabels.h create mode 100644 lc-switch.h create mode 100644 lc.h create mode 100644 loader.h create mode 100644 log.h create mode 100644 mt.c create mode 100644 mt.h create mode 100644 process.c create mode 100644 process.h create mode 100644 procinit.c create mode 100644 procinit.h create mode 100644 pt-sem.h create mode 100644 pt.h create mode 100644 service.c create mode 100644 service.h create mode 100644 timer.c create mode 100644 timer.h diff --git a/arg.c b/arg.c new file mode 100644 index 000000000..9df45198b --- /dev/null +++ b/arg.c @@ -0,0 +1,133 @@ +/** + * \file + * Argument buffer for passing arguments when starting processes + * \author Adam Dunkels + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup arg Argument buffer + * @{ + * + * The argument buffer can be used when passing an argument from an + * exiting process to a process that has not been created yet. Since + * the exiting process will have exited when the new process is + * started, the argument cannot be passed in any of the processes' + * addres spaces. In such situations, the argument buffer can be used. + * + * The argument buffer is statically allocated in memory and is + * globally accessible to all processes. + * + * An argument buffer is allocated with the arg_alloc() function and + * deallocated with the arg_free() function. The arg_free() function + * is designed so that it can take any pointer, not just an argument + * buffer pointer. If the pointer to arg_free() is not an argument + * buffer, the function does nothing. + */ + +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop OS + * + * $Id: arg.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#include "sys/arg.h" + +/** + * \internal Structure used for holding an argument buffer. + */ +struct argbuf { + char buf[128]; + char used; +}; + +static struct argbuf bufs[1]; + +/*-----------------------------------------------------------------------------------*/ +/** + * \internal Initalizer, called by the dispatcher module. + */ +/*-----------------------------------------------------------------------------------*/ +void +arg_init(void) +{ + bufs[0].used = 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Allocates an argument buffer. + * + * \param size The requested size of the buffer, in bytes. + * + * \return Pointer to allocated buffer, or NULL if no buffer could be + * allocated. + * + * \note It currently is not possible to allocate argument buffers of + * any other size than 128 bytes. + * + */ +/*-----------------------------------------------------------------------------------*/ +char * +arg_alloc(char size) +{ + if(bufs[0].used == 0) { + bufs[0].used = 1; + return bufs[0].buf; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Deallocates an argument buffer. + * + * This function deallocates the argument buffer pointed to by the + * parameter, but only if the buffer actually is an argument buffer + * and is allocated. It is perfectly safe to call this function with + * any pointer. + * + * \param arg A pointer. + */ +/*-----------------------------------------------------------------------------------*/ +void +arg_free(char *arg) +{ + if(arg == bufs[0].buf) { + bufs[0].used = 0; + } +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/arg.h b/arg.h new file mode 100644 index 000000000..4abcb820d --- /dev/null +++ b/arg.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop OS + * + * $Id: arg.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ +#ifndef __ARG_H__ +#define __ARG_H__ + +void arg_init(void); + +char *arg_alloc(char size); +void arg_free(char *arg); + +#endif /* __ARG_H__ */ diff --git a/autostart.c b/autostart.c new file mode 100644 index 000000000..1fe80f59b --- /dev/null +++ b/autostart.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: autostart.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of module for automatically starting and exiting a list of processes. + * \author + * Adam Dunkels + */ + +#include "sys/autostart.h" + +/*---------------------------------------------------------------------------*/ +void +autostart_start(struct process *processes[]) +{ + int i; + + for(i = 0; processes[i] != NULL; ++i) { + process_start(processes[i], NULL); + } +} +/*---------------------------------------------------------------------------*/ +void +autostart_exit(struct process *processes[]) +{ + int i; + + for(i = 0; processes[i] != NULL; ++i) { + process_exit(processes[i]); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/autostart.h b/autostart.h new file mode 100644 index 000000000..74ae81c6f --- /dev/null +++ b/autostart.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: autostart.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \file + * Header file for module for automatically starting and exiting a list of processes. + * \author + * Adam Dunkels + */ + +#ifndef __AUTOSTART_H__ +#define __AUTOSTART_H__ + +#include "sys/process.h" + +#if ! CC_NO_VA_ARGS +#if AUTOSTART_ENABLE +#define AUTOSTART_PROCESSES(...) \ +const struct process *autostart_processes[] = {__VA_ARGS__, NULL}; +#else /* AUTOSTART_ENABLE */ +#define AUTOSTART_PROCESSES(...) +#endif /* AUTOSTART_ENABLE */ +#else +#error "C compiler must support __VA_ARGS__ macro" +#endif + +extern const struct process *autostart_processes[]; + +void autostart_start(struct process *processes[]); +void autostart_exit(struct process *processes[]); + +#endif /* __AUTOSTART_H__ */ diff --git a/cc.h b/cc.h new file mode 100644 index 000000000..af23545f3 --- /dev/null +++ b/cc.h @@ -0,0 +1,111 @@ +/** + * \file + * Default definitions of C compiler quirk work-arounds. + * \author Adam Dunkels + * + * This file is used for making use of extra functionality of some C + * compilers used for Contiki, and defining work-arounds for various + * quirks and problems with some other C compilers. + */ + +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop OS + * + * $Id: cc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "contiki-conf.h" + +/** + * Configure if the C compiler supports the "register" keyword for + * function arguments. + */ +#if CC_CONF_REGISTER_ARGS +#define CC_REGISTER_ARG register +#else /* CC_CONF_REGISTER_ARGS */ +#define CC_REGISTER_ARG +#endif /* CC_CONF_REGISTER_ARGS */ + +/** + * Configure if the C compiler supports the arguments for function + * pointers. + */ +#if CC_CONF_FUNCTION_POINTER_ARGS +#define CC_FUNCTION_POINTER_ARGS 1 +#else /* CC_CONF_FUNCTION_POINTER_ARGS */ +#define CC_FUNCTION_POINTER_ARGS 0 +#endif /* CC_CONF_FUNCTION_POINTER_ARGS */ + +/** + * Configure if the C compiler supports fastcall function + * declarations. + */ +#ifdef CC_CONF_FASTCALL +#define CC_FASTCALL CC_CONF_FASTCALL +#else /* CC_CONF_FASTCALL */ +#define CC_FASTCALL +#endif /* CC_CONF_FASTCALL */ + +/** + * Configure work-around for unsigned char bugs with sdcc. + */ +#if CC_CONF_UNSIGNED_CHAR_BUGS +#define CC_UNSIGNED_CHAR_BUGS 1 +#else /* CC_CONF_UNSIGNED_CHAR_BUGS */ +#define CC_UNSIGNED_CHAR_BUGS 0 +#endif /* CC_CONF_UNSIGNED_CHAR_BUGS */ + +/** + * Configure if C compiler supports double hash marks in C macros. + */ +#if CC_CONF_DOUBLE_HASH +#define CC_DOUBLE_HASH 1 +#else /* CC_CONF_DOUBLE_HASH */ +#define CC_DOUBLE_HASH 0 +#endif /* CC_CONF_DOUBLE_HASH */ + +#ifdef CC_CONF_INLINE +#define CC_INLINE CC_CONF_INLINE +#else /* CC_CONF_INLINE */ +#define CC_INLINE +#endif /* CC_CONF_INLINE */ + +#if CC_CONF_NO_VA_ARGS +#define CC_NO_VA_ARGS CC_CONF_VA_ARGS +#endif + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ +#endif /* __CC_H__ */ diff --git a/clock.h b/clock.h new file mode 100644 index 000000000..be0d99cf6 --- /dev/null +++ b/clock.h @@ -0,0 +1,97 @@ +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup clock Clock library + * + * The clock library is the interface between Contiki and the platform + * specific clock functionality. The clock library performs a single + * function: measuring time. Additionally, the clock library provides + * a macro, CLOCK_SECOND, which corresponds to one second of system + * time. + * + * \note The clock library need in many cases not be used + * directly. Rather, the \ref timer "timer library" or the \ref etimer + * "event timers" should be used. + * + * \sa \ref timer "Timer library" + * \sa \ref etimer "Event timers" + * + * @{ + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: clock.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "contiki-conf.h" + +/** + * Initialize the clock library. + * + * This function initializes the clock library and should be called + * from the main() function of the system. + * + */ +void clock_init(void); + +/** + * Get the current clock time. + * + * This function returns the current system clock time. + * + * \return The current clock time, measured in system ticks. + */ +clock_time_t clock_time(void); + +void clock_delay(unsigned int); + +/** + * A second, measured in system clock time. + * + * \hideinitializer + */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif + +#endif /* __CLOCK_H__ */ + +/** @} */ +/** @} */ diff --git a/dsc.h b/dsc.h new file mode 100644 index 000000000..b89b52cfb --- /dev/null +++ b/dsc.h @@ -0,0 +1,128 @@ +/** + * \file + * Declaration of the DSC program description structure. + * \author Adam Dunkels + * + */ + +/** + * \addtogroup loader + * @{ + */ + +/** + * \page dsc The program description structure + * + * The Contiki DSC structure is used for describing programs. It + * includes a string describing the program, the name of the program + * file on disk (or a pointer to the programs initialization function + * for systems without disk support), a bitmap icon and a text version + * of the same icon. + * + * The DSC is saved into a file which can be loaded by programs such + * as the "Directory" application which reads all DSC files on disk + * and presents the icons and descriptions in a window. + * + */ + +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop environment + * + * $Id: dsc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __DSC_H__ +#define __DSC_H__ + +#include "ctk/ctk.h" + +/** + * The DSC program description structure. + * + * The DSC structure is used for describing a Contiki program. It + * includes a short textual description of the program, either the + * name of the program on disk, or a pointer to the init() function, + * and an icon for the program. + */ +struct dsc { + char *description; /**< A text string containing a one-line + description of the program */ + +#if WITH_LOADER_ARCH + char *prgname; /**< The name of the program on disk. */ +#else /* WITH_LOADER_ARCH */ + struct process *process; /**< A pointer to the program's process. */ +#endif /* WITH_LOADER_ARCH */ + + struct ctk_icon *icon; /**< A pointer to the ctk_icon structure for + the DSC. */ + +#if WITH_LOADER_ARCH + void *loadaddr; /**< The loading address of the DSC. Used by + the LOADER_UNLOAD() function when + deallocating the memory allocated for the + DSC when loading it. */ +#endif /* WITH_LOADER_ARCH */ +}; + +/** + * Intantiating macro for the DSC structure. + * + * \param dscname The name of the C variable which is to contain the + * DSC. + * + * \param description A one-line text describing the program. + * + * \param prgname The name of the program on disk. + * + * \param initfunc A pointer to the initialization function of the + * program. + * + * \param icon A pointer to the CTK icon. + */ +#if WITH_LOADER_ARCH +#define DSC(dscname, description, prgname, process, icon) \ + const struct dsc dscname = {description, prgname, icon} +#else /* WITH_LOADER_ARCH */ +#define DSC(dscname, description, prgname, process, icon) \ + PROCESS_NAME(process); \ + const struct dsc dscname = {description, &process, icon} +#endif /* WITH_LOADER_ARCH */ + +#define DSC_HEADER(name) extern struct dsc name; + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +/** @} */ + +#endif /* _DSC_H__ */ diff --git a/etimer.c b/etimer.c new file mode 100644 index 000000000..bd8c0f9da --- /dev/null +++ b/etimer.c @@ -0,0 +1,260 @@ +/** + * \addtogroup etimer + * @{ + */ + +/** + * \file + * Event timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: etimer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki-conf.h" + +#include "sys/etimer.h" +#include "sys/process.h" + +static struct etimer *timerlist; +static clock_time_t next_expiration; + +PROCESS(etimer_process, "Event timer"); +/*---------------------------------------------------------------------------*/ +static void +update_time(void) +{ + clock_time_t nextt; + struct etimer *t; + + if (timerlist == NULL) { + next_expiration = 0; + } else { + t = timerlist; + nextt = t->timer.start + t->timer.interval; + for(t = t->next; t != NULL; t = t->next) { + if(t->timer.start + t->timer.interval < nextt) { + nextt = t->timer.start + t->timer.interval; + } + } + next_expiration = nextt; + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(etimer_process, ev, data) +{ + struct etimer *t, *u; + + PROCESS_BEGIN(); + + timerlist = NULL; + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_EXITED) { + struct process *p = data; + + while(timerlist != NULL && timerlist->p == p) { + timerlist = timerlist->next; + } + + if(timerlist != NULL) { + t = timerlist; + while(t->next != NULL) { + if(t->next->p == p) { + t->next = t->next->next; + } else + t = t->next; + } + } + continue; + } else if(ev != PROCESS_EVENT_POLL) { + continue; + } + + again: + + u = NULL; + + for(t = timerlist; t != NULL; t = t->next) { + if(timer_expired(&t->timer)) { + if(process_post(t->p, PROCESS_EVENT_TIMER, t) == PROCESS_ERR_OK) { + + /* Reset the process ID of the event timer, to signal that the + etimer has expired. This is later checked in the + etimer_expired() function. */ + t->p = PROCESS_NONE; + if(u != NULL) { + u->next = t->next; + } else { + timerlist = t->next; + } + t->next = NULL; + update_time(); + goto again; + } else { + etimer_request_poll(); + } + } + u = t; + } + + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +etimer_request_poll(void) +{ + process_poll(&etimer_process); +} +/*---------------------------------------------------------------------------*/ +static void +add_timer(struct etimer *timer) +{ + struct etimer *t; + + if(timer->p != PROCESS_NONE) { + /* Timer not on list. */ + + for(t = timerlist; t != NULL; t = t->next) { + if(t == timer) { + /* Timer already on list, bail out. */ + update_time(); + return; + } + } + } + + timer->p = PROCESS_CURRENT(); + timer->next = timerlist; + timerlist = timer; + + update_time(); +} +/*---------------------------------------------------------------------------*/ +void +etimer_set(struct etimer *et, clock_time_t interval) +{ + timer_set(&et->timer, interval); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_reset(struct etimer *et) +{ + timer_reset(&et->timer); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_restart(struct etimer *et) +{ + timer_restart(&et->timer); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_adjust(struct etimer *et, int timediff) +{ + et->timer.start += timediff; + update_time(); +} +/*---------------------------------------------------------------------------*/ +int +etimer_expired(struct etimer *et) +{ + return et->p == PROCESS_NONE; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_expiration_time(struct etimer *et) +{ + return et->timer.start + et->timer.interval; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_start_time(struct etimer *et) +{ + return et->timer.start; +} +/*---------------------------------------------------------------------------*/ +int +etimer_pending(void) +{ + return timerlist != NULL; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_next_expiration_time(void) +{ + return etimer_pending() ? next_expiration : 0; +} +/*---------------------------------------------------------------------------*/ +void +etimer_stop(struct etimer *et) +{ + struct etimer *t; + + /* First check if et is the first event timer on the list. */ + if(et == timerlist) { + timerlist = timerlist->next; + update_time(); + } else { + /* Else walk through the list and try to find the item before the + et timer. */ + for(t = timerlist; t != NULL && t->next != et; t = t->next); + + if(t != NULL) { + /* We've found the item before the event timer that we are about + to remove. We point the items next pointer to the event after + the removed item. */ + t->next = et->next; + + update_time(); + } + } + + /* Remove the next pointer from the item to be removed. */ + et->next = NULL; + /* Set the timer as expired */ + et->p = PROCESS_NONE; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/etimer.h b/etimer.h new file mode 100644 index 000000000..40a98f52e --- /dev/null +++ b/etimer.h @@ -0,0 +1,242 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup etimer Event timers + * + * Event timers provides a way to generate timed events. An event + * timer will post an event to the process that set the timer when the + * event timer expires. + * + * An event timer is declared as a \c struct \c etimer and all access + * to the event timer is made by a pointer to the declared event + * timer. + * + * \sa \ref timer "Simple timer library" + * \sa \ref clock "Clock library" (used by the timer library) + * + * @{ + */ + + +/** + * \file + * Event timer header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: etimer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __ETIMER_H__ +#define __ETIMER_H__ + +#include "sys/timer.h" +#include "sys/process.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with etimer_set() before it can be used. + * + * \hideinitializer + */ +struct etimer { + struct timer timer; + struct etimer *next; + struct process *p; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * \brief Set an event timer. + * \param et A pointer to the event timer + * \param interval The interval before the timer expires. + * + * This function is used to set an event timer for a time + * sometime in the future. When the event timer expires, + * the event PROCESS_EVENT_TIMER will be posted to the + * process that called the etimer_set() function. + * + */ +void etimer_set(struct etimer *et, clock_time_t interval); + +/** + * \brief Reset an event timer with the same interval as was + * previously set. + * \param et A pointer to the event timer. + * + * This function resets the event timer with the same + * interval that was given to the event timer with the + * etimer_set() function. The start point of the interval + * is the exact time that the event timer last + * expired. Therefore, this function will cause the timer + * to be stable over time, unlike the etimer_restart() + * function. + * + * \sa etimer_restart() + */ +void etimer_reset(struct etimer *et); + +/** + * \brief Restart an event timer from the current point in time + * \param et A pointer to the event timer. + * + * This function restarts the event timer with the same + * interval that was given to the etimer_set() + * function. The event timer will start at the current + * time. + * + * \note A periodic timer will drift if this function is + * used to reset it. For periodic timers, use the + * etimer_reset() function instead. + * + * \sa etimer_reset() + */ +void etimer_restart(struct etimer *et); + +/** + * \brief Adjust the expiration time for an event timer + * \param et A pointer to the event timer. + * \param td The time difference to adjust the expiration time with. + * + * This function is used to adjust the time the event + * timer will expire. It can be used to synchronize + * periodic timers without the need to restart the timer + * or change the timer interval. + * + * \note This function should only be used for small + * adjustments. For large adjustments use etimer_set() + * instead. + * + * \note A periodic timer will drift unless the + * etimer_reset() function is used. + * + * \sa etimer_set() + * \sa etimer_reset() + */ +void etimer_adjust(struct etimer *et, int td); + +/** + * \brief Get the expiration time for the event timer. + * \param et A pointer to the event timer + * \return The expiration time for the event timer. + * + * This function returns the expiration time for an event timer. + */ +clock_time_t etimer_expiration_time(struct etimer *et); + +/** + * \brief Get the start time for the event timer. + * \param et A pointer to the event timer + * \return The start time for the event timer. + * + * This function returns the start time (when the timer + * was last set) for an event timer. + */ +clock_time_t etimer_start_time(struct etimer *et); + +/** + * \brief Check if an event timer has expired. + * \param et A pointer to the event timer + * \return Non-zero if the timer has expired, zero otherwise. + * + * This function tests if an event timer has expired and + * returns true or false depending on its status. + */ +int etimer_expired(struct etimer *et); + +/** + * \brief Stop a pending event timer. + * \param et A pointer to the pending event timer. + * + * This function stops an event timer that has previously + * been set with etimer_set() or etimer_reset(). After + * this function has been called, the event timer will not + * emit any event when it expires. + * + */ +void etimer_stop(struct etimer *et); + +/** @} */ + +/** + * \name Functions called from timer interrupts, by the system + * @{ + */ + +/** + * \brief Make the event timer aware that the clock has changed + * + * This function is used to inform the event timer module + * that the system clock has been updated. Typically, this + * function would be called from the timer interrupt + * handler when the clock has ticked. + */ +void etimer_request_poll(void); + +/** + * \brief Check if there are any non-expired event timers. + * \return True if there are active event timers, false if there are + * no active timers. + * + * This function checks if there are any active event + * timers that have not expired. + */ +int etimer_pending(void); + +/** + * \brief Get next event timer expiration time. + * \return Next expiration time of all pending event timers. + * If there are no pending event timers this function + * returns 0. + * + * This functions returns next expiration time of all + * pending event timers. + */ +clock_time_t etimer_next_expiration_time(void); + + +/** @} */ + +PROCESS_NAME(etimer_process); +#endif /* __ETIMER_H__ */ +/** @} */ +/** @} */ diff --git a/lc-addrlabels.h b/lc-addrlabels.h new file mode 100644 index 000000000..10578bedb --- /dev/null +++ b/lc-addrlabels.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc-addrlabels.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on the "Labels as + * values" feature of gcc + * \author + * Adam Dunkels + * + * This implementation of local continuations is based on a special + * feature of the GCC C compiler called "labels as values". This + * feature allows assigning pointers with the address of the code + * corresponding to a particular C label. + * + * For more information, see the GCC documentation: + * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html + * + * Thanks to dividuum for finding the nice local scope label + * implementation. + */ + +#ifndef __LC_ADDRLABELS_H__ +#define __LC_ADDRLABELS_H__ + +/** \hideinitializer */ +typedef void * lc_t; + +#define LC_INIT(s) s = NULL + + +#define LC_RESUME(s) \ + do { \ + if(s != NULL) { \ + goto *s; \ + } \ + } while(0) + +#define LC_SET(s) \ + do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0) + +#define LC_END(s) + +#endif /* __LC_ADDRLABELS_H__ */ +/** @} */ diff --git a/lc-switch.h b/lc-switch.h new file mode 100644 index 000000000..64050f7e6 --- /dev/null +++ b/lc-switch.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc-switch.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on switch() statment + * \author Adam Dunkels + * + * This implementation of local continuations uses the C switch() + * statement to resume execution of a function somewhere inside the + * function's body. The implementation is based on the fact that + * switch() statements are able to jump directly into the bodies of + * control structures such as if() or while() statmenets. + * + * This implementation borrows heavily from Simon Tatham's coroutines + * implementation in C: + * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html + */ + +#ifndef __LC_SWITCH_H__ +#define __LC_SWTICH_H__ + +/* WARNING! lc implementation using switch() does not work if an + LC_SET() is done within another switch() statement! */ + +/** \hideinitializer */ +typedef unsigned short lc_t; + +#define LC_INIT(s) s = 0; + +#define LC_RESUME(s) switch(s) { case 0: + +#define LC_SET(s) s = __LINE__; case __LINE__: + +#define LC_END(s) } + +#endif /* __LC_SWITCH_H__ */ + +/** @} */ diff --git a/lc.h b/lc.h new file mode 100644 index 000000000..33c472c9a --- /dev/null +++ b/lc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup lc Local continuations + * @{ + * + * Local continuations form the basis for implementing protothreads. A + * local continuation can be set in a specific function to + * capture the state of the function. After a local continuation has + * been set can be resumed in order to restore the state of the + * function at the point where the local continuation was set. + * + * + */ + +/** + * \file lc.h + * Local continuations + * \author + * Adam Dunkels + * + */ + +#ifdef DOXYGEN +/** + * Initialize a local continuation. + * + * This operation initializes the local continuation, thereby + * unsetting any previously set continuation state. + * + * \hideinitializer + */ +#define LC_INIT(lc) + +/** + * Set a local continuation. + * + * The set operation saves the state of the function at the point + * where the operation is executed. As far as the set operation is + * concerned, the state of the function does not include the + * call-stack or local (automatic) variables, but only the program + * counter and such CPU registers that needs to be saved. + * + * \hideinitializer + */ +#define LC_SET(lc) + +/** + * Resume a local continuation. + * + * The resume operation resumes a previously set local continuation, thus + * restoring the state in which the function was when the local + * continuation was set. If the local continuation has not been + * previously set, the resume operation does nothing. + * + * \hideinitializer + */ +#define LC_RESUME(lc) + +/** + * Mark the end of local continuation usage. + * + * The end operation signifies that local continuations should not be + * used any more in the function. This operation is not needed for + * most implementations of local continuation, but is required by a + * few implementations. + * + * \hideinitializer + */ +#define LC_END(lc) + +/** + * \var typedef lc_t; + * + * The local continuation type. + * + * \hideinitializer + */ +#endif /* DOXYGEN */ + +#ifndef __LC_H__ +#define __LC_H__ + +#ifdef LC_CONF_INCLUDE +#include LC_CONF_INCLUDE +#else /* LC_CONF_INCLUDE */ +#include "sys/lc-switch.h" +#endif /* LC_CONF_INCLUDE */ + +#endif /* __LC_H__ */ + +/** @} */ +/** @} */ diff --git a/loader.h b/loader.h new file mode 100644 index 000000000..cff06e849 --- /dev/null +++ b/loader.h @@ -0,0 +1,132 @@ +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup loader The Contiki program loader + * + * The Contiki program loader is an abstract interface for loading and + * starting programs. + * + * @{ + */ + +/** + * \file + * Default definitions and error values for the Contiki program loader. + * \author Adam Dunkels + * + */ + +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop OS + * + * $Id: loader.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __LOADER_H__ +#define __LOADER_H__ + +/* Errors that the LOADER_LOAD() function may return: */ + +#define LOADER_OK 0 /**< No error. */ +#define LOADER_ERR_READ 1 /**< Read error. */ +#define LOADER_ERR_HDR 2 /**< Header error. */ +#define LOADER_ERR_OS 3 /**< Wrong OS. */ +#define LOADER_ERR_FMT 4 /**< Data format error. */ +#define LOADER_ERR_MEM 5 /**< Not enough memory. */ +#define LOADER_ERR_OPEN 6 /**< Could not open file. */ +#define LOADER_ERR_ARCH 7 /**< Wrong architecture. */ +#define LOADER_ERR_VERSION 8 /**< Wrong OS version. */ +#define LOADER_ERR_NOLOADER 9 /**< Program loading not supported. */ + +#ifdef LOADER_CONF_ARCH +#include LOADER_CONF_ARCH +#endif /* LOADER_CONF_ARCH */ + +/** + * Load and execute a program. + * + * This macro is used for loading and executing a program, and + * requires support from the architecture dependant code. The actual + * program loading is made by architecture specific functions. + * + * \note A program loaded with LOADER_LOAD() must call the + * LOADER_UNLOAD() function to unload itself. + * + * \param name The name of the program to be loaded. + * + * \param arg A pointer argument that is passed to the program. + * + * \return A loader error, or LOADER_OK if loading was successful. + */ +#ifndef LOADER_LOAD +#define LOADER_LOAD(name, arg) LOADER_ERR_NOLOADER +#endif /* LOADER_LOAD */ + +/** + * Unload a program from memory. + * + * This macro is used for unloading a program and deallocating any + * memory that was allocated during the loading of the program. This + * function must be called by the program itself. + * + */ +#ifndef LOADER_UNLOAD +#define LOADER_UNLOAD() +#endif /* LOADER_UNLOAD */ + +/** + * Load a DSC (program description). + * + * Loads a DSC (program description) into memory and returns a pointer + * to the dsc. + * + * \return A pointer to the DSC or NULL if it could not be loaded. + */ +#ifndef LOADER_LOAD_DSC +#define LOADER_LOAD_DSC(name) NULL +#endif /* LOADER_LOAD_DSC */ + +/** + * Unload a DSC (program description). + * + * Unload a DSC from memory and deallocate any memory that was + * allocated when it was loaded. + */ +#ifndef LOADER_UNLOAD_DSC +#define LOADER_UNLOAD_DSC(dsc) +#endif /* LOADER_UNLOAD */ + +#endif /* __LOADER_H__ */ + +/** @} */ +/** @} */ diff --git a/log.h b/log.h new file mode 100644 index 000000000..2460210fa --- /dev/null +++ b/log.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: log.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include "contiki-conf.h" + +#if LOG_CONF_ENABLED +void log_message(const char *part1, const char *part2); +#else /* LOG_CONF_ENABLED */ +#define log_message(p1, p2) +#endif /* LOG_CONF_ENABLED */ + +#endif /* __LOG_H__ */ diff --git a/mt.c b/mt.c new file mode 100644 index 000000000..0efea5793 --- /dev/null +++ b/mt.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: mt.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of the archtecture agnostic parts of the preemptive + * multithreading library for Contiki. + * + * \author + * Adam Dunkels + * + */ + +#include "contiki.h" +#include "sys/mt.h" +#include "sys/cc.h" + +#define MT_STATE_READY 1 +#define MT_STATE_RUNNING 2 +#define MT_STATE_WAITING 3 +#define MT_STATE_PEEK 4 +#define MT_STATE_EXITED 5 + +static struct mt_thread *current; + +/*--------------------------------------------------------------------------*/ +void +mt_init(void) +{ + mtarch_init(); +} +/*--------------------------------------------------------------------------*/ +void +mt_remove(void) +{ + mtarch_remove(); +} +/*--------------------------------------------------------------------------*/ +void +mt_start(struct mt_thread *thread, void (* function)(void *), void *data) +{ + /* Call the architecture dependant function to set up the processor + stack with the correct parameters. */ + mtarch_start(&thread->thread, function, data); + + thread->state = MT_STATE_READY; +} +/*--------------------------------------------------------------------------*/ +void +mt_exec(struct mt_thread *thread) +{ + if(thread->state == MT_STATE_READY || + thread->state == MT_STATE_PEEK) { + thread->state = MT_STATE_RUNNING; + current = thread; + /* Switch context to the thread. The function call will not return + until the the thread has yielded, or is preempted. */ + /*printf("swtis\n");*/ + mtarch_exec(&thread->thread); + } +} +/*--------------------------------------------------------------------------*/ +void +mt_exit(void) +{ + current->state = MT_STATE_EXITED; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mt_exec_event(struct mt_thread *thread, process_event_t ev, + process_data_t data) +{ + if(thread->state == MT_STATE_WAITING || + thread->state == MT_STATE_PEEK) { + *(thread->evptr) = ev; + *(thread->dataptr) = data; + thread->state = MT_STATE_RUNNING; + current = thread; + /* Switch context to the thread. The function call will not return + until the the thread has yielded, or is preempted. */ + mtarch_exec(&thread->thread); + } +} +/*--------------------------------------------------------------------------*/ +void +mt_yield(void) +{ + mtarch_pstop(); + current->state = MT_STATE_READY; + current = NULL; + /* This function is called from the running thread, and we call the + switch function in order to switch the thread to the main Contiki + program instead. For us, the switch function will not return + until the next time we are scheduled to run. */ + mtarch_yield(); + +} +/*--------------------------------------------------------------------------*/ +void +mt_post(struct process *p, process_event_t ev, + process_data_t data) +{ + /* Turn off preemption to ensure mutual exclusion of kernel. */ + mtarch_pstop(); + + process_post(p, ev, data); + + /* Turn preemption on again. */ + mtarch_pstart(); +} +/*--------------------------------------------------------------------------*/ +void +mt_wait(process_event_t *ev, process_data_t *data) +{ + mtarch_pstop(); + current->evptr = ev; + current->dataptr = data; + current->state = MT_STATE_WAITING; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mt_peek(process_event_t *ev, process_data_t *data) +{ + mtarch_pstop(); + *ev = PROCESS_EVENT_NONE; + current->evptr = ev; + current->dataptr = data; + current->state = MT_STATE_PEEK; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mtp_start(struct mt_process *t, + void (* function)(void *), void *data) +{ + mt_start(&t->t, function, data); + process_start(t->p, function); +} +/*--------------------------------------------------------------------------*/ +void +mtp_exit(void) +{ + mtarch_pstop(); + mt_exit(); + mt_remove(); +} +/*--------------------------------------------------------------------------*/ +/*void +mtp_eventhandler(ek_event_t ev, ek_data_t data) +{ + struct mtp_thread *thread = (struct mtp_thread *)EK_PROC_STATE(EK_CURRENT()); + + if(ev == EK_EVENT_REQUEST_EXIT) { + ek_exit(); + LOADER_UNLOAD(); + + } else if(ev == EK_EVENT_INIT) { + + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + + } else if(ev == EK_EVENT_CONTINUE) { + + if(thread->t.state == MT_STATE_READY || + thread->t.state == MT_STATE_PEEK) { + mt_exec(&thread->t); + if(thread->t.state == MT_STATE_EXITED) { + ek_exit(); + LOADER_UNLOAD(); + } else { + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + } + } + } else { + mt_exec_event(&thread->t, ev, data); + if(thread->t.state == MT_STATE_EXITED) { + ek_exit(); + LOADER_UNLOAD(); + } else if(thread->t.state == MT_STATE_READY || + thread->t.state == MT_STATE_PEEK) { + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + } + } +}*/ +/*--------------------------------------------------------------------------*/ diff --git a/mt.h b/mt.h new file mode 100644 index 000000000..242f76d75 --- /dev/null +++ b/mt.h @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: mt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup mt Multi-threading library + * + * The event driven Contiki kernel does not provide multi-threading + * by itself - instead, preemptive multi-threading is implemented + * as a library that optionally can be linked with applications. This + * library constists of two parts: a platform independent part, which is + * the same for all platforms on which Contiki runs, and a platform + * specific part, which must be implemented specifically for the + * platform that the multi-threading library should run. + * + * @{ + */ + +/** + * \defgroup mtarch Architecture support for multi-threading + * @{ + * + * The Contiki multi-threading library requires some architecture + * specific support for seting up and switching stacks. This support + * requires three stack manipulation functions to be implemented: + * mtarch_start(), which sets up the stack frame for a new thread, + * mtarch_exec(), which switches in the stack of a thread, and + * mtarch_yield(), which restores the kernel stack from a thread's + * stack. Additionally, two functions for controlling the preemption + * (if any) must be implemented: mtarch_preemption_start() and + * mtarch_preemption_stop(). If no preemption is used, these functions + * can be implemented as empty functions. Finally, the function + * mtarch_init() is called by mt_init(), and can be used for + * initalization of timer interrupts, or any other mechanisms required + * for correct operation of the architecture specific support funcions. + * + */ + +/** + * \file + * Header file for the preemptive multitasking library for Contiki. + * \author + * Adam Dunkels + * + */ +#ifndef __MT_H__ +#define __MT_H__ + +#include "contiki.h" + + +/** + * An opaque structure that is used for holding the state of a thread. + * + * The structure should be defined in the "mtarch.h" file. This + * structure typically holds the entire stack for the thread. + */ +struct mtarch_thread; + +/** + * Initialize the architecture specific support functions for the + * multi-thread library. + * + * This function is implemented by the architecture specific functions + * for the multi-thread library and is called by the mt_init() + * function as part of the initialization of the library. The + * mtarch_init() function can be used for, e.g., starting preemtion + * timers or other architecture specific mechanisms required for the + * operation of the library. + */ +void mtarch_init(void); + +/** + * Uninstall library and clean up. + * + */ +void mtarch_remove(void); + +/** + * Setup the stack frame for a thread that is being started. + * + * This function is called by the mt_start() function in order to set + * up the architecture specific stack of the thread to be started. + * + * \param thread A pointer to a struct mtarch_thread for the thread to + * be started. + * + * \param function A pointer to the function that the thread will + * start executing the first time it is scheduled to run. + * + * \param data A pointer to the argument that the function should be + * passed. + */ +void mtarch_start(struct mtarch_thread *thread, + void (* function)(void *data), + void *data); + +/** + * Yield the processor. + * + * This function is called by the mt_yield() function, which is called + * from the running thread in order to give up the processor. + * + */ +void mtarch_yield(void); + +/** + * Start executing a thread. + * + * This function is called from mt_exec() and the purpose of the + * function is to start execution of the thread. The function should + * switch in the stack of the thread, and does not return until the + * thread has explicitly yielded (using mt_yield()) or until it is + * preempted. + * + */ +void mtarch_exec(struct mtarch_thread *thread); + + +void mtarch_pstart(void); +void mtarch_pstop(void); + +/** @} */ + + +#include "mtarch.h" + +struct mt_thread { + int state; + process_event_t *evptr; + process_data_t *dataptr; + struct mtarch_thread thread; +}; + +/** + * No error. + * + * \hideinitializer + */ +#define MT_OK 1 + +/** + * Initializes the multithreading library. + * + */ +void mt_init(void); + +/** + * Uninstalls library and cleans up. + * + */ +void mt_remove(void); + + +/** + * Starts a multithreading thread. + * + * \param thread Pointer to an mt_thread struct that must have been + * previously allocated by the caller. + * + * \param function A pointer to the entry function of the thread that is + * to be set up. + * + * \param data A pointer that will be passed to the entry function. + * + */ +void mt_start(struct mt_thread *thread, void (* function)(void *), void *data); + +/** + * Execute parts of a thread. + * + * This function is called by a Contiki process and runs a + * thread. The function does not return until the thread has yielded, + * or is preempted. + * + * \note The thread must first be initialized with the mt_init() function. + * + * \param thread A pointer to a struct mt_thread block that must be + * allocated by the caller. + * + */ +void mt_exec(struct mt_thread *thread); + +/** + * Post an event to a thread. + * + * This function posts an event to a thread. The thread will be + * scheduled if the thread currently is waiting for the posted event + * number. If the thread is not waiting for the event, this function + * does nothing. + * + * \note The thread must first be initialized with the mt_init() function. + * + * \param thread A pointer to a struct mt_thread block that must be + * allocated by the caller. + * + * \param s The event that is posted to the thread. + * + * \param data An opaque pointer to a user specified structure + * containing additonal information, or NULL if no additional + * information is needed. + */ +void mt_exec_event(struct mt_thread *thread, process_event_t s, + process_data_t data); + +/** + * Voluntarily give up the processor. + * + * This function is called by a running thread in order to give up + * control of the CPU. + * + */ +void mt_yield(void); + +/** + * Post an event to another process. + * + * This function is called by a running thread and will emit a signal + * to another Contiki process. This will cause the currently executing + * thread to yield. + * + * \param p The process receiving the signal, or PROCESS_BROADCAST + * for a broadcast event. + * + * \param ev The event to be posted. + * + * \param data A pointer to a message that is to be delivered together + * with the signal. + * + */ +void mt_post(struct process *p, process_event_t ev, process_data_t data); + +/** + * Block and wait for an event to occur. + * + * This function can be called by a running thread in order to block + * and wait for an event. The function returns when an event has + * occured. The event number and the associated data are placed in the + * variables pointed to by the function arguments. + * + * \param ev A pointer to a process_event_t variable. The variable + * will be filled with the number event that woke the thread. + * + * \param data A pointer to a process_data_t variable. The variable + * will be filled with the data associated with the event that woke + * the thread. + * + */ +void mt_wait(process_event_t *ev, process_data_t *data); + +/** + * Exit a thread. + * + * This function is called from within an executing thread in order to + * exit the thread. The function never returns. + * + */ +void mt_exit(void); + +/** + * \defgroup mtp Multi-threading library convenience functions + * @{ + * + * The Contiki multi-threading library has an interface that might be + * hard to use. Therefore, the mtp module provides a simpler + * interface. + * + * Example: +\code +static void +example_thread_code(void *data) +{ + while(1) { + printf("Test\n"); + mt_yield(); + } +} +MTP(example_thread, "Example thread", p1, t1, t1_idle); + +int +main(int argc, char *argv[]) +{ + mtp_start(&example_thread, example_thread_code, NULL); +} +\endcode +* +*/ + + +/** + * Declare a multithreaded process. + * + * This macro is used to declare a multithreaded process. + * + * \hideinitializer + */ +#define MT_PROCESS(name, strname) \ +extern struct mt_process name##mt_process; \ +struct process name = { NULL, strname, mt_process_thread }; \ +static struct mt_process thread = {&name} + +struct mt_process { + struct process *p; + struct mt_thread t; +}; + +/** + * Start a thread. + * + * This function starts the process in which the thread is to run, and + * also sets up the thread to run within the process. The function + * should be passed variable names declared with the MTP() macro. + * + * \param t A pointer to a thread structure previously declared with MTP(). + * + * \param function A pointer to the function that the thread should + * start executing. + * + * \param data A pointer that the function should be passed when first + * invocated. + */ +void mtp_start(struct mt_process *p, + void (* function)(void *), void *data); + +void mtp_exit(void); +void mtp_eventhandler(process_event_t ev, process_data_t data); + +/** @} */ +/** @} */ +/** @} */ +#endif /* __MT_H__ */ diff --git a/process.c b/process.c new file mode 100644 index 000000000..7e7ce9648 --- /dev/null +++ b/process.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: process.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup process + * @{ + */ + +/** + * \file + * Implementation of the Contiki process kernel. + * \author + * Adam Dunkels + * + */ + +#include + +#include "sys/process.h" +#include "sys/arg.h" + +/* + * Pointer to the currently running process structure. + */ +struct process *process_list = NULL; +struct process *process_current = NULL; + +static process_event_t lastevent; + +/* + * Structure used for keeping the queue of active events. + */ +struct event_data { + process_event_t ev; + process_data_t data; + struct process *p; +}; + +#ifdef PROCESS_CONF_FASTPOLL +#define NPOLLS PROCESS_CONF_FASTPOLL +#include +static volatile unsigned npolls; +static struct process *needpoll[NPOLLS]; +#endif +static process_num_events_t nevents, fevent; +static struct event_data events[PROCESS_CONF_NUMEVENTS]; + +static volatile unsigned char poll_requested; + +#define PROCESS_STATE_NONE 0 +#define PROCESS_STATE_INIT 1 +#define PROCESS_STATE_RUNNING 2 +#define PROCESS_STATE_NEEDS_POLL 3 + +static void call_process(struct process *p, process_event_t ev, process_data_t data); + + +/*---------------------------------------------------------------------------*/ +process_event_t +process_alloc_event(void) +{ + return lastevent++; +} +/*---------------------------------------------------------------------------*/ +void +process_start(struct process *p, char *arg) +{ + struct process *q; + + /* First make sure that we don't try to start a process that is + already running. */ + for(q = process_list; q != p && q != NULL; q = q->next); + + /* If we found the process on the process list, we bail out. */ + if(q == p) { + return; + } + /* Put on the procs list.*/ + p->next = process_list; + process_list = p; + + p->state = PROCESS_STATE_INIT; + + PT_INIT(&p->pt); + + /* Post an asynchronous event to the process. */ + process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); +} +/*---------------------------------------------------------------------------*/ +static void +exit_process(struct process *p, struct process *fromprocess) +{ + register struct process *q; + struct process *old_current = process_current; + + if(p->state != PROCESS_STATE_NONE) { + /* Process was running */ + p->state = PROCESS_STATE_NONE; + + /* + * Post a synchronous event to all processes to inform them that + * this process is about to exit. This will allow services to + * deallocate state associated with this process. + */ + for(q = process_list; q != NULL; q = q->next) { + if(p != q) { + call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p); + } + } + + if(p->thread != NULL && p != fromprocess) { + /* Post the exit event to the process that is about to exit. */ + process_current = p; + p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL); + } + } + + if(p == process_list) { + process_list = process_list->next; + } else { + for(q = process_list; q != NULL; q = q->next) { + if(q->next == p) { + q->next = p->next; + break; + } + } + } + + { + int n; + int i = fevent; + for(n = nevents; n > 0; n--) { + if(events[i].p == p) { + events[i].p = PROCESS_ZOMBIE; +#if 0 + printf("soft panic: exiting process has remaining event 0x%x\n", + events[i].ev); +#endif + } + i = (i + 1) % PROCESS_CONF_NUMEVENTS; + } +#ifdef NPOLLS + for(i = 0; i < NPOLLS && i < npolls; i++) { + if(needpoll[i] == p) { + needpoll[i] = PROCESS_ZOMBIE; + } + } +#endif + } + process_current = old_current; +} +/*---------------------------------------------------------------------------*/ +static void +call_process(struct process *p, process_event_t ev, process_data_t data) +{ + int ret; + + if((p->state == PROCESS_STATE_RUNNING || + p->state == PROCESS_STATE_NEEDS_POLL) && + p->thread != NULL) { + process_current = p; + + ret = p->thread(&p->pt, ev, data); + if(ret == PT_EXITED || + ret == PT_ENDED || + ev == PROCESS_EVENT_EXIT) { + exit_process(p, p); + } + } +} +/*---------------------------------------------------------------------------*/ +void +process_exit(struct process *p) +{ + exit_process(p, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +process_init(void) +{ + lastevent = PROCESS_EVENT_MAX; + + nevents = fevent = 0; + + process_current = process_list = NULL; +} +/*---------------------------------------------------------------------------*/ +/* + * Call each process' poll handler. + */ +/*---------------------------------------------------------------------------*/ +static void +do_poll(void) +{ + struct process *p; + + poll_requested = 0; + +#ifdef NPOLLS + unsigned i; + int s; + /* Fastpoll */ + //printf("F %d\n", npolls); + for(i = 0; i < npolls; i++) { + do_more: + if(i == NPOLLS) { + goto slowpoll; + } + if(needpoll[i] != PROCESS_ZOMBIE + && needpoll[i]->state == PROCESS_STATE_NEEDS_POLL) { + needpoll[i]->state = PROCESS_STATE_RUNNING; + call_process(needpoll[i], PROCESS_EVENT_POLL, NULL); + } + } + s = splhigh(); + if(i == npolls) { + npolls = 0; + splx(s); + return; + } + splx(s); + goto do_more; + + /* Call poll handlers. */ + slowpoll: + //printf("S %d\n", npolls); + npolls = 0; +#endif + /* Call poll handlers. */ + for(p = process_list; p != NULL; p = p->next) { + + if(p->state == PROCESS_STATE_NEEDS_POLL) { + p->state = PROCESS_STATE_RUNNING; + call_process(p, PROCESS_EVENT_POLL, NULL); + } + +#if 0 + /* If a poll has been requested for one of the processes, we start + from the beginning again. */ + if(poll_requested) { + poll_requested = 0; + p = process_list; + } +#endif + } +} +/*---------------------------------------------------------------------------*/ +/* + * Process the next event in the event queue and deliver it to + * listening processes. + */ +/*---------------------------------------------------------------------------*/ +static void +do_event(void) +{ + static process_event_t ev; + static process_data_t data; + static struct process *receiver; + static struct process *p; + + /* + * If there are any events in the queue, take the first one and walk + * through the list of processes to see if the event should be + * delivered to any of them. If so, we call the event handler + * function for the process. We only process one event at a time and + * call the poll handlers inbetween. + */ + + if(nevents > 0) { + + /* There are events that we should deliver. */ + ev = events[fevent].ev; + + data = events[fevent].data; + receiver = events[fevent].p; + + /* Since we have seen the new event, we move pointer upwards + and decrese the number of events. */ + fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS; + --nevents; + + /* If this is a broadcast event, we deliver it to all events, in + order of their priority. */ + if(receiver == PROCESS_BROADCAST) { + for(p = process_list; p != NULL; p = p->next) { + + /* If we have been requested to poll a process, we do this in + between processing the broadcast event. */ + if(poll_requested) { + do_poll(); + } + call_process(p, ev, data); + } + } else if(receiver == PROCESS_ZOMBIE) { + /* This process has exited. */ + } else { + /* This is not a broadcast event, so we deliver it to the + specified process. */ + /* If the event was an INIT event, we should also update the + state of the process. */ + if(ev == PROCESS_EVENT_INIT) { + receiver->state = PROCESS_STATE_RUNNING; + } + + /* Make sure that the process actually is running. */ + call_process(receiver, ev, data); + } + } +} +/*---------------------------------------------------------------------------*/ +int +process_run(void) +{ + /* Process "poll" events. */ + if(poll_requested) { + do_poll(); + } + + /* Process one event */ + do_event(); + + return nevents + poll_requested; +} +/*---------------------------------------------------------------------------*/ +int +process_post(struct process *p, process_event_t ev, process_data_t data) +{ + static unsigned char snum; + + if(nevents == PROCESS_CONF_NUMEVENTS) { + printf("soft panic: event queue is full\n"); + return PROCESS_ERR_FULL; + } + + snum = (fevent + nevents) % PROCESS_CONF_NUMEVENTS; + events[snum].ev = ev; + events[snum].data = data; + events[snum].p = p; + ++nevents; + + return PROCESS_ERR_OK; +} +/*---------------------------------------------------------------------------*/ +void +process_post_synch(struct process *p, process_event_t ev, process_data_t data) +{ + struct process *caller = process_current; + + call_process(p, ev, data); + process_current = caller; +} +/*---------------------------------------------------------------------------*/ +void +process_poll(struct process *p) +{ + if(p != NULL) { + if(p->state == PROCESS_STATE_RUNNING) { + p->state = PROCESS_STATE_NEEDS_POLL; + poll_requested = 1; +#ifdef NPOLLS + int s = splhigh(); + if(npolls < NPOLLS) { + needpoll[npolls] = p; + } + if(npolls != ~0u) npolls++; /* Beware of overflow! */ + splx(s); +#endif + } + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/process.h b/process.h new file mode 100644 index 000000000..1d689de30 --- /dev/null +++ b/process.h @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: process.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup process Contiki processes + * + * A process in Contiki consists of a single \ref pt protothread. + * + * @{ + */ + +/** + * \file + * Header file for the Contiki process interface. + * \author + * Adam Dunkels + * + */ +#ifndef __PROCESS_H__ +#define __PROCESS_H__ + +#include "sys/pt.h" +#include "sys/cc.h" + +typedef unsigned char process_event_t; +typedef void * process_data_t; +typedef unsigned char process_num_events_t; + +/** + * \name Return values + * @{ + */ + +/** + * \brief Return value indicating that an operation was successful. + * + * This value is returned to indicate that an operation + * was successful. + */ +#define PROCESS_ERR_OK 0 +/** + * \brief Return value indicating that the event queue was full. + * + * This value is returned from process_post() to indicate + * that the event queue was full and that an event could + * not be posted. + */ +#define PROCESS_ERR_FULL 1 +/* @} */ + +#define PROCESS_NONE NULL + +#ifndef PROCESS_CONF_NUMEVENTS +#define PROCESS_CONF_NUMEVENTS 32 +#endif /* PROCESS_CONF_NUMEVENTS */ + +#define PROCESS_EVENT_NONE 0x80 +#define PROCESS_EVENT_INIT 0x81 +#define PROCESS_EVENT_POLL 0x82 +#define PROCESS_EVENT_EXIT 0x83 +#define PROCESS_EVENT_SERVICE_REMOVED 0x84 +#define PROCESS_EVENT_CONTINUE 0x85 +#define PROCESS_EVENT_MSG 0x86 +#define PROCESS_EVENT_EXITED 0x87 +#define PROCESS_EVENT_TIMER 0x88 +#define PROCESS_EVENT_MAX 0x89 + +#define PROCESS_BROADCAST NULL +#define PROCESS_ZOMBIE ((struct process *)0x1) + +/** + * \name Process protothread functions + * @{ + */ + +/** + * Define the beginning of a process. + * + * This macro defines the beginning of a process, and must always + * appear in a PROCESS_THREAD() definition. The PROCESS_END() macro + * must come at the end of the process. + * + * \hideinitializer + */ +#define PROCESS_BEGIN() PT_BEGIN(process_pt) + +/** + * Define the end of a process. + * + * This macro defines the end of a process. It must appear in a + * PROCESS_THREAD() definition and must always be included. The + * process exits when the PROCESS_END() macro is reached. + * + * \hideinitializer + */ +#define PROCESS_END() PT_END(process_pt) + +/** + * Wait for an event to be posted to the process. + * + * This macro blocks the currently running process until the process + * receives an event. + * + * \hideinitializer + */ +#define PROCESS_WAIT_EVENT() PROCESS_YIELD() + +/** + * Wait for an event to be posted to the process, with an extra + * condition. + * + * This macro is similar to PROCESS_WAIT_EVENT() in that it blocks the + * currently running process until the process receives an event. But + * PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be + * true for the process to continue. + * + * \param c The condition that must be true for the process to continue. + * \sa PT_WAIT_UNTIL() + * + * \hideinitializer + */ +#define PROCESS_WAIT_EVENT_UNTIL(c) PROCESS_YIELD_UNTIL(c) + +/** + * Yield the currently running process. + * + * \hideinitializer + */ +#define PROCESS_YIELD() PT_YIELD(process_pt) + +/** + * Yield the currently running process until a condition occurs. + * + * This macro is different from PROCESS_WAIT_UNTIL() in that + * PROCESS_YIELD_UNTIL() is guaranteed to always yield at least + * once. This ensures that the process does not end up in an infinite + * loop and monopolizing the CPU. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c) + +/** + * Wait for a condition to occur. + * + * This macro does not guarantee that the process yields, and should + * therefore be used with care. In most cases, PROCESS_WAIT_EVENT(), + * PROCESS_WAIT_EVENT_UNTIL(), PROCESS_YIELD() or + * PROCESS_YIELD_UNTIL() should be used instead. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c) + +/** + * Exit the currently running process. + * + * \hideinitializer + */ +#define PROCESS_EXIT() PT_EXIT(process_pt) + +/** + * Spawn a protothread from the process. + * + * \param pt The protothread state (struct pt) for the new protothread + * \param thread The call to the protothread function. + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PROCESS_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) + +/** + * Yield the process for a short while. + * + * This macro yields the currently running process for a short while, + * thus letting other processes run before the process continues. + * + * \hideinitializer + */ +#define PROCESS_PAUSE() do { \ + process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \ + PROCESS_WAIT_EVENT(); \ +} while(0) + +/** @} end of protothread functions */ + +/** + * \name Poll and exit handlers + * @{ + */ +/** + * Specify an action when a process is polled. + * + * \note This declaration must come immediately before the + * PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define PROCESS_POLLHANDLER(handler) if(ev == PROCESS_EVENT_POLL) { handler; } + +/** + * Specify an action when a process exits. + * + * \note This declaration must come immediately before the + * PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define PROCESS_EXITHANDLER(handler) if(ev == PROCESS_EVENT_EXIT) { handler; } + +/** @} */ + +/** + * \name Process declaration and definion + * @{ + */ + +/** + * Define the body of a process. + * + * This macro is used to define the body (protothread) of a + * process. The process is called whenever an event occurs in the + * system, A process always start with the PROCESS_BEGIN() macro and + * end with the PROCESS_END() macro. + * + * \hideinitializer + */ +#define PROCESS_THREAD(name, ev, data) \ +static PT_THREAD(process_thread_##name(struct pt *process_pt, \ + process_event_t ev, \ + process_data_t data)) + +#if PROCESS_LOADABLE +#define PROCESS_LOAD(name) const struct process *process_load = &name; +#else /* PROCESS_LOADABLE */ +#define PROCESS_LOAD(name) +#endif /* PROCESS_LOADABLE */ +extern const struct process *process_load; + +/** + * Declare the name of a process. + * + * This macro is typically used in header files to declare the name of + * a process that is implemented in the C file. + * + * \hideinitializer + */ +#define PROCESS_NAME(name) extern struct process name + +/** + * Declare a process that should not be automatically loaded. + * + * This macro is similar to the PROCESS() declaration, with the + * difference that for programs that are compiled as loadable + * programs, processes declared with the PROCESS_NOLOAD() declaration + * will not be automatically started when the program is loaded. + * + * \hideinitializer + */ +#define PROCESS_NOLOAD(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, strname, \ + process_thread_##name }; +/** + * Declare a process. + * + * This macro declares a process. The process has two names: the + * variable of the process structure, which is used by the C program, + * and a human readable string name, which is used when debugging. + * + * \note For programs that are compiled as loadable programs: the + * process declared with the PROCESS() declaration will be + * automatically started when the program is loaded. The + * PROCESS_NOLOAD() declaration can be used to declare a process that + * shouldn't be automatically loaded. + * + * \param name The variable name of the process structure. + * \param strname The string repressentation of the process' name. + * + * \hideinitializer + */ +#define PROCESS(name, strname) \ + PROCESS_NOLOAD(name, strname); \ + PROCESS_LOAD(name) + +/** @} */ + +struct process { + struct process *next; + const char *name; + PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); + struct pt pt; + unsigned char state; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * Start a process. + * + * \param p A pointer to a process structure. + * + * \param arg An argument pointer that can be passed to the new + * process + * + */ +void process_start(struct process *p, char *arg); + +/** + * Post an asynchronous event. + * + * This function posts an asynchronous event to one or more + * processes. The handing of the event is deferred until the target + * process is scheduled by the kernel. An event can be broadcast to + * all processes, in which case all processes in the system will be + * scheduled to handle the event. + * + * \param ev The event to be posted. + * + * \param data The auxillary data to be sent with the event + * + * \param p The process to which the event should be posted, or + * PROCESS_BROADCAST if the event should be posted to all processes. + * + * \retval PROCESS_ERR_OK The event could be posted. + * + * \retval PROCESS_ERR_FULL The event queue was full and the event could + * not be posted. + */ +int process_post(struct process *p, process_event_t ev, process_data_t data); + +/** + * Post a synchronous event to a process. + * + * \param p A pointer to the process' process structure. + * + * \param ev The event to be posted. + * + * \param data A pointer to additional data that is posted together + * with the event. + */ +void process_post_synch(struct process *p, + process_event_t ev, process_data_t data); + +/** + * \brief Cause a process to exit + * \param p The process that is to be exited + * + * This function causes a process to exit. The process can + * either be the currently executing process, or another + * process that is currently running. + * + * \sa PROCESS_CURRENT() + */ +void process_exit(struct process *p); + + +/** + * Get a pointer to the currently running process. + * + * This macro get a pointer to the currently running + * process. Typically, this macro is used to post an event to the + * current process with process_post(). + * + * \hideinitializer + */ +#define PROCESS_CURRENT() process_current +extern struct process *process_current; + +#define PROCESS_SET_FLAGS(flags) +#define PROCESS_NO_BROADCAST + +/** + * Switch context to another process + * + * This function switch context to the specified process and executes + * the code as if run by that process. Typical use of this function is + * to switch context in services, called by other processes. Each + * PROCESS_CONTEXT_BEGIN() must be followed by the + * PROCESS_CONTEXT_END() macro to end the context switch. + * + * Example: + \code + PROCESS_CONTEXT_BEGIN(&test_process); + etimer_set(&timer, CLOCK_SECOND); + PROCESS_CONTEXT_END(&test_process); + \endcode + * + * \param p The process to use as context + * + * \sa PROCESS_CONTEXT_END() + * \sa PROCESS_CURRENT() + */ +#define PROCESS_CONTEXT_BEGIN(p) {\ +struct process *tmp_current = PROCESS_CURRENT();\ +process_current = p + +/** + * End a context switch + * + * This function ends a context switch and changes back to the + * previous process. + * + * \param p The process used in the context switch + * + * \sa PROCESS_CONTEXT_START() + */ +#define PROCESS_CONTEXT_END(p) process_current = tmp_current; } + +/** + * \brief Allocate a global event number. + * \return The allocated event number + * + * In Contiki, event numbers above 128 are global and may + * be posted from one process to another. This function + * allocates one such event number. + * + * \note There currently is no way to deallocate an allocated event + * number. + */ +process_event_t process_alloc_event(void); + +/** @} */ + +/** + * \name Functions called from device drivers + * @{ + */ + +/** + * Request a process to be polled. + * + * This function typically is called from an interrupt handler to + * cause a process to be polled. + * + * \param p A pointer to the process' process structure. + */ +void process_poll(struct process *p); + +/** @} */ + +/** + * \name Functions called by the system and boot-up code + * @{ + */ + +/** + * \brief Initialize the process module. + * + * This function initializes the process module and should + * be called by the system boot-up code. + */ +void process_init(void); + +/** + * Run the system once - call poll handlers and process one event. + * + * This function should be called repeatedly from the main() program + * to actuall run the Contiki system. It calls the necessary poll + * handlers, and processes one event. The function returns the number + * of events that are waiting in the event queue so that the caller + * may choose to put the CPU to sleep when there are no pending + * events. + * + * \return The number of events that are currently waiting in the + * event queue. + */ +int process_run(void); + +/** @} */ + +extern struct process *process_list; + +#define PROCESS_LIST() process_list + +#endif /* __PROCESS_H__ */ + +/** @} */ +/** @} */ diff --git a/procinit.c b/procinit.c new file mode 100644 index 000000000..169b0cff4 --- /dev/null +++ b/procinit.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: procinit.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "sys/procinit.h" + +extern const struct process *procinit[]; + +/*---------------------------------------------------------------------------*/ +void +procinit_init(void) +{ + int i; + + for(i = 0; procinit[i] != NULL; ++i) { + process_start((struct process *)procinit[i], NULL); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/procinit.h b/procinit.h new file mode 100644 index 000000000..f00dcdcd0 --- /dev/null +++ b/procinit.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: procinit.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __PROCINIT_H__ +#define __PROCINIT_H__ + +#include "sys/process.h" + +#if ! CC_NO_VA_ARGS +#define PROCINIT(...) \ +const struct process *procinit[] = {__VA_ARGS__, NULL}; +#endif + +void procinit_init(void); + +#endif /* __PROCINIT_H__ */ diff --git a/pt-sem.h b/pt-sem.h new file mode 100644 index 000000000..042c54b1d --- /dev/null +++ b/pt-sem.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: pt-sem.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup ptsem Protothread semaphores + * @{ + * + * This module implements counting semaphores on top of + * protothreads. Semaphores are a synchronization primitive that + * provide two operations: "wait" and "signal". The "wait" operation + * checks the semaphore counter and blocks the thread if the counter + * is zero. The "signal" operation increases the semaphore counter but + * does not block. If another thread has blocked waiting for the + * semaphore that is signalled, the blocked thread will become + * runnable again. + * + * Semaphores can be used to implement other, more structured, + * synchronization primitives such as monitors and message + * queues/bounded buffers (see below). + * + * The following example shows how the producer-consumer problem, also + * known as the bounded buffer problem, can be solved using + * protothreads and semaphores. Notes on the program follow after the + * example. + * + \code +#include "pt-sem.h" + +#define NUM_ITEMS 32 +#define BUFSIZE 8 + +static struct pt_sem mutex, full, empty; + +PT_THREAD(producer(struct pt *pt)) +{ + static int produced; + + PT_BEGIN(pt); + + for(produced = 0; produced < NUM_ITEMS; ++produced) { + + PT_SEM_WAIT(pt, &full); + + PT_SEM_WAIT(pt, &mutex); + add_to_buffer(produce_item()); + PT_SEM_SIGNAL(pt, &mutex); + + PT_SEM_SIGNAL(pt, &empty); + } + + PT_END(pt); +} + +PT_THREAD(consumer(struct pt *pt)) +{ + static int consumed; + + PT_BEGIN(pt); + + for(consumed = 0; consumed < NUM_ITEMS; ++consumed) { + + PT_SEM_WAIT(pt, &empty); + + PT_SEM_WAIT(pt, &mutex); + consume_item(get_from_buffer()); + PT_SEM_SIGNAL(pt, &mutex); + + PT_SEM_SIGNAL(pt, &full); + } + + PT_END(pt); +} + +PT_THREAD(driver_thread(struct pt *pt)) +{ + static struct pt pt_producer, pt_consumer; + + PT_BEGIN(pt); + + PT_SEM_INIT(&empty, 0); + PT_SEM_INIT(&full, BUFSIZE); + PT_SEM_INIT(&mutex, 1); + + PT_INIT(&pt_producer); + PT_INIT(&pt_consumer); + + PT_WAIT_THREAD(pt, producer(&pt_producer) & + consumer(&pt_consumer)); + + PT_END(pt); +} + \endcode + * + * The program uses three protothreads: one protothread that + * implements the consumer, one thread that implements the producer, + * and one protothread that drives the two other protothreads. The + * program uses three semaphores: "full", "empty" and "mutex". The + * "mutex" semaphore is used to provide mutual exclusion for the + * buffer, the "empty" semaphore is used to block the consumer is the + * buffer is empty, and the "full" semaphore is used to block the + * producer is the buffer is full. + * + * The "driver_thread" holds two protothread state variables, + * "pt_producer" and "pt_consumer". It is important to note that both + * these variables are declared as static. If the static + * keyword is not used, both variables are stored on the stack. Since + * protothreads do not store the stack, these variables may be + * overwritten during a protothread wait operation. Similarly, both + * the "consumer" and "producer" protothreads declare their local + * variables as static, to avoid them being stored on the stack. + * + * + */ + +/** + * \file + * Counting semaphores implemented on protothreads + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_SEM_H__ +#define __PT_SEM_H__ + +#include "sys/pt.h" + +struct pt_sem { + unsigned int count; +}; + +/** + * Initialize a semaphore + * + * This macro initializes a semaphore with a value for the + * counter. Internally, the semaphores use an "unsigned int" to + * represent the counter, and therefore the "count" argument should be + * within range of an unsigned int. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \param c (unsigned int) The initial count of the semaphore. + * \hideinitializer + */ +#define PT_SEM_INIT(s, c) (s)->count = c + +/** + * Wait for a semaphore + * + * This macro carries out the "wait" operation on the semaphore. The + * wait operation causes the protothread to block while the counter is + * zero. When the counter reaches a value larger than zero, the + * protothread will continue. + * + * \param pt (struct pt *) A pointer to the protothread (struct pt) in + * which the operation is executed. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \hideinitializer + */ +#define PT_SEM_WAIT(pt, s) \ + do { \ + PT_WAIT_UNTIL(pt, (s)->count > 0); \ + --(s)->count; \ + } while(0) + +/** + * Signal a semaphore + * + * This macro carries out the "signal" operation on the semaphore. The + * signal operation increments the counter inside the semaphore, which + * eventually will cause waiting protothreads to continue executing. + * + * \param pt (struct pt *) A pointer to the protothread (struct pt) in + * which the operation is executed. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \hideinitializer + */ +#define PT_SEM_SIGNAL(pt, s) ++(s)->count + +#endif /* __PT_SEM_H__ */ + +/** @} */ +/** @} */ + diff --git a/pt.h b/pt.h new file mode 100644 index 000000000..23f861fb2 --- /dev/null +++ b/pt.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: pt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \file + * Protothreads implementation. + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_H__ +#define __PT_H__ + +#include "sys/lc.h" + +struct pt { + lc_t lc; +}; + +#define PT_WAITING 0 +#define PT_EXITED 1 +#define PT_ENDED 2 +#define PT_YIELDED 3 + +/** + * \name Initialization + * @{ + */ + +/** + * Initialize a protothread. + * + * Initializes a protothread. Initialization must be done prior to + * starting to execute the protothread. + * + * \param pt A pointer to the protothread control structure. + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_INIT(pt) LC_INIT((pt)->lc) + +/** @} */ + +/** + * \name Declaration and definition + * @{ + */ + +/** + * Declaration of a protothread. + * + * This macro is used to declare a protothread. All protothreads must + * be declared with this macro. + * + * \param name_args The name and arguments of the C function + * implementing the protothread. + * + * \hideinitializer + */ +#define PT_THREAD(name_args) char name_args + +/** + * Declare the start of a protothread inside the C function + * implementing the protothread. + * + * This macro is used to declare the starting point of a + * protothread. It should be placed at the start of the function in + * which the protothread runs. All C statements above the PT_BEGIN() + * invokation will be executed each time the protothread is scheduled. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) + +/** + * Declare the end of a protothread. + * + * This macro is used for declaring that a protothread ends. It must + * always be used together with a matching PT_BEGIN() macro. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ + PT_INIT(pt); return PT_ENDED; } + +/** @} */ + +/** + * \name Blocked wait + * @{ + */ + +/** + * Block and wait until condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. + * + * \param pt A pointer to the protothread control structure. + * \param condition The condition. + * + * \hideinitializer + */ +#define PT_WAIT_UNTIL(pt, condition) \ + do { \ + LC_SET((pt)->lc); \ + if(!(condition)) { \ + return PT_WAITING; \ + } \ + } while(0) + +/** + * Block and wait while condition is true. + * + * This function blocks and waits while condition is true. See + * PT_WAIT_UNTIL(). + * + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * \hideinitializer + */ +#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) + +/** @} */ + +/** + * \name Hierarchical protothreads + * @{ + */ + +/** + * Block and wait until a child protothread completes. + * + * This macro schedules a child protothread. The current protothread + * will block until the child protothread completes. + * + * \note The child protothread must be manually initialized with the + * PT_INIT() function before this function is used. + * + * \param pt A pointer to the protothread control structure. + * \param thread The child protothread with arguments + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) + +/** + * Spawn a child protothread and wait until it exits. + * + * This macro spawns a child protothread and waits until it exits. The + * macro can only be used within a protothread. + * + * \param pt A pointer to the protothread control structure. + * \param child A pointer to the child protothread's control structure. + * \param thread The child protothread with arguments + * + * \hideinitializer + */ +#define PT_SPAWN(pt, child, thread) \ + do { \ + PT_INIT((child)); \ + PT_WAIT_THREAD((pt), (thread)); \ + } while(0) + +/** @} */ + +/** + * \name Exiting and restarting + * @{ + */ + +/** + * Restart the protothread. + * + * This macro will block and cause the running protothread to restart + * its execution at the place of the PT_BEGIN() call. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_RESTART(pt) \ + do { \ + PT_INIT(pt); \ + return PT_WAITING; \ + } while(0) + +/** + * Exit the protothread. + * + * This macro causes the protothread to exit. If the protothread was + * spawned by another protothread, the parent protothread will become + * unblocked and can continue to run. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_EXIT(pt) \ + do { \ + PT_INIT(pt); \ + return PT_EXITED; \ + } while(0) + +/** @} */ + +/** + * \name Calling a protothread + * @{ + */ + +/** + * Schedule a protothread. + * + * This function shedules a protothread. The return value of the + * function is non-zero if the protothread is running or zero if the + * protothread has exited. + * + * \param f The call to the C function implementing the protothread to + * be scheduled + * + * \hideinitializer + */ +#define PT_SCHEDULE(f) ((f) == PT_WAITING) + +/** @} */ + +/** + * \name Yielding from a protothread + * @{ + */ + +/** + * Yield from the current protothread. + * + * This function will yield the protothread, thereby allowing other + * processing to take place in the system. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_YIELD(pt) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if(PT_YIELD_FLAG == 0) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** + * \brief Yield from the protothread until a condition occurs. + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * This function will yield the protothread, until the + * specified condition evaluates to true. + * + * + * \hideinitializer + */ +#define PT_YIELD_UNTIL(pt, cond) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if((PT_YIELD_FLAG == 0) || !(cond)) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** @} */ + +#endif /* __PT_H__ */ + +/** @} */ diff --git a/service.c b/service.c new file mode 100644 index 000000000..646c6328e --- /dev/null +++ b/service.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: service.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include + +#include "contiki.h" + +/** + * \addtogroup service + * @{ + */ + +/** + * \file + * Implementation of the Contiki service mechanism. + * \author + * Adam Dunkels + */ + +static struct service *services_list = NULL; + +/*---------------------------------------------------------------------------*/ +void +service_register(struct service *s) +{ + struct service *existing; + + + s->p = PROCESS_CURRENT(); + + existing = service_find(s->name); + if(existing != NULL) { + service_remove(existing); + } + + s->next = services_list; + services_list = s; +} +/*---------------------------------------------------------------------------*/ +void +service_remove(struct service *s) +{ + struct service *t; + + + /* Check if service is first on the list. */ + if(s == services_list) { + services_list = s->next; + + /* Post a notification to the owner process. */ + process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); + + } else { + for(t = services_list; t != NULL && t->next != s; t = t->next); + if(t != NULL) { + t->next = s->next; + + /* Post a notification to the owner process. */ + process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); + } + } + + s->next = NULL; +} +/*---------------------------------------------------------------------------*/ +struct service * +service_find(const char *name) +{ + struct service *s; + + + for(s = services_list; s != NULL; s = s->next) { + if(strcmp(s->name, name) == 0) { + return s; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/service.h b/service.h new file mode 100644 index 000000000..86cc3bf06 --- /dev/null +++ b/service.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: service.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup service The Contiki service mechanism + * + * The Contiki service mechanism enables cross-process functions. A + * service that is registered by one process can be accessed by other + * processes in the system. Services can be transparently replaced at + * run-time. + * + * A service has an interface that callers use to access the service's + * functions. This interface typically is defined in a header file + * that is included by all users of the service. A service interface + * is defined with the SERVICE_INTERFACE() macro. + * + * A service implementation is declared with the SERVICE() macro. The + * SERVICE() statement specifies the actual functions that are used to + * implement the service. + * + * Every service has a controlling process. The controlling process + * registers the service with the system when it starts, and is also + * notified if the service is removed or replaced. A process may + * register any number of services. + * + * Service registration is done with a SERVICE_REGISTER() + * statement. If a service with the same name is already registered, + * this is removed before the new service is registered. + * + * The SERVICE_CALL() macro is used to call a service. If the service + * to be called is not registered, the SERVICE_CALL() statement does + * nothing. The SERVICE_FIND() function can be used to check if a + * particular service exists before calling SERVICE_CALL(). + * + * @{ + */ + +/** + * \file + * Header file for the Contiki service mechanism. + * \author + * Adam Dunkels + */ + +#ifndef __SERVICE_H__ +#define __SERVICE_H__ + +#include "contiki.h" + +struct service { + struct service *next; + struct process *p; + const char *name; + const void *interface; +}; + +/** + * \name Service declaration and defition + * @{ + */ + +/** + * Define the name and interface of a service. + * + * This statement defines the name and interface of a service. + * + * \param name The name of the service. + * + * \param interface A list of function declarations that comprises the + * service interface. This list must be enclosed by curly brackets and + * consist of declarations of function pointers separated by + * semicolons. + * + * \hideinitializer + */ +#define SERVICE_INTERFACE(name, interface) struct name interface; + +#if ! CC_NO_VA_ARGS +/** + * \brief Define an implementation of a service interface. + * \param name The name of this particular instance of the service, for use with SERVICE_REGISTER(). + * \param service_name The name of the service, from the SERVICE_INTERFACE(). + * \param ... A structure containing the functions that implements the service. + * + * This statement defines the name of this implementation + * of the service and defines the functions that actually + * implement the functions offered by the service. + * + * \hideinitializer + */ +#define SERVICE(name, service_name, ...) \ + static struct service_name name##_interface = __VA_ARGS__ ; \ + struct service name = { NULL, NULL, service_name##_name, & name##_interface } +#endif + +/** @} */ + +/** + * \name Calling a service + * @{ + */ + +/** + * Call a function from a specified service, if it is registered. + * + * + * \param service_name The name of the service that is to be called. + * + * \param function The function that is to be called. This is a full + * function call, including parameters. + * + * \hideinitializer + */ +#define SERVICE_CALL(service_name, function) \ + { \ + struct service *service_s; \ + service_s = service_find(service_name##_name); \ + if(service_s != NULL) { \ + ((const struct service_name *)service_s->interface)->function; \ + } \ + } + +/* @} */ + +#define SERVICE_EXISTS(service_name) (service_find(service_name##_name) != NULL) + +/** + * \name Service registration and removal + * @{ + */ + +/** + * Register a service. + * + * \hideinitializer + */ +#define SERVICE_REGISTER(name) service_register(&name) + +/** + * Remove a service. + * + * \hideinitializer + */ +#define SERVICE_REMOVE(service_name) service_remove(&service_name) + +/** @} */ + +/** + * Find service. + * + * \hideinitializer + */ +#define SERVICE_FIND(service_name) service_find(service_name##_name) + +void service_register(struct service *s); +void service_remove(struct service *s); +struct service *service_find(const char *name); + +#endif /* __SERVICE_H__ */ +/** @} */ +/** @} */ diff --git a/timer.c b/timer.c new file mode 100644 index 000000000..c77ec0508 --- /dev/null +++ b/timer.c @@ -0,0 +1,128 @@ +/** + * \addtogroup timer + * @{ + */ + +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: timer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki-conf.h" +#include "sys/clock.h" +#include "sys/timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +timer_set(struct timer *t, clock_time_t interval) +{ + t->interval = interval; + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_rester() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +timer_reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +timer_restart(struct timer *t) +{ + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +timer_expired(struct timer *t) +{ + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/timer.h b/timer.h new file mode 100644 index 000000000..aefd34e48 --- /dev/null +++ b/timer.h @@ -0,0 +1,100 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup timer Timer library + * + * The Contiki kernel does not provide support for timed + * events. Rather, an application that wants to use timers needs to + * explicitly use the timer library. + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: timer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "sys/clock.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct timer { + clock_time_t start; + clock_time_t interval; +}; + +void timer_set(struct timer *t, clock_time_t interval); +void timer_reset(struct timer *t); +void timer_restart(struct timer *t); +int timer_expired(struct timer *t); + +#endif /* __TIMER_H__ */ + +/** @} */ +/** @} */ From 95f9ca612ba754802cfe38a9e1fc1b791041934c Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Mon, 14 Aug 2006 23:39:23 +0000 Subject: [PATCH 002/146] Added main header include. --- arg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arg.c b/arg.c index 9df45198b..48594bc46 100644 --- a/arg.c +++ b/arg.c @@ -60,10 +60,11 @@ * * This file is part of the Contiki desktop OS * - * $Id: arg.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * $Id: arg.c,v 1.2 2006/08/14 23:39:23 oliverschmidt Exp $ * */ +#include "contiki.h" #include "sys/arg.h" /** From 87cc53728a333f09b3a360d995eb970486554cc5 Mon Sep 17 00:00:00 2001 From: bg- Date: Thu, 17 Aug 2006 15:39:24 +0000 Subject: [PATCH 003/146] New function process_nevents(). --- process.c | 12 +++++++++++- process.h | 12 ++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/process.c b/process.c index 7e7ce9648..7ee93ecdd 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.2 2006/08/17 15:39:24 bg- Exp $ */ /** @@ -353,6 +353,16 @@ process_run(void) } /*---------------------------------------------------------------------------*/ int +process_nevents(void) +{ +#ifdef NPOLLS + return nevents + npolls; +#else + return nevents + poll_requested; +#endif +} +/*---------------------------------------------------------------------------*/ +int process_post(struct process *p, process_event_t ev, process_data_t data) { static unsigned char snum; diff --git a/process.h b/process.h index 1d689de30..2706209f6 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.2 2006/08/17 15:39:25 bg- Exp $ */ /** @@ -503,7 +503,7 @@ void process_init(void); * Run the system once - call poll handlers and process one event. * * This function should be called repeatedly from the main() program - * to actuall run the Contiki system. It calls the necessary poll + * to actually run the Contiki system. It calls the necessary poll * handlers, and processes one event. The function returns the number * of events that are waiting in the event queue so that the caller * may choose to put the CPU to sleep when there are no pending @@ -514,6 +514,14 @@ void process_init(void); */ int process_run(void); +/** + * Number of events waiting to be processed. + * + * \return The number of events that are currently waiting to be + * processed. + */ +int process_nevents(void); + /** @} */ extern struct process *process_list; From 156c335161683840e9c322ed26055a3028342e59 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sat, 26 Aug 2006 23:54:00 +0000 Subject: [PATCH 004/146] Added the CCIF (Contiki Core InterFace) declarations used by the applications which are currently part of the Win32 build. --- dsc.h | 4 ++-- etimer.h | 6 +++--- process.h | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dsc.h b/dsc.h index b89b52cfb..4906c482c 100644 --- a/dsc.h +++ b/dsc.h @@ -56,7 +56,7 @@ * * This file is part of the Contiki desktop environment * - * $Id: dsc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: dsc.h,v 1.2 2006/08/26 23:59:39 oliverschmidt Exp $ * */ #ifndef __DSC_H__ @@ -110,7 +110,7 @@ struct dsc { */ #if WITH_LOADER_ARCH #define DSC(dscname, description, prgname, process, icon) \ - const struct dsc dscname = {description, prgname, icon} + CLIF const struct dsc dscname = {description, prgname, icon} #else /* WITH_LOADER_ARCH */ #define DSC(dscname, description, prgname, process, icon) \ PROCESS_NAME(process); \ diff --git a/etimer.h b/etimer.h index 40a98f52e..aa4b5734b 100644 --- a/etimer.h +++ b/etimer.h @@ -58,7 +58,7 @@ * * Author: Adam Dunkels * - * $Id: etimer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: etimer.h,v 1.2 2006/08/26 23:59:39 oliverschmidt Exp $ */ #ifndef __ETIMER_H__ #define __ETIMER_H__ @@ -96,7 +96,7 @@ struct etimer { * process that called the etimer_set() function. * */ -void etimer_set(struct etimer *et, clock_time_t interval); +CCIF void etimer_set(struct etimer *et, clock_time_t interval); /** * \brief Reset an event timer with the same interval as was @@ -181,7 +181,7 @@ clock_time_t etimer_start_time(struct etimer *et); * This function tests if an event timer has expired and * returns true or false depending on its status. */ -int etimer_expired(struct etimer *et); +CCIF int etimer_expired(struct etimer *et); /** * \brief Stop a pending event timer. diff --git a/process.h b/process.h index 2706209f6..314b0d084 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.2 2006/08/17 15:39:25 bg- Exp $ + * @(#)$Id: process.h,v 1.3 2006/08/26 23:59:39 oliverschmidt Exp $ */ /** @@ -279,7 +279,7 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ #else /* PROCESS_LOADABLE */ #define PROCESS_LOAD(name) #endif /* PROCESS_LOADABLE */ -extern const struct process *process_load; +CLIF extern const struct process *process_load; /** * Declare the name of a process. @@ -374,7 +374,7 @@ void process_start(struct process *p, char *arg); * \retval PROCESS_ERR_FULL The event queue was full and the event could * not be posted. */ -int process_post(struct process *p, process_event_t ev, process_data_t data); +CCIF int process_post(struct process *p, process_event_t ev, process_data_t data); /** * Post a synchronous event to a process. @@ -399,7 +399,7 @@ void process_post_synch(struct process *p, * * \sa PROCESS_CURRENT() */ -void process_exit(struct process *p); +CCIF void process_exit(struct process *p); /** @@ -412,7 +412,7 @@ void process_exit(struct process *p); * \hideinitializer */ #define PROCESS_CURRENT() process_current -extern struct process *process_current; +CCIF extern struct process *process_current; #define PROCESS_SET_FLAGS(flags) #define PROCESS_NO_BROADCAST @@ -524,7 +524,7 @@ int process_nevents(void); /** @} */ -extern struct process *process_list; +CCIF extern struct process *process_list; #define PROCESS_LIST() process_list From b0ca156ded5855590720fe44b369c092a33f2f8b Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 1 Sep 2006 22:56:47 +0000 Subject: [PATCH 005/146] #if 0:ed out unused code --- mt.c | 4 +++- mt.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mt.c b/mt.c index 0efea5793..b9a087c11 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: mt.c,v 1.2 2006/09/01 22:56:47 adamdunkels Exp $ */ /** @@ -166,6 +166,7 @@ mt_peek(process_event_t *ev, process_data_t *data) mtarch_yield(); } /*--------------------------------------------------------------------------*/ +#if 0 void mtp_start(struct mt_process *t, void (* function)(void *), void *data) @@ -219,3 +220,4 @@ mtp_eventhandler(ek_event_t ev, ek_data_t data) } }*/ /*--------------------------------------------------------------------------*/ +#endif /* 0 */ diff --git a/mt.h b/mt.h index 242f76d75..c3a71d63c 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: mt.h,v 1.2 2006/09/01 22:56:47 adamdunkels Exp $ */ /** \addtogroup sys @@ -292,6 +292,7 @@ void mt_wait(process_event_t *ev, process_data_t *data); */ void mt_exit(void); +#if 0 /** * \defgroup mtp Multi-threading library convenience functions * @{ @@ -361,6 +362,7 @@ void mtp_exit(void); void mtp_eventhandler(process_event_t ev, process_data_t data); /** @} */ +#endif /* 0 */ /** @} */ /** @} */ #endif /* __MT_H__ */ From 30d0586c80352fb9ef8a7298d06791311471cf78 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sat, 9 Sep 2006 23:24:39 +0000 Subject: [PATCH 006/146] Added the CCIF (Contiki Core InterFace) declarations necessary for a loadable packet driver. --- process.h | 4 ++-- service.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/process.h b/process.h index 314b0d084..f624c0889 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.3 2006/08/26 23:59:39 oliverschmidt Exp $ + * @(#)$Id: process.h,v 1.4 2006/09/09 23:25:07 oliverschmidt Exp $ */ /** @@ -482,7 +482,7 @@ process_event_t process_alloc_event(void); * * \param p A pointer to the process' process structure. */ -void process_poll(struct process *p); +CCIF void process_poll(struct process *p); /** @} */ diff --git a/service.h b/service.h index 86cc3bf06..3ea2e6d62 100644 --- a/service.h +++ b/service.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: service.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * @(#)$Id: service.h,v 1.2 2006/09/09 23:25:07 oliverschmidt Exp $ */ /** \addtogroup sys @@ -186,8 +186,8 @@ struct service { */ #define SERVICE_FIND(service_name) service_find(service_name##_name) -void service_register(struct service *s); -void service_remove(struct service *s); +CCIF void service_register(struct service *s); +CCIF void service_remove(struct service *s); struct service *service_find(const char *name); #endif /* __SERVICE_H__ */ From 97130a9eba613cd5118a97f950e5adc784fb28d6 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 26 Sep 2006 20:53:27 +0000 Subject: [PATCH 007/146] A module that allows Contiki processes to have subprocesses. A subprocess is defined within another process and is created on the fly when needed. --- subprocess.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 subprocess.h diff --git a/subprocess.h b/subprocess.h new file mode 100644 index 000000000..b92527548 --- /dev/null +++ b/subprocess.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: subprocess.h,v 1.1 2006/09/26 20:53:27 adamdunkels Exp $ + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup subprocess Contiki subprocesses + * @{ + * + * A Contiki subprocess is a "process-in-a-process". + */ + +/** + * \file + * Subprocesses for Contiki + * \author + * Adam Dunkels + */ + +#ifndef __SUBPROCESS_H__ +#define __SUBPROCESS_H__ + +#define SUBPROCESS_BEGIN(strname) \ +{ \ + static struct process subprocess_subprocess = {NULL, strname}; \ + subprocess_subprocess.thread = PROCESS_CURRENT()->thread; \ + process_start(&subprocess_subprocess, NULL); \ + PT_INIT(&subprocess_subprocess.pt); \ + LC_SET(subprocess_subprocess.pt.lc); \ + if(PROCESS_CURRENT() == &subprocess_subprocess) { + +#define SUBPROCESS_END() \ + PROCESS_EXIT(); \ + } \ +} + +#endif /* __SUBPROCESS_H__ */ From f3b7fee6884679018e0c34451980865eb716af6d Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 26 Sep 2006 20:57:58 +0000 Subject: [PATCH 008/146] Fixed the behaviour of PT_SCHEDULE() so that it returns true if a protothread is still active (yielded or waiting). Thanks to Kevin Collins for fixing. --- pt.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pt.h b/pt.h index 23f861fb2..1c3efa275 100644 --- a/pt.h +++ b/pt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: pt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: pt.h,v 1.2 2006/09/26 20:57:58 adamdunkels Exp $ */ /** @@ -56,9 +56,9 @@ struct pt { }; #define PT_WAITING 0 -#define PT_EXITED 1 -#define PT_ENDED 2 -#define PT_YIELDED 3 +#define PT_YIELDED 1 +#define PT_EXITED 2 +#define PT_ENDED 3 /** * \name Initialization @@ -268,7 +268,7 @@ struct pt { * * \hideinitializer */ -#define PT_SCHEDULE(f) ((f) == PT_WAITING) +#define PT_SCHEDULE(f) ((f) < PT_EXITED) /** @} */ From 774b2f327900a215b0fa1007bed2a86773ec300d Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 26 Sep 2006 20:59:51 +0000 Subject: [PATCH 009/146] Commented out unused functionality: the ability to create a process running a thread was never used. With the new code, only running 'bare' threads is supported. If support for creating processes with a thread is needed, it may be reneabled later but currently there doesn't seem to be a need for it --- mt.c | 8 +++++++- mt.h | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mt.c b/mt.c index b9a087c11..bbe58f851 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.2 2006/09/01 22:56:47 adamdunkels Exp $ + * $Id: mt.c,v 1.3 2006/09/26 20:59:51 adamdunkels Exp $ */ /** @@ -100,6 +100,7 @@ mt_exit(void) mtarch_yield(); } /*--------------------------------------------------------------------------*/ +#if 0 void mt_exec_event(struct mt_thread *thread, process_event_t ev, process_data_t data) @@ -115,6 +116,7 @@ mt_exec_event(struct mt_thread *thread, process_event_t ev, mtarch_exec(&thread->thread); } } +#endif /*--------------------------------------------------------------------------*/ void mt_yield(void) @@ -130,6 +132,7 @@ mt_yield(void) } /*--------------------------------------------------------------------------*/ +#if 0 void mt_post(struct process *p, process_event_t ev, process_data_t data) @@ -142,7 +145,9 @@ mt_post(struct process *p, process_event_t ev, /* Turn preemption on again. */ mtarch_pstart(); } +#endif /*--------------------------------------------------------------------------*/ +#if 0 void mt_wait(process_event_t *ev, process_data_t *data) { @@ -165,6 +170,7 @@ mt_peek(process_event_t *ev, process_data_t *data) current = NULL; mtarch_yield(); } +#endif /*--------------------------------------------------------------------------*/ #if 0 void diff --git a/mt.h b/mt.h index c3a71d63c..dbadde2eb 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.2 2006/09/01 22:56:47 adamdunkels Exp $ + * $Id: mt.h,v 1.3 2006/09/26 20:59:51 adamdunkels Exp $ */ /** \addtogroup sys @@ -235,8 +235,8 @@ void mt_exec(struct mt_thread *thread); * containing additonal information, or NULL if no additional * information is needed. */ -void mt_exec_event(struct mt_thread *thread, process_event_t s, - process_data_t data); +/*void mt_exec_event(struct mt_thread *thread, process_event_t s, + process_data_t data);*/ /** * Voluntarily give up the processor. @@ -263,7 +263,7 @@ void mt_yield(void); * with the signal. * */ -void mt_post(struct process *p, process_event_t ev, process_data_t data); +/*void mt_post(struct process *p, process_event_t ev, process_data_t data);*/ /** * Block and wait for an event to occur. @@ -281,7 +281,7 @@ void mt_post(struct process *p, process_event_t ev, process_data_t data); * the thread. * */ -void mt_wait(process_event_t *ev, process_data_t *data); +/*void mt_wait(process_event_t *ev, process_data_t *data);*/ /** * Exit a thread. From 41cc076800a9a252c79b48c11bd999bf92f6f0e8 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 9 Oct 2006 11:54:29 +0000 Subject: [PATCH 010/146] Added PROCESS_PT_SPAWN, PROCESS_WAIT_UNTIL --- process.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/process.h b/process.h index f624c0889..7e5a1d6e4 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.4 2006/09/09 23:25:07 oliverschmidt Exp $ + * @(#)$Id: process.h,v 1.5 2006/10/09 11:54:29 adamdunkels Exp $ */ /** @@ -98,7 +98,8 @@ typedef unsigned char process_num_events_t; #define PROCESS_EVENT_MSG 0x86 #define PROCESS_EVENT_EXITED 0x87 #define PROCESS_EVENT_TIMER 0x88 -#define PROCESS_EVENT_MAX 0x89 +#define PROCESS_EVENT_COM 0x89 +#define PROCESS_EVENT_MAX 0x8a #define PROCESS_BROADCAST NULL #define PROCESS_ZOMBIE ((struct process *)0x1) @@ -190,6 +191,7 @@ typedef unsigned char process_num_events_t; * \hideinitializer */ #define PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c) +#define PROCESS_WAIT_WHILE(c) PT_WAIT_WHILE(process_pt, c) /** * Exit the currently running process. @@ -207,7 +209,7 @@ typedef unsigned char process_num_events_t; * * \hideinitializer */ -#define PROCESS_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) +#define PROCESS_PT_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) /** * Yield the process for a short while. From 60d5a5ed41e586cb3bf6a6d71a0487f0318bf549 Mon Sep 17 00:00:00 2001 From: nifi Date: Mon, 9 Oct 2006 16:05:58 +0000 Subject: [PATCH 011/146] major bug fix: arithmetic was done incorrectly in update_time() + process already expired timers when adding timers --- etimer.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/etimer.c b/etimer.c index bd8c0f9da..3d41bb880 100644 --- a/etimer.c +++ b/etimer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: etimer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: etimer.c,v 1.2 2006/10/09 16:05:58 nifi Exp $ */ #include "contiki-conf.h" @@ -59,19 +59,22 @@ static void update_time(void) { clock_time_t nextt; + clock_time_t now; struct etimer *t; if (timerlist == NULL) { next_expiration = 0; } else { + now = clock_time(); t = timerlist; - nextt = t->timer.start + t->timer.interval; + /* Must take current time into account due to wraps */ + nextt = t->timer.start + t->timer.interval - now; for(t = t->next; t != NULL; t = t->next) { - if(t->timer.start + t->timer.interval < nextt) { - nextt = t->timer.start + t->timer.interval; + if(t->timer.start + t->timer.interval - now < nextt) { + nextt = t->timer.start + t->timer.interval - now; } } - next_expiration = nextt; + next_expiration = nextt + now; } } /*---------------------------------------------------------------------------*/ @@ -150,6 +153,8 @@ add_timer(struct etimer *timer) { struct etimer *t; + etimer_request_poll(); + if(timer->p != PROCESS_NONE) { /* Timer not on list. */ From 72bea279ae1a086be262f57bcb0a55b506efb91f Mon Sep 17 00:00:00 2001 From: bg- Date: Wed, 24 Jan 2007 16:07:20 +0000 Subject: [PATCH 012/146] * Don't include signal.h. --- process.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/process.c b/process.c index 7ee93ecdd..87f8f903e 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.2 2006/08/17 15:39:24 bg- Exp $ + * @(#)$Id: process.c,v 1.3 2007/01/24 16:07:20 bg- Exp $ */ /** @@ -68,7 +68,6 @@ struct event_data { #ifdef PROCESS_CONF_FASTPOLL #define NPOLLS PROCESS_CONF_FASTPOLL -#include static volatile unsigned npolls; static struct process *needpoll[NPOLLS]; #endif From 8f9adff8ed10796e1e203b808a62973a131bf222 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 15 Mar 2007 21:46:07 +0000 Subject: [PATCH 013/146] Copyright update --- mt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mt.c b/mt.c index bbe58f851..de81df16e 100644 --- a/mt.c +++ b/mt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Swedish Institute of Computer Science. + * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.3 2006/09/26 20:59:51 adamdunkels Exp $ + * $Id: mt.c,v 1.4 2007/03/15 21:46:07 adamdunkels Exp $ */ /** From c8d7ccd8b532ac76594dcb823bdfb24e82f971ba Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 19 Mar 2007 00:16:13 +0000 Subject: [PATCH 014/146] Initial code for a Contiki real-time scheduler --- rt.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rt.h | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 rt.c create mode 100644 rt.h diff --git a/rt.c b/rt.c new file mode 100644 index 000000000..669239d16 --- /dev/null +++ b/rt.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rt.c,v 1.1 2007/03/19 00:16:13 adamdunkels Exp $ + */ + +#include "sys/rt.h" +#include "contiki.h" + +#define LIST_SIZE 16 + +static struct rt_task *tasks[LIST_SIZE]; +static u8_t next, firstempty; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +void +rt_init(void) +{ + next = 0; + firstempty = 0; + rt_arch_init(); +} +/*---------------------------------------------------------------------------*/ +int +rt_post(struct rt_task *task, rt_clock_t time, rt_clock_t duration) +{ + int i; + + PRINTF("rt_post time %d\n", time); + + /* Check if task queue is full. */ + if(firstempty == (next - 1) % LIST_SIZE) { + PRINTF("rt_post: next %d firstempty %d full\n", next, firstempty); + return RT_ERR_FULL; + } + + /* Check if it is possible to run this task at the requested + time. */ + for(i = next; i != firstempty; + i = (i + 1) % LIST_SIZE) { + + /* XXX: should check a range of time not just the same precise + moment. */ + if(tasks[i]->time == time) { + PRINTF("rt_post: next %d firstempty %d time %d == %d\n", + next, firstempty, tasks[i]->time, time); + return RT_ERR_TIME; + } + } + /* Put the task at the end of the task list. */ + task->time = time; + tasks[firstempty] = task; + PRINTF("rt_post: putting task %s as %d\n", task->name, firstempty); + + firstempty = (firstempty + 1) % LIST_SIZE; + + /* PRINTF("rt_post: next %d firstempty %d scheduling soon\n", + next, firstempty);*/ + + /* Check if this is the first task on the list. If so, we need to + run the rt_arch_schedule() function to get the ball rolling. */ + if(firstempty == (next + 1) % LIST_SIZE) { + + PRINTF("rt_post scheduling %d %s (%d)\n", + next, tasks[next]->name, tasks[next]->time); + rt_arch_schedule(time); + } + + return RT_OK; +} +/*---------------------------------------------------------------------------*/ +void +rt_task_run(void) +{ + int i, n; + struct rt_task *t; + + t = tasks[next]; + + /* Increase the pointer to the next task. */ + next = (next + 1) % LIST_SIZE; + + /* Run the task. */ + PRINTF("rt_task_run running %s\n", t->name); + t->func(t, t->ptr); + + if(next == firstempty) { + PRINTF("rt_task_run: empty task list\n"); + /* The list is empty, no more tasks to schedule. */ + return; + } + + /* Find the next task to run. */ + n = next; + for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { + PRINTF("rt_task_run checking %s (%d) against %s (%d)\n", + tasks[i]->name, tasks[i]->time, + tasks[n]->name, tasks[n]->time); + if(tasks[i]->prio >= tasks[n]->prio && + RT_CLOCK_LT(tasks[i]->time, tasks[n]->time)) { + n = i; + } + } + + PRINTF("rt_task_run next task is %d %s (%d)\n", + n, tasks[n]->name, tasks[n]->time); + + /* Put the next task first in the task list. */ + t = tasks[next]; + tasks[next] = tasks[n]; + tasks[n] = t; + + PRINTF("rt_task_run scheduling %d %s (%d)\n", + next, tasks[next]->name, tasks[next]->time); + + rt_arch_schedule(tasks[next]->time); +} +/*---------------------------------------------------------------------------*/ diff --git a/rt.h b/rt.h new file mode 100644 index 000000000..eedf3f9a9 --- /dev/null +++ b/rt.h @@ -0,0 +1,156 @@ +/** + * \defgroup rt Real-time task scheduling + * + * The real-time module handles the scheduling and execution of + * real-time tasks (with predictible execution times). + * + * @{ + */ + +/** + * \file + * Header file for the real-time module. + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rt.h,v 1.1 2007/03/19 00:16:13 adamdunkels Exp $ + */ +#ifndef __RT_H__ +#define __RT_H__ + +typedef unsigned short rt_clock_t; +#define RT_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) + +/** + * \brief Initialize the real-time scheduler. + * + * This function initializes the real-time scheduler and + * must be called at boot-up, before any other functions + * from the real-time scheduler is called. + */ +void rt_init(void); + +/** + * \brief Repressentation of a real-time task + * + * This structure represents a real-time task and is used + * by the real-time module and the architecture specific + * support module for the real-time module. + */ +struct rt_task { + char *name; + rt_clock_t time; + void (* func)(struct rt_task *t, void *ptr); + unsigned char prio; + void *ptr; +}; + +/** + * \brief Declare a real-time task. + * \param name The name of the task state variable. + * \param func The function implementing the real-time task. + * \param prio The priority of the task. + * \param ptr An opaque pointer that is passed to the real-time task + * when it is executed. + * + * This macro declares a real-time task. + * + * \hideinitializer + */ +#define RT_TASK(name, func, prio, ptr) { name, 0, func, prio, ptr } + +enum { + RT_OK, + RT_ERR_FULL, + RT_ERR_TIME, +}; + +/** + * \brief Post a real-time task. + * \param task A pointer to the task variable previously declared with RT_TASK(). + * \param time The time when the task is to be executed. + * \return Non-zero (true) if the task could be scheduled, zero + * (false) if the task could not be scheduled. + * + * This function schedules a real-time task a specified + * time in the future. + * + */ +int rt_post(struct rt_task *task, rt_clock_t time, rt_clock_t duration); + +/** + * \brief Execute the next real-time task and schedule the next task, if any + * + * This function is called by the architecture dependent + * code to execute and schedule the next real-time task. + * + */ +void rt_task_run(void); + +/** + * \brief Get the current clock time + * \return The current time + * + * This function returns what the real-time module thinks + * is the current time. The current time is used to set + * the timeouts for real-time tasks. + * + * \hideinitializer + */ +#define RT_NOW() rt_arch_now() + +/** + * \brief Get the time that a task last was executed + * \param task The task + * \return The time that a task last was executed + * + * This function returns the time that the task was last + * executed. This typically is used to get a periodic + * execution of a task without clock drift. + * + * \hideinitializer + */ +#define RT_TASK_TIME(task) ((task)->time) + +void rt_arch_init(void); +void rt_arch_schedule(rt_clock_t t); +rt_clock_t rt_arch_now(void); + + +#include "rt-arch.h" + +#endif /* __RT_H__ */ + +/** @} */ From e460f7c22bd0c56cf6e4d3bcffdfa4e1933f3bd8 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 25 Mar 2007 17:10:30 +0000 Subject: [PATCH 015/146] Renamed rt module to rtimer --- rt.c => rtimer.c | 94 ++++++++++++++++++++++++------------------------ rt.h => rtimer.h | 62 ++++++++++++-------------------- 2 files changed, 70 insertions(+), 86 deletions(-) rename rt.c => rtimer.c (59%) rename rt.h => rtimer.h (76%) diff --git a/rt.c b/rtimer.c similarity index 59% rename from rt.c rename to rtimer.c index 669239d16..8fba96f30 100644 --- a/rt.c +++ b/rtimer.c @@ -28,15 +28,15 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rt.c,v 1.1 2007/03/19 00:16:13 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.1 2007/03/25 17:10:30 adamdunkels Exp $ */ -#include "sys/rt.h" +#include "sys/rtimer.h" #include "contiki.h" #define LIST_SIZE 16 -static struct rt_task *tasks[LIST_SIZE]; +static struct rtimer *rtimers[LIST_SIZE]; static u8_t next, firstempty; #define DEBUG 0 @@ -49,105 +49,105 @@ static u8_t next, firstempty; /*---------------------------------------------------------------------------*/ void -rt_init(void) +rtimer_init(void) { next = 0; firstempty = 0; - rt_arch_init(); + rtimer_arch_init(); } /*---------------------------------------------------------------------------*/ int -rt_post(struct rt_task *task, rt_clock_t time, rt_clock_t duration) +rtimer_set(struct rtimer *rtimer, rt_clock_t time, rt_clock_t duration, + void (* func)(struct rtimer *t, void *ptr), void *ptr) { int i; - PRINTF("rt_post time %d\n", time); + PRINTF("rtimer_set time %d\n", time); - /* Check if task queue is full. */ + /* Check if rtimer queue is full. */ if(firstempty == (next - 1) % LIST_SIZE) { - PRINTF("rt_post: next %d firstempty %d full\n", next, firstempty); - return RT_ERR_FULL; + PRINTF("rtimer_set: next %d firstempty %d full\n", next, firstempty); + return RTIMER_ERR_FULL; } - /* Check if it is possible to run this task at the requested + /* Check if it is possible to run this rtimer at the requested time. */ for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { /* XXX: should check a range of time not just the same precise moment. */ - if(tasks[i]->time == time) { - PRINTF("rt_post: next %d firstempty %d time %d == %d\n", - next, firstempty, tasks[i]->time, time); - return RT_ERR_TIME; + if(rtimers[i]->time == time) { + PRINTF("rtimer_set: next %d firstempty %d time %d == %d\n", + next, firstempty, rtimers[i]->time, time); + return RTIMER_ERR_TIME; } } - /* Put the task at the end of the task list. */ - task->time = time; - tasks[firstempty] = task; - PRINTF("rt_post: putting task %s as %d\n", task->name, firstempty); + /* Put the rtimer at the end of the rtimer list. */ + rtimer->time = time; + rtimers[firstempty] = rtimer; + PRINTF("rt_post: putting rtimer %s as %d\n", rtimer->name, firstempty); firstempty = (firstempty + 1) % LIST_SIZE; /* PRINTF("rt_post: next %d firstempty %d scheduling soon\n", next, firstempty);*/ - /* Check if this is the first task on the list. If so, we need to + /* Check if this is the first rtimer on the list. If so, we need to run the rt_arch_schedule() function to get the ball rolling. */ if(firstempty == (next + 1) % LIST_SIZE) { - PRINTF("rt_post scheduling %d %s (%d)\n", - next, tasks[next]->name, tasks[next]->time); - rt_arch_schedule(time); + PRINTF("rtimer_set scheduling %d %s (%d)\n", + next, rtimers[next]->name, rtimers[next]->time); + rtimer } - return RT_OK; + return RTIMER_OK; } /*---------------------------------------------------------------------------*/ void -rt_task_run(void) +rtimer_run_next(void) { int i, n; - struct rt_task *t; + struct rtimer *t; - t = tasks[next]; + t = rtimers[next]; - /* Increase the pointer to the next task. */ + /* Increase the pointer to the next rtimer. */ next = (next + 1) % LIST_SIZE; - /* Run the task. */ - PRINTF("rt_task_run running %s\n", t->name); + /* Run the rtimer. */ + PRINTF("rtimer_run_next running %s\n", t->name); t->func(t, t->ptr); if(next == firstempty) { - PRINTF("rt_task_run: empty task list\n"); - /* The list is empty, no more tasks to schedule. */ + PRINTF("rtimer_run_next: empty rtimer list\n"); + /* The list is empty, no more rtimers to schedule. */ return; } - /* Find the next task to run. */ + /* Find the next rtimer to run. */ n = next; for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { - PRINTF("rt_task_run checking %s (%d) against %s (%d)\n", - tasks[i]->name, tasks[i]->time, - tasks[n]->name, tasks[n]->time); - if(tasks[i]->prio >= tasks[n]->prio && - RT_CLOCK_LT(tasks[i]->time, tasks[n]->time)) { + PRINTF("rtimer_run_next checking %s (%d) against %s (%d)\n", + rtimers[i]->name, rtimers[i]->time, + rtimers[n]->name, rtimers[n]->time); + if(RT_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { n = i; } } - PRINTF("rt_task_run next task is %d %s (%d)\n", - n, tasks[n]->name, tasks[n]->time); + PRINTF("rtimer_run_next next rtimer is %d %s (%d)\n", + n, rtimers[n]->name, rtimers[n]->time); - /* Put the next task first in the task list. */ - t = tasks[next]; - tasks[next] = tasks[n]; - tasks[n] = t; + /* Put the next rtimer first in the rtimer list. */ + t = rtimers[next]; + rtimers[next] = rtimers[n]; + rtimers[n] = t; - PRINTF("rt_task_run scheduling %d %s (%d)\n", - next, tasks[next]->name, tasks[next]->time); + PRINTF("rtimer_run_next scheduling %d %s (%d)\n", + next, rtimers[next]->name, rtimers[next]->time); - rt_arch_schedule(tasks[next]->time); + rtimer_arch_schedule(rtimers[next]->time); } /*---------------------------------------------------------------------------*/ diff --git a/rt.h b/rtimer.h similarity index 76% rename from rt.h rename to rtimer.h index eedf3f9a9..268bb6fe7 100644 --- a/rt.h +++ b/rtimer.h @@ -45,13 +45,13 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rt.h,v 1.1 2007/03/19 00:16:13 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.1 2007/03/25 17:11:02 adamdunkels Exp $ */ -#ifndef __RT_H__ -#define __RT_H__ +#ifndef __RTIMER_H__ +#define __RTIMER_H__ -typedef unsigned short rt_clock_t; -#define RT_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) +typedef unsigned short rtimer_clock_t; +#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) /** * \brief Initialize the real-time scheduler. @@ -60,7 +60,7 @@ typedef unsigned short rt_clock_t; * must be called at boot-up, before any other functions * from the real-time scheduler is called. */ -void rt_init(void); +void rtimer_init(void); /** * \brief Repressentation of a real-time task @@ -69,37 +69,21 @@ void rt_init(void); * by the real-time module and the architecture specific * support module for the real-time module. */ -struct rt_task { - char *name; - rt_clock_t time; - void (* func)(struct rt_task *t, void *ptr); - unsigned char prio; +struct rtimer { + rtimer_clock_t time; + void (* func)(struct rtimer *t, void *ptr); void *ptr; }; -/** - * \brief Declare a real-time task. - * \param name The name of the task state variable. - * \param func The function implementing the real-time task. - * \param prio The priority of the task. - * \param ptr An opaque pointer that is passed to the real-time task - * when it is executed. - * - * This macro declares a real-time task. - * - * \hideinitializer - */ -#define RT_TASK(name, func, prio, ptr) { name, 0, func, prio, ptr } - enum { - RT_OK, - RT_ERR_FULL, - RT_ERR_TIME, + RTIMER_OK, + RTIMER_ERR_FULL, + RTIMER_ERR_TIME, }; /** * \brief Post a real-time task. - * \param task A pointer to the task variable previously declared with RT_TASK(). + * \param task A pointer to the task variable previously declared with RTIMER_TASK(). * \param time The time when the task is to be executed. * \return Non-zero (true) if the task could be scheduled, zero * (false) if the task could not be scheduled. @@ -108,7 +92,8 @@ enum { * time in the future. * */ -int rt_post(struct rt_task *task, rt_clock_t time, rt_clock_t duration); +int rtimer_set(struct rtimer *t, rtimer_clock_t time, rtimer_clock_t duration, + void (* func)(struct rtimer *t, void *ptr), void *ptr); /** * \brief Execute the next real-time task and schedule the next task, if any @@ -117,7 +102,7 @@ int rt_post(struct rt_task *task, rt_clock_t time, rt_clock_t duration); * code to execute and schedule the next real-time task. * */ -void rt_task_run(void); +void rtimer_next(void); /** * \brief Get the current clock time @@ -129,7 +114,7 @@ void rt_task_run(void); * * \hideinitializer */ -#define RT_NOW() rt_arch_now() +#define RTIMER_NOW() rtimer_arch_now() /** * \brief Get the time that a task last was executed @@ -142,15 +127,14 @@ void rt_task_run(void); * * \hideinitializer */ -#define RT_TASK_TIME(task) ((task)->time) - -void rt_arch_init(void); -void rt_arch_schedule(rt_clock_t t); -rt_clock_t rt_arch_now(void); +#define RTIMER_TIME(task) ((task)->time) +void rtimer_arch_init(void); +void rtimer_arch_schedule(rtimer_clock_t t); +rtimer_clock_t rtimer_arch_now(void); -#include "rt-arch.h" +#include "rtimer-arch.h" -#endif /* __RT_H__ */ +#endif /* __RTIMER_H__ */ /** @} */ From 546ff9182d5b5399624defba5aa32e6164b97e1c Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 25 Mar 2007 17:16:57 +0000 Subject: [PATCH 016/146] Debug output --- autostart.c | 12 +++++++++++- process.c | 19 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/autostart.c b/autostart.c index 1fe80f59b..1514b0fe3 100644 --- a/autostart.c +++ b/autostart.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * $Id: autostart.c,v 1.2 2007/03/25 17:16:57 adamdunkels Exp $ */ /** @@ -40,6 +40,14 @@ #include "sys/autostart.h" +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + /*---------------------------------------------------------------------------*/ void autostart_start(struct process *processes[]) @@ -48,6 +56,7 @@ autostart_start(struct process *processes[]) for(i = 0; processes[i] != NULL; ++i) { process_start(processes[i], NULL); + PRINTF("autostart_start: starting process '%s'\n", processes[i]->name); } } /*---------------------------------------------------------------------------*/ @@ -58,6 +67,7 @@ autostart_exit(struct process *processes[]) for(i = 0; processes[i] != NULL; ++i) { process_exit(processes[i]); + PRINTF("autostart_exit: stopping process '%s'\n", processes[i]->name); } } /*---------------------------------------------------------------------------*/ diff --git a/process.c b/process.c index 87f8f903e..a54163f93 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.3 2007/01/24 16:07:20 bg- Exp $ + * @(#)$Id: process.c,v 1.4 2007/03/25 17:18:37 adamdunkels Exp $ */ /** @@ -83,6 +83,13 @@ static volatile unsigned char poll_requested; static void call_process(struct process *p, process_event_t ev, process_data_t data); +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif /*---------------------------------------------------------------------------*/ process_event_t @@ -112,7 +119,7 @@ process_start(struct process *p, char *arg) PT_INIT(&p->pt); - /* Post an asynchronous event to the process. */ + /* Post a synchronous event to the process. */ process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); } /*---------------------------------------------------------------------------*/ @@ -367,7 +374,13 @@ process_post(struct process *p, process_event_t ev, process_data_t data) static unsigned char snum; if(nevents == PROCESS_CONF_NUMEVENTS) { - printf("soft panic: event queue is full\n"); +#if DEBUG + if(p == PROCESS_BROADCAST) { + printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, process_current->name); + } else { + printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, p->name, process_current->name); + } +#endif /* DEBUG */ return PROCESS_ERR_FULL; } From 858dab4087d5328f802f71b1b3a9e93197294d7f Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 25 Mar 2007 21:51:31 +0000 Subject: [PATCH 017/146] Added experimental clock_fine() function --- clock.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clock.h b/clock.h index be0d99cf6..8bcef866d 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: clock.h,v 1.2 2007/03/25 21:51:31 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -91,6 +91,10 @@ void clock_delay(unsigned int); #define CLOCK_SECOND (clock_time_t)32 #endif +int clock_fine_max(void); +unsigned short clock_fine(void); + + #endif /* __CLOCK_H__ */ /** @} */ From 3d108f13a546fd57f6973bcfd91b6a6fe80210b5 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 28 Mar 2007 19:52:50 +0000 Subject: [PATCH 018/146] Spelling error fix --- lc-switch.h | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/lc-switch.h b/lc-switch.h index 64050f7e6..f9542c0f5 100644 --- a/lc-switch.h +++ b/lc-switch.h @@ -1,36 +1,36 @@ /* * Copyright (c) 2004-2005, Swedish Institute of Computer Science. - * All rights reserved. + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + * * Author: Adam Dunkels * - * $Id: lc-switch.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: lc-switch.h,v 1.2 2007/03/28 19:52:50 adamdunkels Exp $ */ /** @@ -55,7 +55,7 @@ */ #ifndef __LC_SWITCH_H__ -#define __LC_SWTICH_H__ +#define __LC_SWITCH_H__ /* WARNING! lc implementation using switch() does not work if an LC_SET() is done within another switch() statement! */ @@ -67,7 +67,7 @@ typedef unsigned short lc_t; #define LC_RESUME(s) switch(s) { case 0: -#define LC_SET(s) s = __LINE__; case __LINE__: +#define LC_SET(s) s = __LINE__; case __LINE__: #define LC_END(s) } From cb7a903f8b6bcc1e6ff9cd3a54e5f2b175911a20 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 28 Mar 2007 20:28:22 +0000 Subject: [PATCH 019/146] Fixed API to be consistent between .h and .c file --- rtimer.c | 17 ++++++++++------- rtimer.h | 4 +++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/rtimer.c b/rtimer.c index 8fba96f30..bf59498b2 100644 --- a/rtimer.c +++ b/rtimer.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.1 2007/03/25 17:10:30 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.2 2007/03/28 20:28:22 adamdunkels Exp $ */ #include "sys/rtimer.h" @@ -57,12 +57,15 @@ rtimer_init(void) } /*---------------------------------------------------------------------------*/ int -rtimer_set(struct rtimer *rtimer, rt_clock_t time, rt_clock_t duration, +rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, void (* func)(struct rtimer *t, void *ptr), void *ptr) { int i; PRINTF("rtimer_set time %d\n", time); + + rtimer->func = func; + rtimer->ptr = ptr; /* Check if rtimer queue is full. */ if(firstempty == (next - 1) % LIST_SIZE) { @@ -86,20 +89,20 @@ rtimer_set(struct rtimer *rtimer, rt_clock_t time, rt_clock_t duration, /* Put the rtimer at the end of the rtimer list. */ rtimer->time = time; rtimers[firstempty] = rtimer; - PRINTF("rt_post: putting rtimer %s as %d\n", rtimer->name, firstempty); + PRINTF("rtimer_post: putting rtimer %s as %d\n", rtimer->name, firstempty); firstempty = (firstempty + 1) % LIST_SIZE; - /* PRINTF("rt_post: next %d firstempty %d scheduling soon\n", + /* PRINTF("rtimer_post: next %d firstempty %d scheduling soon\n", next, firstempty);*/ /* Check if this is the first rtimer on the list. If so, we need to - run the rt_arch_schedule() function to get the ball rolling. */ + run the rtimer_arch_schedule() function to get the ball rolling. */ if(firstempty == (next + 1) % LIST_SIZE) { PRINTF("rtimer_set scheduling %d %s (%d)\n", next, rtimers[next]->name, rtimers[next]->time); - rtimer + rtimer_arch_schedule(rtimers[next]->time); } return RTIMER_OK; @@ -132,7 +135,7 @@ rtimer_run_next(void) PRINTF("rtimer_run_next checking %s (%d) against %s (%d)\n", rtimers[i]->name, rtimers[i]->time, rtimers[n]->name, rtimers[n]->time); - if(RT_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { + if(RTIMER_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { n = i; } } diff --git a/rtimer.h b/rtimer.h index 268bb6fe7..23344daaa 100644 --- a/rtimer.h +++ b/rtimer.h @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.1 2007/03/25 17:11:02 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.2 2007/03/28 20:28:22 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -133,6 +133,8 @@ void rtimer_arch_init(void); void rtimer_arch_schedule(rtimer_clock_t t); rtimer_clock_t rtimer_arch_now(void); +#define RTIMER_SECOND RTIMER_ARCH_SECOND + #include "rtimer-arch.h" #endif /* __RTIMER_H__ */ From e04d8dbaa4c5e5b0a916cd12652b1bed067f7843 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 30 Mar 2007 00:04:12 +0000 Subject: [PATCH 020/146] Removed erroneous documentation --- process.h | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/process.h b/process.h index 7e5a1d6e4..b49e5510d 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.5 2006/10/09 11:54:29 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.6 2007/03/30 00:04:12 adamdunkels Exp $ */ /** @@ -293,16 +293,6 @@ CLIF extern const struct process *process_load; */ #define PROCESS_NAME(name) extern struct process name -/** - * Declare a process that should not be automatically loaded. - * - * This macro is similar to the PROCESS() declaration, with the - * difference that for programs that are compiled as loadable - * programs, processes declared with the PROCESS_NOLOAD() declaration - * will not be automatically started when the program is loaded. - * - * \hideinitializer - */ #define PROCESS_NOLOAD(name, strname) \ PROCESS_THREAD(name, ev, data); \ struct process name = { NULL, strname, \ @@ -314,12 +304,6 @@ CLIF extern const struct process *process_load; * variable of the process structure, which is used by the C program, * and a human readable string name, which is used when debugging. * - * \note For programs that are compiled as loadable programs: the - * process declared with the PROCESS() declaration will be - * automatically started when the program is loaded. The - * PROCESS_NOLOAD() declaration can be used to declare a process that - * shouldn't be automatically loaded. - * * \param name The variable name of the process structure. * \param strname The string repressentation of the process' name. * From da1f9478a7514fc643ea8f1c6bbb00c2a6457d8a Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 31 Mar 2007 11:20:20 +0000 Subject: [PATCH 021/146] Correct function prototype --- rtimer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtimer.h b/rtimer.h index 23344daaa..0a4ebafd1 100644 --- a/rtimer.h +++ b/rtimer.h @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.2 2007/03/28 20:28:22 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.3 2007/03/31 11:20:20 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -102,7 +102,7 @@ int rtimer_set(struct rtimer *t, rtimer_clock_t time, rtimer_clock_t duration, * code to execute and schedule the next real-time task. * */ -void rtimer_next(void); +void rtimer_run_next(void); /** * \brief Get the current clock time From 2b6c01a626e4d58b61d5baaf6c9eab04284d4321 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 2 Apr 2007 18:07:10 +0000 Subject: [PATCH 022/146] Documentation updates --- process.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process.h b/process.h index b49e5510d..186c9f759 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.6 2007/03/30 00:04:12 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.7 2007/04/02 18:07:26 adamdunkels Exp $ */ /** @@ -39,7 +39,7 @@ /** * \defgroup process Contiki processes * - * A process in Contiki consists of a single \ref pt protothread. + * A process in Contiki consists of a single \ref pt "protothread". * * @{ */ From d88d1e01f586f72bffec56e4afd61d7866ca9ea0 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Tue, 3 Apr 2007 18:47:21 +0000 Subject: [PATCH 023/146] Added mt_stop() calling mtarch_stop() to allow for thread resource cleanup. --- mt.c | 24 ++++++++++++-------- mt.h | 73 +++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/mt.c b/mt.c index de81df16e..1757fadf0 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.4 2007/03/15 21:46:07 adamdunkels Exp $ + * $Id: mt.c,v 1.5 2007/04/03 18:47:21 oliverschmidt Exp $ */ /** @@ -92,14 +92,6 @@ mt_exec(struct mt_thread *thread) } } /*--------------------------------------------------------------------------*/ -void -mt_exit(void) -{ - current->state = MT_STATE_EXITED; - current = NULL; - mtarch_yield(); -} -/*--------------------------------------------------------------------------*/ #if 0 void mt_exec_event(struct mt_thread *thread, process_event_t ev, @@ -132,6 +124,20 @@ mt_yield(void) } /*--------------------------------------------------------------------------*/ +void +mt_exit(void) +{ + current->state = MT_STATE_EXITED; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mt_stop(struct mt_thread *thread) +{ + mtarch_stop(&thread->thread); +} +/*--------------------------------------------------------------------------*/ #if 0 void mt_post(struct process *p, process_event_t ev, diff --git a/mt.h b/mt.h index dbadde2eb..d8330b0a7 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.3 2006/09/26 20:59:51 adamdunkels Exp $ + * $Id: mt.h,v 1.4 2007/04/03 18:47:21 oliverschmidt Exp $ */ /** \addtogroup sys @@ -57,17 +57,19 @@ * * The Contiki multi-threading library requires some architecture * specific support for seting up and switching stacks. This support - * requires three stack manipulation functions to be implemented: + * requires four stack manipulation functions to be implemented: * mtarch_start(), which sets up the stack frame for a new thread, - * mtarch_exec(), which switches in the stack of a thread, and + * mtarch_exec(), which switches in the stack of a thread, * mtarch_yield(), which restores the kernel stack from a thread's - * stack. Additionally, two functions for controlling the preemption - * (if any) must be implemented: mtarch_preemption_start() and - * mtarch_preemption_stop(). If no preemption is used, these functions - * can be implemented as empty functions. Finally, the function - * mtarch_init() is called by mt_init(), and can be used for - * initalization of timer interrupts, or any other mechanisms required - * for correct operation of the architecture specific support funcions. + * stack and mtarch_stop(), which cleans up the stack of a thread. + * Additionally, two functions for controlling the preemption + * (if any) must be implemented: mtarch_pstart() and mtarch_pstop(). + * If no preemption is used, these functions can be implemented as + * empty functions. Finally, the function mtarch_init() is called by + * mt_init(), and can be used for initalization of timer interrupts, + * or any other mechanisms required for correct operation of the + * architecture specific support funcions while mtarch_remove() is + * called by mt_remove() to clean up those resources. * */ @@ -130,6 +132,21 @@ void mtarch_start(struct mtarch_thread *thread, void (* function)(void *data), void *data); +/** + * Start executing a thread. + * + * This function is called from mt_exec() and the purpose of the + * function is to start execution of the thread. The function should + * switch in the stack of the thread, and does not return until the + * thread has explicitly yielded (using mt_yield()) or until it is + * preempted. + * + * \param thread A pointer to a struct mtarch_thread for the thread to + * be executed. + * + */ +void mtarch_exec(struct mtarch_thread *thread); + /** * Yield the processor. * @@ -140,17 +157,19 @@ void mtarch_start(struct mtarch_thread *thread, void mtarch_yield(void); /** - * Start executing a thread. + * Clean up the stack of a thread. * - * This function is called from mt_exec() and the purpose of the - * function is to start execution of the thread. The function should - * switch in the stack of the thread, and does not return until the - * thread has explicitly yielded (using mt_yield()) or until it is - * preempted. + * This function is called by the mt_stop() function in order to clean + * up the architecture specific stack of the thread to be stopped. + * + * \note If the stack is wholly contained in struct mtarch_thread this + * function may very well be empty. + * + * \param thread A pointer to a struct mtarch_thread for the thread to + * be stopped. * */ -void mtarch_exec(struct mtarch_thread *thread); - +void mtarch_stop(struct mtarch_thread *thread); void mtarch_pstart(void); void mtarch_pstop(void); @@ -208,7 +227,8 @@ void mt_start(struct mt_thread *thread, void (* function)(void *), void *data); * thread. The function does not return until the thread has yielded, * or is preempted. * - * \note The thread must first be initialized with the mt_init() function. + * \note The thread library must first be initialized with the mt_init() + * function. * * \param thread A pointer to a struct mt_thread block that must be * allocated by the caller. @@ -224,7 +244,8 @@ void mt_exec(struct mt_thread *thread); * number. If the thread is not waiting for the event, this function * does nothing. * - * \note The thread must first be initialized with the mt_init() function. + * \note The thread library must first be initialized with the mt_init() + * function. * * \param thread A pointer to a struct mt_thread block that must be * allocated by the caller. @@ -292,6 +313,18 @@ void mt_yield(void); */ void mt_exit(void); +/** + * Stop a thread. + * + * This function is called by a Contiki process in order to clean up a + * thread. The struct mt_thread block may then be discarded by the caller. + * + * \param thread A pointer to a struct mt_thread block that must be + * allocated by the caller. + * + */ +void mt_stop(struct mt_thread *thread); + #if 0 /** * \defgroup mtp Multi-threading library convenience functions From 8118f022ef35d54815837b1d5b4f8d54a0ddee95 Mon Sep 17 00:00:00 2001 From: nifi Date: Wed, 4 Apr 2007 09:19:18 +0000 Subject: [PATCH 024/146] corrected comment --- process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process.c b/process.c index a54163f93..10cb2616b 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.4 2007/03/25 17:18:37 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.5 2007/04/04 09:19:18 nifi Exp $ */ /** @@ -119,7 +119,7 @@ process_start(struct process *p, char *arg) PT_INIT(&p->pt); - /* Post a synchronous event to the process. */ + /* Post an asynchronous event to the process. */ process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); } /*---------------------------------------------------------------------------*/ From d96b525765f0c05acd39c594b0a2ea7907ef27a3 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 17 May 2007 00:23:58 +0000 Subject: [PATCH 025/146] Bugfix: should not invoke timer if timer list is empty. --- rtimer.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/rtimer.c b/rtimer.c index bf59498b2..af8b2a037 100644 --- a/rtimer.c +++ b/rtimer.c @@ -28,13 +28,13 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.2 2007/03/28 20:28:22 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.3 2007/05/17 00:23:58 adamdunkels Exp $ */ #include "sys/rtimer.h" #include "contiki.h" -#define LIST_SIZE 16 +#define LIST_SIZE 4 static struct rtimer *rtimers[LIST_SIZE]; static u8_t next, firstempty; @@ -78,6 +78,12 @@ rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { + if(rtimers[i] == rtimer) { + /* Check if timer is already scheduled. If so, we do not + schedule it again. */ + return RTIMER_ERR_ALREADY_SCHEDULED; + + } /* XXX: should check a range of time not just the same precise moment. */ if(rtimers[i]->time == time) { @@ -89,7 +95,7 @@ rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, /* Put the rtimer at the end of the rtimer list. */ rtimer->time = time; rtimers[firstempty] = rtimer; - PRINTF("rtimer_post: putting rtimer %s as %d\n", rtimer->name, firstempty); + PRINTF("rtimer_post: putting rtimer %p as %d\n", rtimer, firstempty); firstempty = (firstempty + 1) % LIST_SIZE; @@ -100,8 +106,8 @@ rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, run the rtimer_arch_schedule() function to get the ball rolling. */ if(firstempty == (next + 1) % LIST_SIZE) { - PRINTF("rtimer_set scheduling %d %s (%d)\n", - next, rtimers[next]->name, rtimers[next]->time); + PRINTF("rtimer_set scheduling %d %p (%d)\n", + next, rtimers[next], rtimers[next]->time); rtimer_arch_schedule(rtimers[next]->time); } @@ -114,13 +120,18 @@ rtimer_run_next(void) int i, n; struct rtimer *t; + /* Do not run timer if list is empty. */ + if(next == firstempty) { + return; + } + t = rtimers[next]; /* Increase the pointer to the next rtimer. */ next = (next + 1) % LIST_SIZE; /* Run the rtimer. */ - PRINTF("rtimer_run_next running %s\n", t->name); + PRINTF("rtimer_run_next running %p\n", t); t->func(t, t->ptr); if(next == firstempty) { @@ -132,24 +143,24 @@ rtimer_run_next(void) /* Find the next rtimer to run. */ n = next; for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { - PRINTF("rtimer_run_next checking %s (%d) against %s (%d)\n", - rtimers[i]->name, rtimers[i]->time, - rtimers[n]->name, rtimers[n]->time); + PRINTF("rtimer_run_next checking %p (%d) against %p (%d)\n", + rtimers[i], rtimers[i]->time, + rtimers[n], rtimers[n]->time); if(RTIMER_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { n = i; } } - PRINTF("rtimer_run_next next rtimer is %d %s (%d)\n", - n, rtimers[n]->name, rtimers[n]->time); + PRINTF("rtimer_run_next next rtimer is %d %p (%d)\n", + n, rtimers[n], rtimers[n]->time); /* Put the next rtimer first in the rtimer list. */ t = rtimers[next]; rtimers[next] = rtimers[n]; rtimers[n] = t; - PRINTF("rtimer_run_next scheduling %d %s (%d)\n", - next, rtimers[next]->name, rtimers[next]->time); + PRINTF("rtimer_run_next scheduling %d %p (%d)\n", + next, rtimers[next], rtimers[next]->time); rtimer_arch_schedule(rtimers[next]->time); } From a6a2e81c8495a789d1fc2210abaad55194ef4ee5 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 17 May 2007 00:24:29 +0000 Subject: [PATCH 026/146] Added error return value --- rtimer.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtimer.h b/rtimer.h index 0a4ebafd1..04d127730 100644 --- a/rtimer.h +++ b/rtimer.h @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.3 2007/03/31 11:20:20 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.4 2007/05/17 00:24:29 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -79,6 +79,7 @@ enum { RTIMER_OK, RTIMER_ERR_FULL, RTIMER_ERR_TIME, + RTIMER_ERR_ALREADY_SCHEDULED, }; /** @@ -131,7 +132,7 @@ void rtimer_run_next(void); void rtimer_arch_init(void); void rtimer_arch_schedule(rtimer_clock_t t); -rtimer_clock_t rtimer_arch_now(void); +/*rtimer_clock_t rtimer_arch_now(void);*/ #define RTIMER_SECOND RTIMER_ARCH_SECOND From caf9d3659d0ffd2c73f9cfa6538de85c6802c6ac Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 22 May 2007 20:58:14 +0000 Subject: [PATCH 027/146] Removed unused code --- mt.c | 115 +---------------------------------------------------------- 1 file changed, 1 insertion(+), 114 deletions(-) diff --git a/mt.c b/mt.c index 1757fadf0..367392960 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.5 2007/04/03 18:47:21 oliverschmidt Exp $ + * $Id: mt.c,v 1.6 2007/05/22 20:58:14 adamdunkels Exp $ */ /** @@ -92,24 +92,6 @@ mt_exec(struct mt_thread *thread) } } /*--------------------------------------------------------------------------*/ -#if 0 -void -mt_exec_event(struct mt_thread *thread, process_event_t ev, - process_data_t data) -{ - if(thread->state == MT_STATE_WAITING || - thread->state == MT_STATE_PEEK) { - *(thread->evptr) = ev; - *(thread->dataptr) = data; - thread->state = MT_STATE_RUNNING; - current = thread; - /* Switch context to the thread. The function call will not return - until the the thread has yielded, or is preempted. */ - mtarch_exec(&thread->thread); - } -} -#endif -/*--------------------------------------------------------------------------*/ void mt_yield(void) { @@ -138,98 +120,3 @@ mt_stop(struct mt_thread *thread) mtarch_stop(&thread->thread); } /*--------------------------------------------------------------------------*/ -#if 0 -void -mt_post(struct process *p, process_event_t ev, - process_data_t data) -{ - /* Turn off preemption to ensure mutual exclusion of kernel. */ - mtarch_pstop(); - - process_post(p, ev, data); - - /* Turn preemption on again. */ - mtarch_pstart(); -} -#endif -/*--------------------------------------------------------------------------*/ -#if 0 -void -mt_wait(process_event_t *ev, process_data_t *data) -{ - mtarch_pstop(); - current->evptr = ev; - current->dataptr = data; - current->state = MT_STATE_WAITING; - current = NULL; - mtarch_yield(); -} -/*--------------------------------------------------------------------------*/ -void -mt_peek(process_event_t *ev, process_data_t *data) -{ - mtarch_pstop(); - *ev = PROCESS_EVENT_NONE; - current->evptr = ev; - current->dataptr = data; - current->state = MT_STATE_PEEK; - current = NULL; - mtarch_yield(); -} -#endif -/*--------------------------------------------------------------------------*/ -#if 0 -void -mtp_start(struct mt_process *t, - void (* function)(void *), void *data) -{ - mt_start(&t->t, function, data); - process_start(t->p, function); -} -/*--------------------------------------------------------------------------*/ -void -mtp_exit(void) -{ - mtarch_pstop(); - mt_exit(); - mt_remove(); -} -/*--------------------------------------------------------------------------*/ -/*void -mtp_eventhandler(ek_event_t ev, ek_data_t data) -{ - struct mtp_thread *thread = (struct mtp_thread *)EK_PROC_STATE(EK_CURRENT()); - - if(ev == EK_EVENT_REQUEST_EXIT) { - ek_exit(); - LOADER_UNLOAD(); - - } else if(ev == EK_EVENT_INIT) { - - ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); - - } else if(ev == EK_EVENT_CONTINUE) { - - if(thread->t.state == MT_STATE_READY || - thread->t.state == MT_STATE_PEEK) { - mt_exec(&thread->t); - if(thread->t.state == MT_STATE_EXITED) { - ek_exit(); - LOADER_UNLOAD(); - } else { - ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); - } - } - } else { - mt_exec_event(&thread->t, ev, data); - if(thread->t.state == MT_STATE_EXITED) { - ek_exit(); - LOADER_UNLOAD(); - } else if(thread->t.state == MT_STATE_READY || - thread->t.state == MT_STATE_PEEK) { - ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); - } - } -}*/ -/*--------------------------------------------------------------------------*/ -#endif /* 0 */ From c677e23cbd64d452e7e2e081c9a026716242989d Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 22 May 2007 20:58:38 +0000 Subject: [PATCH 028/146] Documentation fix. Number of rtimers configurable with contiki-conf.h --- rtimer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/rtimer.c b/rtimer.c index af8b2a037..0a0f78294 100644 --- a/rtimer.c +++ b/rtimer.c @@ -1,3 +1,17 @@ +/** + * \addtogroup rt + * @{ + */ + +/** + * \file + * Implementation of the architecture-agnostic parts of the real-time timer module. + * \author + * Adam Dunkels + * + */ + + /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -28,13 +42,17 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.3 2007/05/17 00:23:58 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.4 2007/05/22 20:58:38 adamdunkels Exp $ */ #include "sys/rtimer.h" #include "contiki.h" +#ifdef RTIMER_CONF_NUM +#define LIST_SIZE RTIMER_CONF_NUM +#else #define LIST_SIZE 4 +#endif static struct rtimer *rtimers[LIST_SIZE]; static u8_t next, firstempty; From e1520315116419e66c569018893ca517504dfd72 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 22 May 2007 20:58:49 +0000 Subject: [PATCH 029/146] Documentation fix. --- rtimer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtimer.h b/rtimer.h index 04d127730..fd926d070 100644 --- a/rtimer.h +++ b/rtimer.h @@ -9,7 +9,7 @@ /** * \file - * Header file for the real-time module. + * Header file for the real-time timer module. * \author * Adam Dunkels * @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.4 2007/05/17 00:24:29 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.5 2007/05/22 20:58:49 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ From 4839c187a8c4af555b4f2d699e1dedd5f3bda14c Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Wed, 23 May 2007 22:16:05 +0000 Subject: [PATCH 030/146] Removed the empty PROCESS_NO_BROADCAST macro. --- process.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/process.h b/process.h index 186c9f759..cc99a4d89 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.7 2007/04/02 18:07:26 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.8 2007/05/23 22:16:05 oliverschmidt Exp $ */ /** @@ -400,9 +400,6 @@ CCIF void process_exit(struct process *p); #define PROCESS_CURRENT() process_current CCIF extern struct process *process_current; -#define PROCESS_SET_FLAGS(flags) -#define PROCESS_NO_BROADCAST - /** * Switch context to another process * From c7cc9d88c986f9f9dc1dd394da2da49e1476340b Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sat, 26 May 2007 23:23:28 +0000 Subject: [PATCH 031/146] Finally moved service.[c|h] into backyard. The "only" user left in outside backyard is the CTK on GTK simulation layer - which needs to be updated to build / run again... --- service.c | 111 ------------------------------- service.h | 195 ------------------------------------------------------ 2 files changed, 306 deletions(-) delete mode 100644 service.c delete mode 100644 service.h diff --git a/service.c b/service.c deleted file mode 100644 index 646c6328e..000000000 --- a/service.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * @(#)$Id: service.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ - */ - -#include - -#include "contiki.h" - -/** - * \addtogroup service - * @{ - */ - -/** - * \file - * Implementation of the Contiki service mechanism. - * \author - * Adam Dunkels - */ - -static struct service *services_list = NULL; - -/*---------------------------------------------------------------------------*/ -void -service_register(struct service *s) -{ - struct service *existing; - - - s->p = PROCESS_CURRENT(); - - existing = service_find(s->name); - if(existing != NULL) { - service_remove(existing); - } - - s->next = services_list; - services_list = s; -} -/*---------------------------------------------------------------------------*/ -void -service_remove(struct service *s) -{ - struct service *t; - - - /* Check if service is first on the list. */ - if(s == services_list) { - services_list = s->next; - - /* Post a notification to the owner process. */ - process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); - - } else { - for(t = services_list; t != NULL && t->next != s; t = t->next); - if(t != NULL) { - t->next = s->next; - - /* Post a notification to the owner process. */ - process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); - } - } - - s->next = NULL; -} -/*---------------------------------------------------------------------------*/ -struct service * -service_find(const char *name) -{ - struct service *s; - - - for(s = services_list; s != NULL; s = s->next) { - if(strcmp(s->name, name) == 0) { - return s; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/service.h b/service.h deleted file mode 100644 index 3ea2e6d62..000000000 --- a/service.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * @(#)$Id: service.h,v 1.2 2006/09/09 23:25:07 oliverschmidt Exp $ - */ - -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup service The Contiki service mechanism - * - * The Contiki service mechanism enables cross-process functions. A - * service that is registered by one process can be accessed by other - * processes in the system. Services can be transparently replaced at - * run-time. - * - * A service has an interface that callers use to access the service's - * functions. This interface typically is defined in a header file - * that is included by all users of the service. A service interface - * is defined with the SERVICE_INTERFACE() macro. - * - * A service implementation is declared with the SERVICE() macro. The - * SERVICE() statement specifies the actual functions that are used to - * implement the service. - * - * Every service has a controlling process. The controlling process - * registers the service with the system when it starts, and is also - * notified if the service is removed or replaced. A process may - * register any number of services. - * - * Service registration is done with a SERVICE_REGISTER() - * statement. If a service with the same name is already registered, - * this is removed before the new service is registered. - * - * The SERVICE_CALL() macro is used to call a service. If the service - * to be called is not registered, the SERVICE_CALL() statement does - * nothing. The SERVICE_FIND() function can be used to check if a - * particular service exists before calling SERVICE_CALL(). - * - * @{ - */ - -/** - * \file - * Header file for the Contiki service mechanism. - * \author - * Adam Dunkels - */ - -#ifndef __SERVICE_H__ -#define __SERVICE_H__ - -#include "contiki.h" - -struct service { - struct service *next; - struct process *p; - const char *name; - const void *interface; -}; - -/** - * \name Service declaration and defition - * @{ - */ - -/** - * Define the name and interface of a service. - * - * This statement defines the name and interface of a service. - * - * \param name The name of the service. - * - * \param interface A list of function declarations that comprises the - * service interface. This list must be enclosed by curly brackets and - * consist of declarations of function pointers separated by - * semicolons. - * - * \hideinitializer - */ -#define SERVICE_INTERFACE(name, interface) struct name interface; - -#if ! CC_NO_VA_ARGS -/** - * \brief Define an implementation of a service interface. - * \param name The name of this particular instance of the service, for use with SERVICE_REGISTER(). - * \param service_name The name of the service, from the SERVICE_INTERFACE(). - * \param ... A structure containing the functions that implements the service. - * - * This statement defines the name of this implementation - * of the service and defines the functions that actually - * implement the functions offered by the service. - * - * \hideinitializer - */ -#define SERVICE(name, service_name, ...) \ - static struct service_name name##_interface = __VA_ARGS__ ; \ - struct service name = { NULL, NULL, service_name##_name, & name##_interface } -#endif - -/** @} */ - -/** - * \name Calling a service - * @{ - */ - -/** - * Call a function from a specified service, if it is registered. - * - * - * \param service_name The name of the service that is to be called. - * - * \param function The function that is to be called. This is a full - * function call, including parameters. - * - * \hideinitializer - */ -#define SERVICE_CALL(service_name, function) \ - { \ - struct service *service_s; \ - service_s = service_find(service_name##_name); \ - if(service_s != NULL) { \ - ((const struct service_name *)service_s->interface)->function; \ - } \ - } - -/* @} */ - -#define SERVICE_EXISTS(service_name) (service_find(service_name##_name) != NULL) - -/** - * \name Service registration and removal - * @{ - */ - -/** - * Register a service. - * - * \hideinitializer - */ -#define SERVICE_REGISTER(name) service_register(&name) - -/** - * Remove a service. - * - * \hideinitializer - */ -#define SERVICE_REMOVE(service_name) service_remove(&service_name) - -/** @} */ - -/** - * Find service. - * - * \hideinitializer - */ -#define SERVICE_FIND(service_name) service_find(service_name##_name) - -CCIF void service_register(struct service *s); -CCIF void service_remove(struct service *s); -struct service *service_find(const char *name); - -#endif /* __SERVICE_H__ */ -/** @} */ -/** @} */ From 15974e6715dc108ffd7be041ee0039f4ca86cee6 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 27 May 2007 11:11:28 +0000 Subject: [PATCH 032/146] Fixed typo. --- timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/timer.c b/timer.c index c77ec0508..2719834db 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: timer.c,v 1.2 2007/05/27 11:11:28 oliverschmidt Exp $ */ #include "contiki-conf.h" @@ -75,7 +75,7 @@ timer_set(struct timer *t, clock_time_t interval) * given to the timer_set() function. The start point of the interval * is the exact time that the timer last expired. Therefore, this * function will cause the timer to be stable over time, unlike the - * timer_rester() function. + * timer_restart() function. * * \param t A pointer to the timer. * From 76d4a48ad37f5a83cbb1f8621ef8f4bb938ece06 Mon Sep 17 00:00:00 2001 From: ksb Date: Wed, 22 Aug 2007 10:49:48 +0000 Subject: [PATCH 033/146] Changed macros to not include a trailing semicolon. --- process.h | 8 ++++---- procinit.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/process.h b/process.h index cc99a4d89..d9eb34863 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.8 2007/05/23 22:16:05 oliverschmidt Exp $ + * @(#)$Id: process.h,v 1.9 2007/08/22 10:49:48 ksb Exp $ */ /** @@ -277,9 +277,9 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_data_t data)) #if PROCESS_LOADABLE -#define PROCESS_LOAD(name) const struct process *process_load = &name; +#define PROCESS_LOAD(name) const struct process *process_load = &name #else /* PROCESS_LOADABLE */ -#define PROCESS_LOAD(name) +#define PROCESS_LOAD(name) extern int _dummy #endif /* PROCESS_LOADABLE */ CLIF extern const struct process *process_load; @@ -296,7 +296,7 @@ CLIF extern const struct process *process_load; #define PROCESS_NOLOAD(name, strname) \ PROCESS_THREAD(name, ev, data); \ struct process name = { NULL, strname, \ - process_thread_##name }; + process_thread_##name } /** * Declare a process. * diff --git a/procinit.h b/procinit.h index f00dcdcd0..b590560ee 100644 --- a/procinit.h +++ b/procinit.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: procinit.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * @(#)$Id: procinit.h,v 1.2 2007/08/22 10:49:48 ksb Exp $ */ #ifndef __PROCINIT_H__ #define __PROCINIT_H__ @@ -37,7 +37,7 @@ #if ! CC_NO_VA_ARGS #define PROCINIT(...) \ -const struct process *procinit[] = {__VA_ARGS__, NULL}; +const struct process *procinit[] = {__VA_ARGS__, NULL} #endif void procinit_init(void); From b123cc60708da7fe37f444575c12dbe7a4f0c588 Mon Sep 17 00:00:00 2001 From: matsutsuka Date: Thu, 30 Aug 2007 14:39:16 +0000 Subject: [PATCH 034/146] Support for z80(sdcc) port. In order to support, some core modules are modified as follows: core/sys/dsc.h - If CTK_CONF_ICONS is diabled, the whole icon-related code is disabled. - DSC_HEADER is changed to remove extra semicolon. core/sys/process.h - process_data_t is expressed by void* in signatures (known bug on sdcc). core/sys/autostart.h - autostart_processes is changed to remove extra semicolon. core/sys/cc.h - CC_CONF_ASSIGN_AGGREGATE is introduced. - CC_CONF_INC_CAST_POINTER is introduced, a workaround of a kind of sdcc bug for an increment. core/net/hc.c core/net/uip_arp.c core/net/uaodv.c - Aggregation assignments are changed to uip_ipaddr_copy. core/net/psock.c core/net/uipbuf.c core/net/dhcpc.c apps/shell/shell.c core/ctk/vnc-server.c core/ctk/vnc-out.c - "register" keyword in a signature cannot be used in sdcc, CC_REGISTER_ARG is used instead. core/net/uip-over-mesh.c - An extra semicolon is removed. apps/dhcp/dhcp-dsc.c apps/shell/shell-dsc. apps/ftp/ftp-dsc.c apps/process-list/process-list-dsc.c apps/email/email-dsc.c apps/webserver/webserver-dsc.c apps/vnc/vnc-dsc.c apps/vnc/vnc-viewer.h apps/webbrowser/www-dsc.c apps/about/about-dsc.c apps/irc/irc-dsc.c apps/telnet/telnet-dsc.c apps/telnetd/telnetd-dsc.c apps/netconf/netconf-dsc.c apps/directory/directory-dsc.c pps/calc/calc-dsc.c - Modify an extern type to a real declaration, which is static to prevent a compile error. core/net/mac/xmac.c - Variables cannot be defined in a head of block on sdcc. core/ctk/ctk.h core/ctk/ctk.c apps/program-handler/program-handler.c - If CTK_CONF_ICONS is diabled, the whole icon-related code is disabled. Makefile.include - Add a set of configuration for an assembler. - $(CLEAN) variable is introduced for customized cleanup. apps/process-list/process-list.c - PROCESSLIST_CONF_HEIGHT is introduced to address smaller screen size. core/lib/ctk-filedialog.c - FILES_CONF_HEIGHT is introduced to address smaller screen size. - "register" keyword in a signature cannot be used in sdcc, CC_REGISTER_ARG is used instead. apps/vnc/vnc-viewer.c - A cast is added to prevent a compile error. - "register" keyword in a signature cannot be used in sdcc, CC_REGISTER_ARG is used instead. apps/webbrowser/webclient.c - CC_CONF_INC_CAST_POINTER is introduced, a workaround of a kind of sdcc bug for an increment. core/loader/elfloader.c - A cast is added to prevent a compile error. core/net/rime/rimeaddr.c - An initialization is added to prevent a compile error. core/net/rime/rudolph0.c - NULL is changed to 0, because NULL causes a compile error. core/net/rime/route-discovery.c - Add an argument to match the definition of nf_callbacks. cpu/z80/strcasecmp.h cpu/z80/strcasecmp.c cpu/z80/contiki-sdcc-conf.h cpu/z80/mtarch.c cpu/z80/mtarch.h cpu/z80/Makefile.z80 - New files to make compilation availble on sdcc. - Added support for multithreading. --- autostart.h | 7 ++++--- cc.h | 22 +++++++++++++++++++++- dsc.h | 17 +++++++++++++++-- process.h | 6 +++--- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/autostart.h b/autostart.h index 74ae81c6f..7d5a64842 100644 --- a/autostart.h +++ b/autostart.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: autostart.h,v 1.2 2007/08/30 14:39:17 matsutsuka Exp $ */ /** @@ -46,9 +46,10 @@ #if ! CC_NO_VA_ARGS #if AUTOSTART_ENABLE #define AUTOSTART_PROCESSES(...) \ -const struct process *autostart_processes[] = {__VA_ARGS__, NULL}; +const struct process *autostart_processes[] = {__VA_ARGS__, NULL} #else /* AUTOSTART_ENABLE */ -#define AUTOSTART_PROCESSES(...) +#define AUTOSTART_PROCESSES(...) \ +extern int _dummy #endif /* AUTOSTART_ENABLE */ #else #error "C compiler must support __VA_ARGS__ macro" diff --git a/cc.h b/cc.h index af23545f3..5895a9f4f 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: cc.h,v 1.2 2007/08/30 14:39:17 matsutsuka Exp $ * */ #ifndef __CC_H__ @@ -101,6 +101,26 @@ #define CC_INLINE #endif /* CC_CONF_INLINE */ +/** + * Configure if the C compiler supports the assignment of struct value. + */ +#ifdef CC_CONF_ASSIGN_AGGREGATE +#define CC_ASSIGN_AGGREGATE(dest, src) CC_ASSIGN_AGGREGATE(dest, src) +#else /* CC_CONF_ASSIGN_AGGREGATE */ +#define CC_ASSIGN_AGGREGATE(dest, src) *dest = *src +#endif /* CC_CONF_ASSIGN_AGGREGATE */ + +/** + * Configure if the C compiler supports the increment of pointer. + */ +#ifdef CC_CONF_INC_CAST_POINTER +#define CC_INC_CAST_POINTER(type, data) \ + CC_CONF_INC_CAST_POINTER(type, data) +#else /* CC_CONF_INC_CAST_POINTER */ +#define CC_INC_CAST_POINTER(type, data) \ + ++((type) data) +#endif /* CC_CONF_INC_CAST_POINTER */ + #if CC_CONF_NO_VA_ARGS #define CC_NO_VA_ARGS CC_CONF_VA_ARGS #endif diff --git a/dsc.h b/dsc.h index 4906c482c..3a688709d 100644 --- a/dsc.h +++ b/dsc.h @@ -56,7 +56,7 @@ * * This file is part of the Contiki desktop environment * - * $Id: dsc.h,v 1.2 2006/08/26 23:59:39 oliverschmidt Exp $ + * $Id: dsc.h,v 1.3 2007/08/30 14:39:17 matsutsuka Exp $ * */ #ifndef __DSC_H__ @@ -82,8 +82,10 @@ struct dsc { struct process *process; /**< A pointer to the program's process. */ #endif /* WITH_LOADER_ARCH */ +#if CTK_CONF_ICONS struct ctk_icon *icon; /**< A pointer to the ctk_icon structure for the DSC. */ +#endif /* CTK_CONF_ICONS */ #if WITH_LOADER_ARCH void *loadaddr; /**< The loading address of the DSC. Used by @@ -109,15 +111,26 @@ struct dsc { * \param icon A pointer to the CTK icon. */ #if WITH_LOADER_ARCH +#if CTK_CONF_ICONS #define DSC(dscname, description, prgname, process, icon) \ CLIF const struct dsc dscname = {description, prgname, icon} +#else /* CTK_CONF_ICONS */ +#define DSC(dscname, description, prgname, process, icon) \ + CLIF const struct dsc dscname = {description, prgname} +#endif /* CTK_CONF_ICONS */ #else /* WITH_LOADER_ARCH */ +#if CTK_CONF_ICONS #define DSC(dscname, description, prgname, process, icon) \ PROCESS_NAME(process); \ const struct dsc dscname = {description, &process, icon} +#else /* CTK_CONF_ICONS */ +#define DSC(dscname, description, prgname, process, icon) \ + PROCESS_NAME(process); \ + const struct dsc dscname = {description, &process} +#endif /* CTK_CONF_ICONS */ #endif /* WITH_LOADER_ARCH */ -#define DSC_HEADER(name) extern struct dsc name; +#define DSC_HEADER(name) extern struct dsc name #ifndef NULL #define NULL 0 diff --git a/process.h b/process.h index d9eb34863..15da37d7b 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.9 2007/08/22 10:49:48 ksb Exp $ + * @(#)$Id: process.h,v 1.10 2007/08/30 14:39:17 matsutsuka Exp $ */ /** @@ -360,7 +360,7 @@ void process_start(struct process *p, char *arg); * \retval PROCESS_ERR_FULL The event queue was full and the event could * not be posted. */ -CCIF int process_post(struct process *p, process_event_t ev, process_data_t data); +CCIF int process_post(struct process *p, process_event_t ev, void* data); /** * Post a synchronous event to a process. @@ -373,7 +373,7 @@ CCIF int process_post(struct process *p, process_event_t ev, process_data_t data * with the event. */ void process_post_synch(struct process *p, - process_event_t ev, process_data_t data); + process_event_t ev, void* data); /** * \brief Cause a process to exit From 4925b850ed607ccf4e08cc64676ce984a75fb1bb Mon Sep 17 00:00:00 2001 From: matsutsuka Date: Sat, 1 Sep 2007 00:49:41 +0000 Subject: [PATCH 035/146] Fixed a glitch of CC_CONF_ASSIGN_AGGREGATE. --- cc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cc.h b/cc.h index 5895a9f4f..47f5f77ee 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.2 2007/08/30 14:39:17 matsutsuka Exp $ + * $Id: cc.h,v 1.3 2007/09/01 00:49:41 matsutsuka Exp $ * */ #ifndef __CC_H__ @@ -105,7 +105,7 @@ * Configure if the C compiler supports the assignment of struct value. */ #ifdef CC_CONF_ASSIGN_AGGREGATE -#define CC_ASSIGN_AGGREGATE(dest, src) CC_ASSIGN_AGGREGATE(dest, src) +#define CC_ASSIGN_AGGREGATE(dest, src) CC_CONF_ASSIGN_AGGREGATE(dest, src) #else /* CC_CONF_ASSIGN_AGGREGATE */ #define CC_ASSIGN_AGGREGATE(dest, src) *dest = *src #endif /* CC_CONF_ASSIGN_AGGREGATE */ From 9b56da52f498adb2f841309243f331e344c4bfb7 Mon Sep 17 00:00:00 2001 From: fros4943 Date: Fri, 7 Sep 2007 10:20:30 +0000 Subject: [PATCH 036/146] compare clock_time_t's --- clock.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clock.h b/clock.h index 8bcef866d..144c646e9 100644 --- a/clock.h +++ b/clock.h @@ -53,13 +53,15 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.2 2007/03/25 21:51:31 adamdunkels Exp $ + * $Id: clock.h,v 1.3 2007/09/07 10:20:30 fros4943 Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ #include "contiki-conf.h" +#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) + /** * Initialize the clock library. * From 32d6d0fad3718fcd45e36dbae6e001d8c1c53abc Mon Sep 17 00:00:00 2001 From: joxe Date: Sun, 7 Oct 2007 19:59:27 +0000 Subject: [PATCH 037/146] renamed variable, rewrote comment to make easier to read --- etimer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/etimer.c b/etimer.c index 3d41bb880..089ddbc8b 100644 --- a/etimer.c +++ b/etimer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: etimer.c,v 1.2 2006/10/09 16:05:58 nifi Exp $ + * $Id: etimer.c,v 1.3 2007/10/07 19:59:27 joxe Exp $ */ #include "contiki-conf.h" @@ -58,7 +58,7 @@ PROCESS(etimer_process, "Event timer"); static void update_time(void) { - clock_time_t nextt; + clock_time_t tdist; clock_time_t now; struct etimer *t; @@ -67,14 +67,14 @@ update_time(void) } else { now = clock_time(); t = timerlist; - /* Must take current time into account due to wraps */ - nextt = t->timer.start + t->timer.interval - now; + /* Must calculate distance to next time into account due to wraps */ + tdist = t->timer.start + t->timer.interval - now; for(t = t->next; t != NULL; t = t->next) { - if(t->timer.start + t->timer.interval - now < nextt) { - nextt = t->timer.start + t->timer.interval - now; + if(t->timer.start + t->timer.interval - now < tdist) { + tdist = t->timer.start + t->timer.interval - now; } } - next_expiration = nextt + now; + next_expiration = now + tdist; } } /*---------------------------------------------------------------------------*/ From 14b96467b712a6d37b27ec5bfaa3d74229180370 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 23 Oct 2007 20:33:19 +0000 Subject: [PATCH 038/146] Made rtimer callback a typedefed type to make function prototypes nicer --- rtimer.c | 7 ++++--- rtimer.h | 11 +++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rtimer.c b/rtimer.c index 0a0f78294..3430c4b71 100644 --- a/rtimer.c +++ b/rtimer.c @@ -42,7 +42,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.4 2007/05/22 20:58:38 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.5 2007/10/23 20:33:19 adamdunkels Exp $ */ #include "sys/rtimer.h" @@ -75,8 +75,9 @@ rtimer_init(void) } /*---------------------------------------------------------------------------*/ int -rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, - void (* func)(struct rtimer *t, void *ptr), void *ptr) +rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, + rtimer_clock_t duration, + rtimer_callback_t func, void *ptr) { int i; diff --git a/rtimer.h b/rtimer.h index fd926d070..5223da260 100644 --- a/rtimer.h +++ b/rtimer.h @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.5 2007/05/22 20:58:49 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.6 2007/10/23 20:33:19 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -62,6 +62,9 @@ typedef unsigned short rtimer_clock_t; */ void rtimer_init(void); +struct rtimer; +typedef void (* rtimer_callback_t)(struct rtimer *t, void *ptr); + /** * \brief Repressentation of a real-time task * @@ -71,7 +74,7 @@ void rtimer_init(void); */ struct rtimer { rtimer_clock_t time; - void (* func)(struct rtimer *t, void *ptr); + rtimer_callback_t func; void *ptr; }; @@ -93,8 +96,8 @@ enum { * time in the future. * */ -int rtimer_set(struct rtimer *t, rtimer_clock_t time, rtimer_clock_t duration, - void (* func)(struct rtimer *t, void *ptr), void *ptr); +int rtimer_set(struct rtimer *t, rtimer_clock_t time, + rtimer_clock_t duration, rtimer_callback_t func, void *ptr); /** * \brief Execute the next real-time task and schedule the next task, if any From 60e277ed4df14936054dc1034c58b0aa45a2f205 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 23 Oct 2007 20:39:07 +0000 Subject: [PATCH 039/146] Initial implementation of a profiling system for Contiki --- profile-aggregates.c | 244 +++++++++++++++++++++++++++++++++++++++++++ profile.c | 173 ++++++++++++++++++++++++++++++ profile.h | 156 +++++++++++++++++++++++++++ 3 files changed, 573 insertions(+) create mode 100644 profile-aggregates.c create mode 100644 profile.c create mode 100644 profile.h diff --git a/profile-aggregates.c b/profile-aggregates.c new file mode 100644 index 000000000..1ad3e3a3b --- /dev/null +++ b/profile-aggregates.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: profile-aggregates.c,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + */ + +/** + * \file + * Compuation of aggregates for the Contiki profiling system + * \author + * Adam Dunkels + */ + +#include "sys/profile.h" + +#include +#include + +struct aggregate { + const unsigned char *ptr; + unsigned short episodes; + unsigned long cycles; +}; + +#define DETAILED_AGGREGATES 0 + +#define MAX_CATEGORIES 32 +#define LIST_LEN 100 + +static struct aggregate aggregates[LIST_LEN]; + +static int aggregates_list_ptr = 0; + +/*---------------------------------------------------------------------------*/ +static struct aggregate * +find_aggregate_category(const uint16_t cat) +{ + int i; + uint16_t acat; + +/* printf("find_aggregate_category 0x%04x %c%c\n", */ +/* cat, cat >> 8, cat & 0xff); */ + + for(i = 0; i < aggregates_list_ptr; ++i) { + acat = (aggregates[i].ptr[0] << 8) + aggregates[i].ptr[1]; + +/* printf("acat 0x%04x %c%c\n", */ +/* acat, acat >> 8, acat & 0xff); */ + + if(acat == cat) { + return &aggregates[i]; + } + } + + if(i == LIST_LEN) { + return NULL; + } + + aggregates[aggregates_list_ptr].ptr = NULL; + return &aggregates[aggregates_list_ptr++]; +} +/*---------------------------------------------------------------------------*/ +static struct aggregate * +find_aggregate(const unsigned char *ptr) +{ + int i; + for(i = 0; i < aggregates_list_ptr; ++i) { + if(aggregates[i].ptr == ptr) { + return &aggregates[i]; + } + } + if(i == LIST_LEN) { + return NULL; + } + + return &aggregates[aggregates_list_ptr++]; +} +/*---------------------------------------------------------------------------*/ +void +profile_aggregates_print(void) +{ + int i; + +#if DETAILED_AGGREGATES + for(i = 0; i < aggregates_list_ptr; ++i) { + printf("-- %s: %lu / %u = %lu\n", aggregates[i].ptr, + aggregates[i].cycles, + aggregates[i].episodes, + aggregates[i].cycles / aggregates[i].episodes); + } +#else + for(i = 0; i < aggregates_list_ptr; ++i) { + printf("-- %c%c: %lu / %u = %lu\n", + aggregates[i].ptr[0], aggregates[i].ptr[1], + aggregates[i].cycles, + aggregates[i].episodes, + aggregates[i].cycles / aggregates[i].episodes); + } +#endif + + printf("Memory for aggregates: %d * %d = %d\n", + sizeof(struct aggregate), aggregates_list_ptr, + sizeof(struct aggregate) * aggregates_list_ptr); +} +/*---------------------------------------------------------------------------*/ +static void +detailed_profile_aggregates_compute(void) +{ + int i; + rtimer_clock_t t; + /* const char *str = "profile_aggregates_compute"; + + PROFILE_TIMESTAMP(str);*/ + + t = profile_timestamps[0].time; + + for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { + struct aggregate *a; + a = find_aggregate(profile_timestamps[i - 1].ptr); + if(a == NULL) { + /* The list is full, skip this entry */ + printf("profile_aggregates_compute: list full\n"); + } else if(a->ptr == NULL) { + a->ptr = profile_timestamps[i - 1].ptr; + a->cycles = (unsigned long)(profile_timestamps[i].time - t); + a->episodes = 1; + } else { + a->cycles += (unsigned long)(profile_timestamps[i].time - t); + a->episodes++; + } + t = profile_timestamps[i].time; + } + + /* PROFILE_TIMESTAMP(str);*/ + + /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", + profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, + aggregates_list_ptr, profile_timestamp_time);*/ + + + /* print_aggregates();*/ +} +/*---------------------------------------------------------------------------*/ +static void +category_profile_aggregates_compute(void) +{ + int i,j; + rtimer_clock_t t; + uint16_t categories[MAX_CATEGORIES]; + int categories_ptr = 0; + /* const char *str = "profile_aggregates_compute"; + + PROFILE_TIMESTAMP(str);*/ + + t = profile_timestamps[0].time; + + for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { + struct aggregate *a; + uint16_t cat; + +/* printf("category_profile_aggregates_compute %s\n", */ +/* profile_timestamps[i - 1].ptr); */ + cat = (profile_timestamps[i - 1].ptr[0] << 8) + + (profile_timestamps[i - 1].ptr[1] & 0xff); + a = find_aggregate_category(cat); + if(a == NULL) { + /* The list is full, skip this entry */ + printf("profile_aggregates_compute: list full\n"); + } else if(a->ptr == NULL) { + a->ptr = profile_timestamps[i - 1].ptr; + a->cycles = (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); + a->episodes = 1; + } else { + + a->cycles += (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); + + /* Make sure that we only update the episodes of each category + once per run. We keep track of all updated categories in the + "categories" array. If the category is already present in the + array, we do not update it. Otherwise, we insert the category + in the array and update the episodes counter of the + category. */ + + for(j = 0; j < categories_ptr; ++j) { + if(categories[j] == cat) { + break; + } + } + if(j == categories_ptr) { + categories[j] = cat; + categories_ptr++; + a->episodes++; + } + } + t = profile_timestamps[i].time; + } + + /* PROFILE_TIMESTAMP(str);*/ + + /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", + profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, + aggregates_list_ptr, profile_timestamp_time);*/ + + + /* print_aggregates();*/ +} +/*---------------------------------------------------------------------------*/ +void +profile_aggregates_compute(void) +{ +#if DETAILED_AGGREGATES + detailed_profile_aggregates_compute(); +#else + category_profile_aggregates_compute(); +#endif +} +/*---------------------------------------------------------------------------*/ diff --git a/profile.c b/profile.c new file mode 100644 index 000000000..df97ef09d --- /dev/null +++ b/profile.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: profile.c,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of the Contiki profiling system + * \author + * Adam Dunkels + */ + +#include "sys/profile.h" + +#include /* For NULL */ + +unsigned int profile_timestamp_ptr; +struct profile_timestamp profile_timestamps[PROFILE_LIST_LENGTH]; +rtimer_clock_t profile_timestamp_time; + +int profile_invalid_episode_overflow, profile_invalid_episode_toolong; + +int profile_max_queuelen = 0; + +static rtimer_clock_t episode_start_time; + +/* The number of fine grained ticks per coarse grained ticks. We + currently (MSP430) have 2457600 ticks per second for the fine + grained timer, and 32678 / 8 ticks per second for the coarse. */ +#define FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8)) + +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +profile_timediff(const char *ptr1, const char *ptr2) +{ + int i; + int t1, t2; + int timestamp_ptr = PROFILE_TIMESTAMP_PTR; + + /* printf("profile_timestamp_ptr %d max %d\n", profile_timestamp_ptr, profile_max_queuelen);*/ + + t1 = t2 = PROFILE_LIST_LENGTH; + + for(i = timestamp_ptr - 1; i >= 0; --i) { + /* printf("Checking 1 %s %u == %s i %d\n", + profile_timestamps[i].ptr, + profile_timestamps[i].time, + ptr1, i);*/ + if(profile_timestamps[i].ptr == ptr1) { + t1 = i; + break; + } + } + + for(i = i - 1; i >= 0; --i) { + /* printf("Checking 2 %s %u == %s i %d\n", + profile_timestamps[i].ptr, + profile_timestamps[i].time, + ptr1, i);*/ + if(profile_timestamps[i].ptr == ptr2) { + t2 = i; + break; + } + } + /* printf("t1 %d t2 %d\n", t1, t2);*/ + if(t1 != PROFILE_LIST_LENGTH && t2 != PROFILE_LIST_LENGTH) { + return profile_timestamps[t1].time - profile_timestamps[t2].time; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +profile_clear_timestamps(void) +{ + /* int i; + for(i = 0; i < PROFILE_LIST_LENGTH; ++i) { + profile_timestamps[i].str = "NULL"; + profile_timestamps[i].time = 0; + }*/ + profile_timestamp_ptr = 0; +} +/*---------------------------------------------------------------------------*/ +void +profile_init(void) +{ + profile_clear_timestamps(); + + /* Measure the time for taking a timestamp. */ + PROFILE_TIMESTAMP(NULL); + PROFILE_TIMESTAMP(NULL); + profile_timestamp_time = profile_timestamps[1].time - profile_timestamps[0].time; + + profile_clear_timestamps(); +} +/*---------------------------------------------------------------------------*/ +void +profile_episode_start(void) +{ + profile_timestamp_ptr = 0; + + episode_start_time = clock_counter(); + + profile_timestamps[PROFILE_LIST_LENGTH - 1].ptr = NULL; +} +/*---------------------------------------------------------------------------*/ +void +profile_episode_end(void) +{ + rtimer_clock_t episode_end_time = clock_counter(); + + PROFILE_TIMESTAMP("profile_episode_end"); + +/* printf("profile_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */ + if(profile_timestamps[PROFILE_LIST_LENGTH - 1].ptr != NULL) { + /* Invalid episode because of list overflow. */ + profile_invalid_episode_overflow++; + profile_max_queuelen = PROFILE_LIST_LENGTH; + } else if(episode_end_time - episode_start_time > 65536/FINE_TICKS_PER_COARSE_TICK) { + /* Invalid episode because of timer overflow. */ + profile_invalid_episode_toolong++; + } else { + /* Compute aggregates. */ + if(PROFILE_TIMESTAMP_PTR > profile_max_queuelen) { + profile_max_queuelen = PROFILE_TIMESTAMP_PTR; + } + profile_aggregates_compute(); + /* printf("Episode length %d\n", profile_timestamp_ptr);*/ + } + +/* profile_aggregates_print(); */ +/* profile_print_stats(); */ +} +/*---------------------------------------------------------------------------*/ +void +profile_print_stats(void) +{ + printf("Memory for profiling: %d * %d = %d\n", + sizeof(struct profile_timestamp), profile_max_queuelen, + sizeof(struct profile_timestamp) * profile_max_queuelen); + printf("Invalid episodes overflow %d time %d\n", + profile_invalid_episode_overflow, + profile_invalid_episode_toolong); +} +/*---------------------------------------------------------------------------*/ diff --git a/profile.h b/profile.h new file mode 100644 index 000000000..d8f70b378 --- /dev/null +++ b/profile.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: profile.h,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the Contiki profiling system + * \author + * Adam Dunkels + */ + +#ifndef __PROFILE_H__ +#define __PROFILE_H__ + +#include "sys/rtimer.h" + +#ifdef EXPERIMENT_SETUP +#include "experiment-setup.h" +#endif + +#include "contiki-conf.h" + +#ifdef PROFILE_CONF_LIST_LENGTH +#define PROFILE_LIST_LENGTH PROFILE_CONF_LIST_LENGTH +#else +#define PROFILE_LIST_LENGTH 128 +#endif + +struct profile_timestamp { + const unsigned char *ptr; + rtimer_clock_t time; +}; + +extern struct profile_timestamp profile_timestamps[PROFILE_LIST_LENGTH]; +extern unsigned int profile_timestamp_ptr; +extern rtimer_clock_t profile_timestamp_time; + +#define PROFILE_TIMESTAMP_PTR (profile_timestamp_ptr / sizeof(struct profile_timestamp)) + +#if PROFILE_CONF_ON +#define PROFILE_TIMESTAMP(str) \ + do { \ + profile_timestamps[profile_timestamp_ptr / sizeof(struct profile_timestamp)].ptr = str; \ + profile_timestamps[profile_timestamp_ptr / sizeof(struct profile_timestamp)].time = RTIMER_NOW(); \ + profile_timestamp_ptr = (profile_timestamp_ptr + sizeof(struct profile_timestamp)) % (PROFILE_LIST_LENGTH * sizeof(struct profile_timestamp)); \ + } while(0) +#define PROFILE_RESUME(num) PROFILE_TIMESTAMP(profile_timestamps[num].ptr) + +#define PROFILE_COND_TIMESTAMP(cond, ptr) do { if(cond) {PROFILE_TIMESTAMP(ptr);} } while(0) +#define PROFILE_COND_RESUME(cond, num) PROFILE_COND_TIMESTAMP(cond, profile_timestamps[num].ptr) +#else /* PROFILE_CONF_ON */ +#define PROFILE_TIMESTAMP(id) +#define PROFILE_RESUME(num) +#define PROFILE_COND_TIMESTAMP(cond, id) +#define PROFILE_COND_RESUME(cond, num) +#endif /* PROFILE_CONF_ON */ + +rtimer_clock_t profile_timediff(const char *ptr1, const char *ptr2); + +#define PROFILE_GETPTR() (PROFILE_TIMESTAMP_PTR) + +void profile_clear_timestamps(void); +void profile_init(void); + +void profile_episode_start(void); +void profile_episode_end(void); + +void profile_aggregates_print(void); +void profile_aggregates_compute(void); + +void profile_print_stats(void); + + +enum { + PROFILE_TYPE_STACK, + PROFILE_TYPE_HW, + PROFILE_TYPE_RADIO, + PROFILE_TYPE_SYSTEM, + PROFILE_TYPE_APP, +}; + +#endif /* __PROFILE_H__ */ + +/* profile_timestamp_ptr code: + + 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 + 32: 0e 4f mov r15, r14 ; + 34: 0e 5e rla r14 ; + 36: 0e 5e rla r14 ; + 38: 3e 50 00 00 add #0, r14 ;#0x0000 + 3c: be 40 00 00 mov #0, 0(r14) ;#0x0000 + 40: 00 00 + 42: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 + 46: 02 00 + 48: 1f 53 inc r15 ; + 4a: 3f f0 3f 00 and #63, r15 ;#0x003f + 4e: 82 4f 00 00 mov r15, &0x0000 ; + + msp430-specific profile_timetstamp_2ptr code: + + 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 + 32: 0e 4f mov r15, r14 ; + 34: 3e 50 00 00 add #0, r14 ;#0x0000 + 38: be 40 00 00 mov #0, 0(r14) ;#0x0000 + 3c: 00 00 + 3e: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 + 42: 02 00 + 44: 2f 53 incd r15 ; + 46: 3f f0 7f 00 and #127, r15 ;#0x007f + 4a: 82 4f 00 00 mov r15, &0x0000 ; + + generic timestamp_2ptr code: + + 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 + 32: 0e 4f mov r15, r14 ; + 34: 1e c3 bic #1, r14 ;r3 As==01 + 36: 0e 5e rla r14 ; + 38: 3e 50 00 00 add #0, r14 ;#0x0000 + 3c: be 40 00 00 mov #0, 0(r14) ;#0x0000 + 40: 00 00 + 42: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 + 46: 02 00 + 48: 2f 53 incd r15 ; + 4a: 3f f0 7f 00 and #127, r15 ;#0x007f + 4e: 82 4f 00 00 mov r15, &0x0000 ; + +*/ From cf37e1307717281c05af075edce0a743abddd73c Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 17 Nov 2007 10:12:19 +0000 Subject: [PATCH 040/146] Fixed compiler warnings --- profile-aggregates.c | 6 +++++- profile.c | 13 +++++++++++-- profile.h | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/profile-aggregates.c b/profile-aggregates.c index 1ad3e3a3b..cc75b4cbb 100644 --- a/profile-aggregates.c +++ b/profile-aggregates.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile-aggregates.c,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + * $Id: profile-aggregates.c,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ */ /** @@ -87,6 +87,7 @@ find_aggregate_category(const uint16_t cat) return &aggregates[aggregates_list_ptr++]; } /*---------------------------------------------------------------------------*/ +#if DETAILED_AGGREGATES static struct aggregate * find_aggregate(const unsigned char *ptr) { @@ -102,6 +103,7 @@ find_aggregate(const unsigned char *ptr) return &aggregates[aggregates_list_ptr++]; } +#endif /* DETAILED_AGGREGATES */ /*---------------------------------------------------------------------------*/ void profile_aggregates_print(void) @@ -130,6 +132,7 @@ profile_aggregates_print(void) sizeof(struct aggregate) * aggregates_list_ptr); } /*---------------------------------------------------------------------------*/ +#if DETAILED_AGGREGATES static void detailed_profile_aggregates_compute(void) { @@ -167,6 +170,7 @@ detailed_profile_aggregates_compute(void) /* print_aggregates();*/ } +#endif /* DETAILED_AGGREGATES */ /*---------------------------------------------------------------------------*/ static void category_profile_aggregates_compute(void) diff --git a/profile.c b/profile.c index df97ef09d..ec2dbee05 100644 --- a/profile.c +++ b/profile.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.c,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + * $Id: profile.c,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ */ /** @@ -57,6 +57,12 @@ static rtimer_clock_t episode_start_time; grained timer, and 32678 / 8 ticks per second for the coarse. */ #define FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8)) +/* XXX hack: we use a function called clock_counter() that is not part + of the clock API and currently is only implemented for the + MSP430. We therefore declare this function here instead of in + dev/clock.h. */ +rtimer_clock_t clock_counter(void); + /*---------------------------------------------------------------------------*/ rtimer_clock_t profile_timediff(const char *ptr1, const char *ptr2) @@ -64,7 +70,7 @@ profile_timediff(const char *ptr1, const char *ptr2) int i; int t1, t2; int timestamp_ptr = PROFILE_TIMESTAMP_PTR; - + /* printf("profile_timestamp_ptr %d max %d\n", profile_timestamp_ptr, profile_max_queuelen);*/ t1 = t2 = PROFILE_LIST_LENGTH; @@ -160,6 +166,8 @@ profile_episode_end(void) /* profile_print_stats(); */ } /*---------------------------------------------------------------------------*/ +#if 0 +#include void profile_print_stats(void) { @@ -170,4 +178,5 @@ profile_print_stats(void) profile_invalid_episode_overflow, profile_invalid_episode_toolong); } +#endif /* 0 */ /*---------------------------------------------------------------------------*/ diff --git a/profile.h b/profile.h index d8f70b378..28d5c13ec 100644 --- a/profile.h +++ b/profile.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.h,v 1.1 2007/10/23 20:39:07 adamdunkels Exp $ + * $Id: profile.h,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ */ /** @@ -56,7 +56,7 @@ #endif struct profile_timestamp { - const unsigned char *ptr; + const char *ptr; rtimer_clock_t time; }; From 6bd5b7229cdcfcb789c2166f074f1f822faf19af Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 17 Nov 2007 18:01:00 +0000 Subject: [PATCH 041/146] Fixed compiler warnings to make code compile with gcc's -pedantic switch --- profile-aggregates.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/profile-aggregates.c b/profile-aggregates.c index cc75b4cbb..2d34a9f15 100644 --- a/profile-aggregates.c +++ b/profile-aggregates.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile-aggregates.c,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ + * $Id: profile-aggregates.c,v 1.3 2007/11/17 18:07:40 adamdunkels Exp $ */ /** @@ -44,7 +44,7 @@ #include struct aggregate { - const unsigned char *ptr; + const char *ptr; unsigned short episodes; unsigned long cycles; }; From b723692ef98e1a6a1bb8117876dd6935808cc238 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 17 Nov 2007 18:07:13 +0000 Subject: [PATCH 042/146] Made definition of PROCESS() macro nicer by removing unused PROCESS_LOAD() and PROCESS_NOLOAD() --- process.h | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/process.h b/process.h index 15da37d7b..d0c97ef70 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.10 2007/08/30 14:39:17 matsutsuka Exp $ + * @(#)$Id: process.h,v 1.11 2007/11/17 18:07:13 adamdunkels Exp $ */ /** @@ -276,13 +276,6 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) -#if PROCESS_LOADABLE -#define PROCESS_LOAD(name) const struct process *process_load = &name -#else /* PROCESS_LOADABLE */ -#define PROCESS_LOAD(name) extern int _dummy -#endif /* PROCESS_LOADABLE */ -CLIF extern const struct process *process_load; - /** * Declare the name of a process. * @@ -293,10 +286,6 @@ CLIF extern const struct process *process_load; */ #define PROCESS_NAME(name) extern struct process name -#define PROCESS_NOLOAD(name, strname) \ - PROCESS_THREAD(name, ev, data); \ - struct process name = { NULL, strname, \ - process_thread_##name } /** * Declare a process. * @@ -309,9 +298,11 @@ CLIF extern const struct process *process_load; * * \hideinitializer */ -#define PROCESS(name, strname) \ - PROCESS_NOLOAD(name, strname); \ - PROCESS_LOAD(name) +#define PROCESS(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, strname, \ + process_thread_##name } + /** @} */ From 05a271f3a3ff1cb953a8d9f3b096b3558637b921 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 17 Nov 2007 22:11:19 +0000 Subject: [PATCH 043/146] reverted the PROCESS_LOAD() commit - the PROCESS_LOAD() code is used by ports such as the win32 and 6502 ports --- process.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/process.h b/process.h index d0c97ef70..e14ad3a0e 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.11 2007/11/17 18:07:13 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.12 2007/11/17 22:11:19 adamdunkels Exp $ */ /** @@ -276,6 +276,13 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) +#if PROCESS_LOADABLE +#define PROCESS_LOAD(name) const struct process *process_load = &name +#else /* PROCESS_LOADABLE */ +#define PROCESS_LOAD(name) extern int _dummy +#endif /* PROCESS_LOADABLE */ +CLIF extern const struct process *process_load; + /** * Declare the name of a process. * @@ -286,6 +293,10 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ */ #define PROCESS_NAME(name) extern struct process name +#define PROCESS_NOLOAD(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, strname, \ + process_thread_##name } /** * Declare a process. * @@ -298,11 +309,9 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ * * \hideinitializer */ -#define PROCESS(name, strname) \ - PROCESS_THREAD(name, ev, data); \ - struct process name = { NULL, strname, \ - process_thread_##name } - +#define PROCESS(name, strname) \ + PROCESS_NOLOAD(name, strname); \ + PROCESS_LOAD(name) /** @} */ From f6b26c8c338d16088de0e7add34c83c846799b98 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 18 Nov 2007 01:36:59 +0000 Subject: [PATCH 044/146] Removed compiler warnings. --- cc.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/cc.h b/cc.h index 47f5f77ee..c35bdad3f 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.3 2007/09/01 00:49:41 matsutsuka Exp $ + * $Id: cc.h,v 1.4 2007/11/18 01:37:48 oliverschmidt Exp $ * */ #ifndef __CC_H__ @@ -110,17 +110,6 @@ #define CC_ASSIGN_AGGREGATE(dest, src) *dest = *src #endif /* CC_CONF_ASSIGN_AGGREGATE */ -/** - * Configure if the C compiler supports the increment of pointer. - */ -#ifdef CC_CONF_INC_CAST_POINTER -#define CC_INC_CAST_POINTER(type, data) \ - CC_CONF_INC_CAST_POINTER(type, data) -#else /* CC_CONF_INC_CAST_POINTER */ -#define CC_INC_CAST_POINTER(type, data) \ - ++((type) data) -#endif /* CC_CONF_INC_CAST_POINTER */ - #if CC_CONF_NO_VA_ARGS #define CC_NO_VA_ARGS CC_CONF_VA_ARGS #endif From 13b045b3fe75beacc9900de075a28e98d4ade875 Mon Sep 17 00:00:00 2001 From: ksb Date: Sun, 18 Nov 2007 12:27:44 +0000 Subject: [PATCH 045/146] slip.c: char is signed but uip_buf is unsigned spi.h: casted unused values to void autostart.c: autostart.h: The array itself should be const but the processes pointed to should not. profile-aggregates.c: sizeof returns unsigned long on my platform --- autostart.c | 6 +++--- autostart.h | 10 +++++----- profile-aggregates.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/autostart.c b/autostart.c index 1514b0fe3..8bd2ccfa4 100644 --- a/autostart.c +++ b/autostart.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.c,v 1.2 2007/03/25 17:16:57 adamdunkels Exp $ + * $Id: autostart.c,v 1.3 2007/11/18 12:27:45 ksb Exp $ */ /** @@ -50,7 +50,7 @@ /*---------------------------------------------------------------------------*/ void -autostart_start(struct process *processes[]) +autostart_start(struct process * const processes[]) { int i; @@ -61,7 +61,7 @@ autostart_start(struct process *processes[]) } /*---------------------------------------------------------------------------*/ void -autostart_exit(struct process *processes[]) +autostart_exit(struct process * const processes[]) { int i; diff --git a/autostart.h b/autostart.h index 7d5a64842..ae8c57a3f 100644 --- a/autostart.h +++ b/autostart.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.h,v 1.2 2007/08/30 14:39:17 matsutsuka Exp $ + * $Id: autostart.h,v 1.3 2007/11/18 12:27:45 ksb Exp $ */ /** @@ -46,7 +46,7 @@ #if ! CC_NO_VA_ARGS #if AUTOSTART_ENABLE #define AUTOSTART_PROCESSES(...) \ -const struct process *autostart_processes[] = {__VA_ARGS__, NULL} +struct process * const autostart_processes[] = {__VA_ARGS__, NULL} #else /* AUTOSTART_ENABLE */ #define AUTOSTART_PROCESSES(...) \ extern int _dummy @@ -55,9 +55,9 @@ extern int _dummy #error "C compiler must support __VA_ARGS__ macro" #endif -extern const struct process *autostart_processes[]; +extern struct process * const autostart_processes[]; -void autostart_start(struct process *processes[]); -void autostart_exit(struct process *processes[]); +void autostart_start(struct process * const processes[]); +void autostart_exit(struct process * const processes[]); #endif /* __AUTOSTART_H__ */ diff --git a/profile-aggregates.c b/profile-aggregates.c index 2d34a9f15..4cd3bc232 100644 --- a/profile-aggregates.c +++ b/profile-aggregates.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile-aggregates.c,v 1.3 2007/11/17 18:07:40 adamdunkels Exp $ + * $Id: profile-aggregates.c,v 1.4 2007/11/18 12:27:45 ksb Exp $ */ /** @@ -128,8 +128,8 @@ profile_aggregates_print(void) #endif printf("Memory for aggregates: %d * %d = %d\n", - sizeof(struct aggregate), aggregates_list_ptr, - sizeof(struct aggregate) * aggregates_list_ptr); + (int)sizeof(struct aggregate), aggregates_list_ptr, + (int)sizeof(struct aggregate) * aggregates_list_ptr); } /*---------------------------------------------------------------------------*/ #if DETAILED_AGGREGATES From 6c9af3e1adad820c8b2cd9351d3aaff580ba6497 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 18 Nov 2007 19:16:49 +0000 Subject: [PATCH 046/146] Including stddef.h for NULL seems to be somewhat more portable than stdlib.h. --- profile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/profile.c b/profile.c index ec2dbee05..d6e7d7988 100644 --- a/profile.c +++ b/profile.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.c,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ + * $Id: profile.c,v 1.3 2007/11/18 19:16:49 oliverschmidt Exp $ */ /** @@ -40,7 +40,7 @@ #include "sys/profile.h" -#include /* For NULL */ +#include /* For NULL */ unsigned int profile_timestamp_ptr; struct profile_timestamp profile_timestamps[PROFILE_LIST_LENGTH]; From ad25e7bc4c4dfb0e3fe825592fd7fe9eb14764b5 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 16 Dec 2007 14:29:56 +0000 Subject: [PATCH 047/146] A simple implicit network time synchronization mechanism --- timesynch.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++ timesynch.h | 144 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 timesynch.c create mode 100644 timesynch.h diff --git a/timesynch.c b/timesynch.c new file mode 100644 index 000000000..6f9d190ba --- /dev/null +++ b/timesynch.c @@ -0,0 +1,176 @@ +/** + * \addtogroup timesynch + * @{ + */ + + +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timesynch.c,v 1.1 2007/12/16 14:29:56 adamdunkels Exp $ + */ + +/** + * \file + * A simple time synchronization mechanism + * \author + * Adam Dunkels + */ + +#include "sys/timesynch.h" +#include "net/rime/rimebuf.h" +#include "net/rime.h" +#include "dev/simple-cc2420.h" + +static const struct mac_driver timesynch_driver; +static const struct mac_driver *mac; +static void (* receiver_callback)(const struct mac_driver *); + +#include + +static int authority_level; +static rtimer_clock_t offset; + +/*---------------------------------------------------------------------------*/ +int +timesynch_authority_level(void) +{ + return authority_level; +} +/*---------------------------------------------------------------------------*/ +void +timesynch_set_authority_level(int level) +{ + authority_level = level; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +timesynch_time(void) +{ + return rtimer_arch_now() + offset; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +timesynch_time_to_rtimer(rtimer_clock_t synched_time) +{ + return synched_time - offset; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +timesynch_offset(void) +{ + return offset; +} +/*---------------------------------------------------------------------------*/ +static int +send(void) +{ + return mac->send(); +} +/*---------------------------------------------------------------------------*/ +static void +input(const struct mac_driver *d) +{ + if(receiver_callback) { + receiver_callback(×ynch_driver); + } +} +/*---------------------------------------------------------------------------*/ +static void +adjust_offset(rtimer_clock_t authoritative_time, rtimer_clock_t local_time) +{ + offset = offset + authoritative_time - local_time; +} +/*---------------------------------------------------------------------------*/ +static int +read(void) +{ + int len; + + len = mac->read(); + + /* We check the authority level of the sender of the incoming + packet. If the sending node has a lower authority level than we + have, we synchronize to the time of the sending node and set our + own authority level to be one more than the sending node. */ + if(simple_cc2420_authority_level_of_sender < authority_level) { + adjust_offset(simple_cc2420_time_of_departure + + simple_cc2420_time_for_transmission, + simple_cc2420_time_of_arrival); + if(simple_cc2420_authority_level_of_sender + 1 != authority_level) { + printf("New authority %d, previous %d\n", + simple_cc2420_authority_level_of_sender + 1, + authority_level); + authority_level = simple_cc2420_authority_level_of_sender + 1; + } + + /* XXX the authority level should be increased over time except + for the sink node. */ + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static void +set_receive_function(void (* recv)(const struct mac_driver *)) +{ + receiver_callback = recv; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + return mac->on(); +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + return mac->off(); +} +/*---------------------------------------------------------------------------*/ +static const struct mac_driver timesynch_driver = { + send, + read, + set_receive_function, + on, + off, +}; +/*---------------------------------------------------------------------------*/ +const struct mac_driver * +timesynch_init(const struct mac_driver *d) +{ + mac = d; + mac->set_receive_function(input); + mac->on(); + return ×ynch_driver; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/timesynch.h b/timesynch.h new file mode 100644 index 000000000..e975b8247 --- /dev/null +++ b/timesynch.h @@ -0,0 +1,144 @@ +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup timesynch Implicit network time synchronization + * @{ + * + * This crude and simple network time synchronization module + * synchronizes clocks of all nodes in a network. The time + * synchronization is implicit in that no explicit time + * synchronization messages are sent: the module relies on the + * underlying network device driver to timestamp all radio messages, + * both outgoing and incoming. The code currently only works on the + * Tmote Sky platform and the simple-cc2420 driver. + * + * Every node has an authority level, which is included in every + * outgoing packet. If a message is received from a node with higher + * authority (lower authority number), the node adjusts its clock + * towards the clock of the sending node. + * + * The timesynch module is implemented as a meta-MAC protocol, so that + * the module is invoked for every incoming packet. + * + */ + +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timesynch.h,v 1.1 2007/12/16 14:29:56 adamdunkels Exp $ + */ + +/** + * \file + * Header file for a simple time synchronization mechanism + * \author + * Adam Dunkels + */ + +#ifndef __TIMESYNCH_H__ +#define __TIMESYNCH_H__ + +#include "net/mac/mac.h" +#include "sys/rtimer.h" + +/** + * \brief Initialize the timesynch module; should be called during the MAC initialization procedure + * \param r The underlying MAC driver + * \return A pointer to the timesynch module's meta MAC driver + * + * This function initializes the timesynch module. The + * function should be called as part of the MAC + * initialization procedure. + * + */ +const struct mac_driver *timesynch_init(const struct mac_driver *r); + +/** + * \brief Get the current time-synchronized time + * \return The current time-synchronized time + * + * This function returns the current time-synchronized + * time. + * + */ +rtimer_clock_t timesynch_time(void); + +/** + * \brief Get the current time-synchronized rtimer time, suitable for use with the rtimer module + * \return The current time-synchronized rtimer time + * + * This function returns the (local) rtimer-equivalent + * time corresponding to the current time-synchronized + * (global) time. The rtimer-equivalent time is used for + * setting rtimer timers that are synchronized to other + * nodes in the network. + * + */ +rtimer_clock_t timesynch_time_to_rtimer(rtimer_clock_t synched_time); + +/** + * \brief Get the current time-synchronized offset from the rtimer clock, which is used mainly for debugging + * \return The current time-synchronized offset from the rtimer clock + * + * This function returns the current time-synchronized + * offset from the rtimer arch clock. This is mainly + * useful for debugging the timesynch module. + * + */ +rtimer_clock_t timesynch_offset(void); + +/** + * \brief Get the current authority level of the time-synchronized time + * \return The current authority level of the time-synchronized time + * + * This function returns the current authority level of + * the time-synchronized time. A node with a lower + * authority level is defined to have a better notion of + * time than a node with a higher authority + * level. Authority level 0 is best and should be used by + * a sink node that has a connection to an outside, + * "true", clock source. + * + */ +int timesynch_authority_level(void); + +/** + * \brief Set the authority level of the current time + * \param level The authority level + */ +void timesynch_set_authority_level(int level); + +#endif /* __TIMESYNCH_H__ */ + +/** @} */ +/** @} */ From 71d58293ad224ebc64f6a008599631b38e7a50f1 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 16 Dec 2007 14:48:33 +0000 Subject: [PATCH 048/146] Removed debug output --- timesynch.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/timesynch.c b/timesynch.c index 6f9d190ba..13ca56a61 100644 --- a/timesynch.c +++ b/timesynch.c @@ -34,7 +34,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timesynch.c,v 1.1 2007/12/16 14:29:56 adamdunkels Exp $ + * $Id: timesynch.c,v 1.2 2007/12/16 14:48:33 adamdunkels Exp $ */ /** @@ -125,9 +125,6 @@ read(void) simple_cc2420_time_for_transmission, simple_cc2420_time_of_arrival); if(simple_cc2420_authority_level_of_sender + 1 != authority_level) { - printf("New authority %d, previous %d\n", - simple_cc2420_authority_level_of_sender + 1, - authority_level); authority_level = simple_cc2420_authority_level_of_sender + 1; } From 129dfbcdb687e4750fd9d45d9de7967c1f55c3c8 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 20 Dec 2007 20:30:55 +0000 Subject: [PATCH 049/146] Easily avoided double (meant to be a forward ?) definition of timesynch_driver. --- timesynch.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/timesynch.c b/timesynch.c index 13ca56a61..ed688ba9e 100644 --- a/timesynch.c +++ b/timesynch.c @@ -34,7 +34,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timesynch.c,v 1.2 2007/12/16 14:48:33 adamdunkels Exp $ + * $Id: timesynch.c,v 1.3 2007/12/20 20:30:55 oliverschmidt Exp $ */ /** @@ -49,7 +49,6 @@ #include "net/rime.h" #include "dev/simple-cc2420.h" -static const struct mac_driver timesynch_driver; static const struct mac_driver *mac; static void (* receiver_callback)(const struct mac_driver *); @@ -96,14 +95,6 @@ send(void) } /*---------------------------------------------------------------------------*/ static void -input(const struct mac_driver *d) -{ - if(receiver_callback) { - receiver_callback(×ynch_driver); - } -} -/*---------------------------------------------------------------------------*/ -static void adjust_offset(rtimer_clock_t authoritative_time, rtimer_clock_t local_time) { offset = offset + authoritative_time - local_time; @@ -161,6 +152,14 @@ static const struct mac_driver timesynch_driver = { off, }; /*---------------------------------------------------------------------------*/ +static void +input(const struct mac_driver *d) +{ + if(receiver_callback) { + receiver_callback(×ynch_driver); + } +} +/*---------------------------------------------------------------------------*/ const struct mac_driver * timesynch_init(const struct mac_driver *d) { From b8b866e310868d1c840df6eb1dd038ac82001ba3 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 23 Dec 2007 14:56:54 +0000 Subject: [PATCH 050/146] Avoid usage of POSIX function names even for static functions as some indirectly included system header might declare them. --- timesynch.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/timesynch.c b/timesynch.c index ed688ba9e..ecf8c33db 100644 --- a/timesynch.c +++ b/timesynch.c @@ -34,7 +34,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timesynch.c,v 1.3 2007/12/20 20:30:55 oliverschmidt Exp $ + * $Id: timesynch.c,v 1.4 2007/12/23 14:57:11 oliverschmidt Exp $ */ /** @@ -89,7 +89,7 @@ timesynch_offset(void) } /*---------------------------------------------------------------------------*/ static int -send(void) +send_packet(void) { return mac->send(); } @@ -101,7 +101,7 @@ adjust_offset(rtimer_clock_t authoritative_time, rtimer_clock_t local_time) } /*---------------------------------------------------------------------------*/ static int -read(void) +read_packet(void) { int len; @@ -145,15 +145,15 @@ off(void) } /*---------------------------------------------------------------------------*/ static const struct mac_driver timesynch_driver = { - send, - read, + send_packet, + read_packet, set_receive_function, on, off, }; /*---------------------------------------------------------------------------*/ static void -input(const struct mac_driver *d) +input_packet(const struct mac_driver *d) { if(receiver_callback) { receiver_callback(×ynch_driver); @@ -164,7 +164,7 @@ const struct mac_driver * timesynch_init(const struct mac_driver *d) { mac = d; - mac->set_receive_function(input); + mac->set_receive_function(input_packet); mac->on(); return ×ynch_driver; } From aaab8ef3a96eae8f9d9cdbabf4d019c7913e5b58 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 8 Jan 2008 07:54:16 +0000 Subject: [PATCH 051/146] The radio driver now takes care of adjusting for the transmission time --- timesynch.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/timesynch.c b/timesynch.c index ecf8c33db..adb808bd7 100644 --- a/timesynch.c +++ b/timesynch.c @@ -34,7 +34,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timesynch.c,v 1.4 2007/12/23 14:57:11 oliverschmidt Exp $ + * $Id: timesynch.c,v 1.5 2008/01/08 07:54:16 adamdunkels Exp $ */ /** @@ -107,25 +107,36 @@ read_packet(void) len = mac->read(); + if(len == 0) { + return 0; + } + /* We check the authority level of the sender of the incoming packet. If the sending node has a lower authority level than we have, we synchronize to the time of the sending node and set our own authority level to be one more than the sending node. */ if(simple_cc2420_authority_level_of_sender < authority_level) { - adjust_offset(simple_cc2420_time_of_departure + - simple_cc2420_time_for_transmission, + + adjust_offset(simple_cc2420_time_of_departure, simple_cc2420_time_of_arrival); if(simple_cc2420_authority_level_of_sender + 1 != authority_level) { authority_level = simple_cc2420_authority_level_of_sender + 1; } - /* XXX the authority level should be increased over time except - for the sink node. */ } return len; } /*---------------------------------------------------------------------------*/ +#if 0 +static void +periodic_authority_increase(void *ptr) +{ + /* XXX the authority level should be increased over time except + for the sink node (which has authority 0). */ +} +#endif +/*---------------------------------------------------------------------------*/ static void set_receive_function(void (* recv)(const struct mac_driver *)) { From 9fdd68154c93a31194c4c9e1593940c4ffee01f3 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 14 Jan 2008 09:22:22 +0000 Subject: [PATCH 052/146] Added a macro for concatenation of two strings, which may be macro expansions --- cc.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cc.h b/cc.h index c35bdad3f..1d1c8bdde 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.4 2007/11/18 01:37:48 oliverschmidt Exp $ + * $Id: cc.h,v 1.5 2008/01/14 09:22:22 adamdunkels Exp $ * */ #ifndef __CC_H__ @@ -117,4 +117,15 @@ #ifndef NULL #define NULL 0 #endif /* NULL */ + +#define CC_CONCAT2(s1, s2) s1##s2 +/** + * A C preprocessing macro for concatenating to + * strings. + * + * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow + * concatenation of two #defined macros. + */ +#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) + #endif /* __CC_H__ */ From 6496eeff71410db1a2fe5a228b79bd3856beaad9 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 17 Jan 2008 12:19:25 +0000 Subject: [PATCH 053/146] Factored out the time table keeping code from the profiling code and placed it in a separate 'timetable' module, that may be uesd on its own. --- profile.c | 221 +++++++++++++++++++++------------------- profile.h | 124 ++++++----------------- timetable-aggregate.c | 229 ++++++++++++++++++++++++++++++++++++++++++ timetable-aggregate.h | 91 +++++++++++++++++ timetable.c | 128 +++++++++++++++++++++++ timetable.h | 140 ++++++++++++++++++++++++++ 6 files changed, 734 insertions(+), 199 deletions(-) create mode 100644 timetable-aggregate.c create mode 100644 timetable-aggregate.h create mode 100644 timetable.c create mode 100644 timetable.h diff --git a/profile.c b/profile.c index d6e7d7988..9f16c0b31 100644 --- a/profile.c +++ b/profile.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.c,v 1.3 2007/11/18 19:16:49 oliverschmidt Exp $ + * $Id: profile.c,v 1.4 2008/01/17 12:19:26 adamdunkels Exp $ */ /** @@ -39,144 +39,159 @@ */ #include "sys/profile.h" +#include "sys/clock.h" -#include /* For NULL */ +#include + +/* XXX: the profiling code is under development and may not work at + present. */ -unsigned int profile_timestamp_ptr; -struct profile_timestamp profile_timestamps[PROFILE_LIST_LENGTH]; -rtimer_clock_t profile_timestamp_time; -int profile_invalid_episode_overflow, profile_invalid_episode_toolong; +TIMETABLE_NONSTATIC(profile_timetable); -int profile_max_queuelen = 0; +TIMETABLE_NONSTATIC(profile_begin_timetable); +TIMETABLE_NONSTATIC(profile_end_timetable); +TIMETABLE_AGGREGATE(profile_aggregate, PROFILE_AGGREGATE_SIZE); static rtimer_clock_t episode_start_time; +static unsigned int invalid_episode_overflow, invalid_episode_toolong, + max_queuelen; /* The number of fine grained ticks per coarse grained ticks. We currently (MSP430) have 2457600 ticks per second for the fine grained timer, and 32678 / 8 ticks per second for the coarse. */ -#define FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8)) +#define XXX_HACK_FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8)) -/* XXX hack: we use a function called clock_counter() that is not part - of the clock API and currently is only implemented for the - MSP430. We therefore declare this function here instead of in - dev/clock.h. */ -rtimer_clock_t clock_counter(void); - -/*---------------------------------------------------------------------------*/ -rtimer_clock_t -profile_timediff(const char *ptr1, const char *ptr2) -{ - int i; - int t1, t2; - int timestamp_ptr = PROFILE_TIMESTAMP_PTR; - - /* printf("profile_timestamp_ptr %d max %d\n", profile_timestamp_ptr, profile_max_queuelen);*/ - - t1 = t2 = PROFILE_LIST_LENGTH; - - for(i = timestamp_ptr - 1; i >= 0; --i) { - /* printf("Checking 1 %s %u == %s i %d\n", - profile_timestamps[i].ptr, - profile_timestamps[i].time, - ptr1, i);*/ - if(profile_timestamps[i].ptr == ptr1) { - t1 = i; - break; - } - } - - for(i = i - 1; i >= 0; --i) { - /* printf("Checking 2 %s %u == %s i %d\n", - profile_timestamps[i].ptr, - profile_timestamps[i].time, - ptr1, i);*/ - if(profile_timestamps[i].ptr == ptr2) { - t2 = i; - break; - } - } - /* printf("t1 %d t2 %d\n", t1, t2);*/ - if(t1 != PROFILE_LIST_LENGTH && t2 != PROFILE_LIST_LENGTH) { - return profile_timestamps[t1].time - profile_timestamps[t2].time; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -void -profile_clear_timestamps(void) -{ - /* int i; - for(i = 0; i < PROFILE_LIST_LENGTH; ++i) { - profile_timestamps[i].str = "NULL"; - profile_timestamps[i].time = 0; - }*/ - profile_timestamp_ptr = 0; -} /*---------------------------------------------------------------------------*/ void profile_init(void) { - profile_clear_timestamps(); - - /* Measure the time for taking a timestamp. */ - PROFILE_TIMESTAMP(NULL); - PROFILE_TIMESTAMP(NULL); - profile_timestamp_time = profile_timestamps[1].time - profile_timestamps[0].time; - - profile_clear_timestamps(); + timetable_init(); + timetable_clear(&profile_begin_timetable); + timetable_clear(&profile_end_timetable); } /*---------------------------------------------------------------------------*/ void profile_episode_start(void) { - profile_timestamp_ptr = 0; + struct timetable_timestamp *e; + timetable_clear(&profile_begin_timetable); + timetable_clear(&profile_end_timetable); + episode_start_time = clock_time(); - episode_start_time = clock_counter(); - - profile_timestamps[PROFILE_LIST_LENGTH - 1].ptr = NULL; + e = timetable_entry(&profile_begin_timetable, + PROFILE_TIMETABLE_SIZE - 1); + if(e != NULL) { + e->id = NULL; + } + e = timetable_entry(&profile_end_timetable, + PROFILE_TIMETABLE_SIZE - 1); + if(e != NULL) { + e->id = NULL; + } } /*---------------------------------------------------------------------------*/ void profile_episode_end(void) { - rtimer_clock_t episode_end_time = clock_counter(); + struct timetable_timestamp *e; + rtimer_clock_t episode_end_time = clock_time(); - PROFILE_TIMESTAMP("profile_episode_end"); - -/* printf("profile_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */ - if(profile_timestamps[PROFILE_LIST_LENGTH - 1].ptr != NULL) { +/* printf("timetable_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */ + e = timetable_entry(&profile_begin_timetable, + PROFILE_TIMETABLE_SIZE - 1); + if(e != NULL && e->id != NULL) { /* Invalid episode because of list overflow. */ - profile_invalid_episode_overflow++; - profile_max_queuelen = PROFILE_LIST_LENGTH; - } else if(episode_end_time - episode_start_time > 65536/FINE_TICKS_PER_COARSE_TICK) { + invalid_episode_overflow++; + max_queuelen = PROFILE_TIMETABLE_SIZE; + } else if(episode_end_time - episode_start_time > + 65536/XXX_HACK_FINE_TICKS_PER_COARSE_TICK) { /* Invalid episode because of timer overflow. */ - profile_invalid_episode_toolong++; + invalid_episode_toolong++; } else { /* Compute aggregates. */ - if(PROFILE_TIMESTAMP_PTR > profile_max_queuelen) { - profile_max_queuelen = PROFILE_TIMESTAMP_PTR; + if(timetable_ptr(&profile_begin_timetable) > max_queuelen) { + max_queuelen = timetable_ptr(&profile_begin_timetable); } - profile_aggregates_compute(); - /* printf("Episode length %d\n", profile_timestamp_ptr);*/ + /* timetable_aggregates_compute();*/ } - -/* profile_aggregates_print(); */ -/* profile_print_stats(); */ } /*---------------------------------------------------------------------------*/ -#if 0 -#include +/* + * + * Find a specific aggregate ID in the list of aggregates. + * + */ +static struct timetable_aggregate_entry * +find_aggregate(struct timetable_aggregate *a, + const char *id) +{ + int i; + for(i = 0; i < a->ptr; ++i) { + if(a->entries[i].id == id) { + return &a->entries[i]; + } + } + if(i == a->size) { + return NULL; + } + a->entries[a->ptr].id = NULL; + return &a->entries[a->ptr++]; +} +/*---------------------------------------------------------------------------*/ void -profile_print_stats(void) +profile_aggregate_print_detailed(void) { - printf("Memory for profiling: %d * %d = %d\n", - sizeof(struct profile_timestamp), profile_max_queuelen, - sizeof(struct profile_timestamp) * profile_max_queuelen); - printf("Invalid episodes overflow %d time %d\n", - profile_invalid_episode_overflow, - profile_invalid_episode_toolong); + int i; + struct timetable_aggregate *a = &profile_aggregate; + + /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/ + for(i = 0; i < a->ptr; ++i) { + printf("-- %s: %lu / %u = %lu\n", a->entries[i].id, + a->entries[i].time, + a->entries[i].episodes, + a->entries[i].time / a->entries[i].episodes); + } + + printf("Memory for entries: %d * %d = %d\n", + (int)sizeof(struct timetable_aggregate), a->ptr, + (int)sizeof(struct timetable_aggregate) * a->ptr); +} +/*---------------------------------------------------------------------------*/ +void +profile_aggregate_compute_detailed(void) +{ + int i; + int last; + rtimer_clock_t t; + struct timetable_aggregate *a = &profile_aggregate; + struct timetable *timetable = &profile_timetable; + struct timetable_aggregate_entry *entry; + + last = timetable_ptr(&profile_begin_timetable); + t = profile_begin_timetable.timestamps[0].time; + for(i = 0; i < last; ++i) { + + entry = find_aggregate(a, profile_begin_timetable.timestamps[i].id); + if(entry == NULL) { + /* The list is full, skip this entry */ + /* printf("detailed_timetable_aggregate_compute: list full\n");*/ + } else if(entry->id == NULL) { + /* The id was found in the list, so we add it. */ + entry->id = timetable->timestamps[i - 1].id; + entry->time = (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + entry->episodes = 1; + /* printf("New entry %s %lu\n", entry->id, entry->time);*/ + } else { + entry->time += (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + entry->episodes++; + } + t = timetable->timestamps[i].time; + /* printf("a ptr %d\n", a->ptr);*/ + + } + } -#endif /* 0 */ /*---------------------------------------------------------------------------*/ diff --git a/profile.h b/profile.h index 28d5c13ec..bd9c3226e 100644 --- a/profile.h +++ b/profile.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.h,v 1.2 2007/11/17 10:14:19 adamdunkels Exp $ + * $Id: profile.h,v 1.3 2008/01/17 12:19:26 adamdunkels Exp $ */ /** @@ -41,116 +41,48 @@ #ifndef __PROFILE_H__ #define __PROFILE_H__ -#include "sys/rtimer.h" +/* XXX: the profiling code is under development and may not work at + present. */ -#ifdef EXPERIMENT_SETUP -#include "experiment-setup.h" -#endif - -#include "contiki-conf.h" +#define TIMETABLE_WITH_TYPE 1 +#include "sys/timetable.h" -#ifdef PROFILE_CONF_LIST_LENGTH -#define PROFILE_LIST_LENGTH PROFILE_CONF_LIST_LENGTH +#ifdef PROFILE_CONF_TIMETABLE_SIZE +#define PROFILE_TIMETABLE_SIZE PROFILE_CONF_TIMETABLE_SIZE #else -#define PROFILE_LIST_LENGTH 128 +#define PROFILE_TIMETABLE_SIZE 128 #endif -struct profile_timestamp { - const char *ptr; - rtimer_clock_t time; -}; - -extern struct profile_timestamp profile_timestamps[PROFILE_LIST_LENGTH]; -extern unsigned int profile_timestamp_ptr; -extern rtimer_clock_t profile_timestamp_time; - -#define PROFILE_TIMESTAMP_PTR (profile_timestamp_ptr / sizeof(struct profile_timestamp)) +#ifdef PROFILE_CONF_AGGREGATE_SIZE +#define PROFILE_AGGREGATE_SIZE PROFILE_CONF_AGGREGATE_SIZE +#else +#define PROFILE_AGGREGATE_SIZE 128 +#endif -#if PROFILE_CONF_ON -#define PROFILE_TIMESTAMP(str) \ - do { \ - profile_timestamps[profile_timestamp_ptr / sizeof(struct profile_timestamp)].ptr = str; \ - profile_timestamps[profile_timestamp_ptr / sizeof(struct profile_timestamp)].time = RTIMER_NOW(); \ - profile_timestamp_ptr = (profile_timestamp_ptr + sizeof(struct profile_timestamp)) % (PROFILE_LIST_LENGTH * sizeof(struct profile_timestamp)); \ - } while(0) -#define PROFILE_RESUME(num) PROFILE_TIMESTAMP(profile_timestamps[num].ptr) +#define PROFILE_BEGIN(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 1) +#define PROFILE_END(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 2) -#define PROFILE_COND_TIMESTAMP(cond, ptr) do { if(cond) {PROFILE_TIMESTAMP(ptr);} } while(0) -#define PROFILE_COND_RESUME(cond, num) PROFILE_COND_TIMESTAMP(cond, profile_timestamps[num].ptr) -#else /* PROFILE_CONF_ON */ -#define PROFILE_TIMESTAMP(id) -#define PROFILE_RESUME(num) -#define PROFILE_COND_TIMESTAMP(cond, id) -#define PROFILE_COND_RESUME(cond, num) -#endif /* PROFILE_CONF_ON */ +/*#define PROFILE_COND_BEGIN(cond, id) TIMETABLE_COND_TIMESTAMP(profile_begin_timetable, \ + cond, id) +#define PROFILE_COND_END(cond, id) TIMETABLE_COND_TIMESTAMP(profile_end_timetable, \ + cond, id) +*/ -rtimer_clock_t profile_timediff(const char *ptr1, const char *ptr2); +#define profile_begin_timetable_size PROFILE_TIMETABLE_SIZE +TIMETABLE_DECLARE(profile_begin_timetable); +#define profile_end_timetable_size PROFILE_TIMETABLE_SIZE +TIMETABLE_DECLARE(profile_end_timetable); -#define PROFILE_GETPTR() (PROFILE_TIMESTAMP_PTR) +#define profile_timetable_size PROFILE_TIMETABLE_SIZE +TIMETABLE_DECLARE(profile_timetable); -void profile_clear_timestamps(void); void profile_init(void); void profile_episode_start(void); void profile_episode_end(void); -void profile_aggregates_print(void); -void profile_aggregates_compute(void); - -void profile_print_stats(void); +void profile_aggregate_print_detailed(void); +void profile_aggregate_compute_detailed(void); -enum { - PROFILE_TYPE_STACK, - PROFILE_TYPE_HW, - PROFILE_TYPE_RADIO, - PROFILE_TYPE_SYSTEM, - PROFILE_TYPE_APP, -}; - #endif /* __PROFILE_H__ */ - -/* profile_timestamp_ptr code: - - 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 - 32: 0e 4f mov r15, r14 ; - 34: 0e 5e rla r14 ; - 36: 0e 5e rla r14 ; - 38: 3e 50 00 00 add #0, r14 ;#0x0000 - 3c: be 40 00 00 mov #0, 0(r14) ;#0x0000 - 40: 00 00 - 42: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 - 46: 02 00 - 48: 1f 53 inc r15 ; - 4a: 3f f0 3f 00 and #63, r15 ;#0x003f - 4e: 82 4f 00 00 mov r15, &0x0000 ; - - msp430-specific profile_timetstamp_2ptr code: - - 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 - 32: 0e 4f mov r15, r14 ; - 34: 3e 50 00 00 add #0, r14 ;#0x0000 - 38: be 40 00 00 mov #0, 0(r14) ;#0x0000 - 3c: 00 00 - 3e: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 - 42: 02 00 - 44: 2f 53 incd r15 ; - 46: 3f f0 7f 00 and #127, r15 ;#0x007f - 4a: 82 4f 00 00 mov r15, &0x0000 ; - - generic timestamp_2ptr code: - - 2e: 1f 42 00 00 mov &0x0000,r15 ;0x0000 - 32: 0e 4f mov r15, r14 ; - 34: 1e c3 bic #1, r14 ;r3 As==01 - 36: 0e 5e rla r14 ; - 38: 3e 50 00 00 add #0, r14 ;#0x0000 - 3c: be 40 00 00 mov #0, 0(r14) ;#0x0000 - 40: 00 00 - 42: 9e 42 90 01 mov &0x0190,2(r14) ;0x0190 - 46: 02 00 - 48: 2f 53 incd r15 ; - 4a: 3f f0 7f 00 and #127, r15 ;#0x007f - 4e: 82 4f 00 00 mov r15, &0x0000 ; - -*/ diff --git a/timetable-aggregate.c b/timetable-aggregate.c new file mode 100644 index 000000000..dabe4189e --- /dev/null +++ b/timetable-aggregate.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timetable-aggregate.c,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "sys/timetable-aggregate.h" + +#define XXX_HACK_MAX_CATEGORIES 32 + +#include + +/*---------------------------------------------------------------------------*/ +/* + * + * Find an aggregation category in the list of aggregates. If the + * category could not be found, the function returns a pointer to an + * empty entry. If the list is full, the function returns NULL. + * + */ +static struct timetable_aggregate_entry * +find_aggregate_category(struct timetable_aggregate *a, + const uint16_t cat) +{ + int i; + uint16_t acat; + + for(i = 0; i < a->ptr; ++i) { + acat = (a->entries[i].id[0] << 8) + a->entries[i].id[1]; + if(acat == cat) { + + return &a->entries[i]; + } + } + + if(i == a->size) { + return NULL; + } + + a->entries[a->ptr].id = NULL; + return &a->entries[a->ptr++]; +} +/*---------------------------------------------------------------------------*/ +/* + * + * Find a specific aggregate ID in the list of aggregates. + * + */ +static struct timetable_aggregate_entry * +find_aggregate(struct timetable_aggregate *a, + const char *id) +{ + int i; + for(i = 0; i < a->ptr; ++i) { + if(a->entries[i].id == id) { + return &a->entries[i]; + } + } + if(i == a->size) { + return NULL; + } + a->entries[a->ptr].id = NULL; + return &a->entries[a->ptr++]; +} +/*---------------------------------------------------------------------------*/ +void +timetable_aggregate_print_detailed(struct timetable_aggregate *a) +{ + int i; + /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/ + for(i = 0; i < a->ptr; ++i) { + printf("-- %s: %lu / %u = %lu\n", a->entries[i].id, + a->entries[i].time, + a->entries[i].episodes, + a->entries[i].time / a->entries[i].episodes); + } + + printf("Memory for entries: %d * %d = %d\n", + (int)sizeof(struct timetable_aggregate), a->ptr, + (int)sizeof(struct timetable_aggregate) * a->ptr); +} +/*---------------------------------------------------------------------------*/ +void +timetable_aggregate_print_categories(struct timetable_aggregate *a) +{ + int i; + + /* printf("timetable_aggregate_print_categories: a ptr %d\n", a->ptr);*/ + for(i = 0; i < a->ptr; ++i) { + printf("-- %c%c: %lu / %u = %lu\n", + a->entries[i].id[0], a->entries[i].id[1], + a->entries[i].time, + a->entries[i].episodes, + a->entries[i].time / a->entries[i].episodes); + } + + printf("Memory for entries: %d * %d = %d\n", + (int)sizeof(struct timetable_aggregate), a->ptr, + (int)sizeof(struct timetable_aggregate) * a->ptr); +} +/*---------------------------------------------------------------------------*/ +void +timetable_aggregate_compute_detailed(struct timetable_aggregate *a, + struct timetable *timetable) +{ + int i; + rtimer_clock_t t; + + t = timetable->timestamps[0].time; + + for(i = 1; i < *timetable->ptr; ++i) { + struct timetable_aggregate_entry *entry; + entry = find_aggregate(a, timetable->timestamps[i - 1].id); + if(entry == NULL) { + /* The list is full, skip this entry */ + /* printf("detailed_timetable_aggregate_compute: list full\n");*/ + } else if(entry->id == NULL) { + /* The id was found in the list, so we add it. */ + entry->id = timetable->timestamps[i - 1].id; + entry->time = (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + entry->episodes = 1; + /* printf("New entry %s %lu\n", entry->id, entry->time);*/ + } else { + entry->time += (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + entry->episodes++; + } + t = timetable->timestamps[i].time; + /* printf("a ptr %d\n", a->ptr);*/ + } +} +/*---------------------------------------------------------------------------*/ +void +timetable_aggregate_compute_categories(struct timetable_aggregate *a, + struct timetable *timetable) +{ + int i,j; + rtimer_clock_t t; + uint16_t categories[XXX_HACK_MAX_CATEGORIES]; + int categories_ptr = 0; + + t = timetable->timestamps[0].time; + + for(i = 1; i < *timetable->ptr; ++i) { + struct timetable_aggregate_entry *entry; + uint16_t cat; + + /* printf("category_timetable_aggregate_compute %s %d\n", + timetable->timestamps[i - 1].id, i);*/ + cat = (timetable->timestamps[i - 1].id[0] << 8) + + (timetable->timestamps[i - 1].id[1] & 0xff); + entry = find_aggregate_category(a, cat); + if(entry == NULL) { + /* The list is full, skip this entry */ + /* printf("category_timetable_aggregate_compute: list full\n");*/ + } else if(entry->id == NULL) { + /* The category was not found in the list, so we add it. */ + entry->id = timetable->timestamps[i - 1].id; + entry->time = (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + entry->episodes = 1; + /* printf("New category %c%c time %lu\n", + timetable->timestamps[i - 1].id[0], + timetable->timestamps[i - 1].id[1], entry->time);*/ + } else { + + entry->time += (unsigned long)(timetable->timestamps[i].time - t - + timetable_timestamp_time); + /* printf("Adding time to %c%c time %lu\n", + timetable->timestamps[i - 1].id[0], + timetable->timestamps[i - 1].id[1], entry->time);*/ + + /* Make sure that we only update the episodes of each category + once per run. We keep track of all updated categories in the + "categories" array. If the category is already present in the + array, we do not update it. Otherwise, we insert the category + in the array and update the episodes counter of the + category. */ + + for(j = 0; j < categories_ptr; ++j) { + if(categories[j] == cat) { + break; + } + } + if(j == categories_ptr) { + categories[j] = cat; + categories_ptr++; + entry->episodes++; + } + } + t = timetable->timestamps[i].time; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/timetable-aggregate.h b/timetable-aggregate.h new file mode 100644 index 000000000..d7bc72b6e --- /dev/null +++ b/timetable-aggregate.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timetable-aggregate.h,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __TIMETABLE_AGGREGATE_H__ +#define __TIMETABLE_AGGREGATE_H__ + +#include "sys/timetable.h" +#include "sys/cc.h" + +struct timetable_aggregate_entry { + const char *id; + unsigned short episodes; + unsigned long time; +}; + +struct timetable_aggregate { + struct timetable_aggregate_entry *entries; + int ptr; + const int size; +}; + + +#define TIMETABLE_AGGREGATE_DECLARE(name) \ +struct timetable_aggregate name + + +#define TIMETABLE_AGGREGATE(name, size) \ +static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \ +static struct timetable_aggregate name = { \ + CC_CONCAT(name,_entries), \ + 0, \ + size \ +} + +#define TIMETABLE_AGGREGATE_NONSTATIC(name, size) \ +static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \ +struct timetable_aggregate name = { \ + CC_CONCAT(name,_entries), \ + 0, \ + size \ +} + +void timetable_aggregate_print_detailed(struct timetable_aggregate *a); + +void timetable_aggregate_print_categories(struct timetable_aggregate *a); + +void timetable_aggregate_compute_detailed(struct timetable_aggregate *a, + struct timetable *timetable); +void timetable_aggregate_compute_categories(struct timetable_aggregate *a, + struct timetable *timetable); + + + +#endif /* __TIMETABLE_AGGREGATE_H__ */ diff --git a/timetable.c b/timetable.c new file mode 100644 index 000000000..ce226acf4 --- /dev/null +++ b/timetable.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timetable.c,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "sys/timetable.h" + +#include + +rtimer_clock_t timetable_timestamp_time; + + +/*---------------------------------------------------------------------------*/ +struct timetable_timestamp * +timetable_entry(struct timetable *t, int num) +{ + if(t == NULL) { + return NULL; + } + return &(t->timestamps[num]); +} +/*---------------------------------------------------------------------------*/ +int +timetable_ptr(struct timetable *t) +{ + return *t->ptr; +} +/*---------------------------------------------------------------------------*/ +void +timetable_clear(struct timetable *t) +{ + *t->ptr = 0; +} +/*---------------------------------------------------------------------------*/ +rtimer_clock_t +timetable_timediff(struct timetable *t, + const char *id1, const char *id2) +{ + int i; + int t1, t2; + + t1 = t2 = t->size; + + for(i = *t->ptr - 1; i >= 0; --i) { + if(t->timestamps[i].id == id1) { + t1 = i; + break; + } + } + + for(i = i - 1; i >= 0; --i) { + if(t->timestamps[i].id == id2) { + t2 = i; + break; + } + } + if(t1 != t->size && t2 != t->size) { + return t->timestamps[t1].time - t->timestamps[t2].time; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +timetable_init(void) +{ + char dummy1, dummy2; +#define temp_size 4 + TIMETABLE_NONSTATIC(temp); + + timetable_clear(&temp); + + /* Measure the time for taking a timestamp. */ + TIMETABLE_TIMESTAMP(temp, &dummy1); + TIMETABLE_TIMESTAMP(temp, &dummy2); + timetable_timestamp_time = timetable_timediff(&temp, &dummy1, &dummy2); +} +/*---------------------------------------------------------------------------*/ +void +timetable_print(struct timetable *t) +{ + int i; + int time; + + time = t->timestamps[0].time; + + printf("---\n"); + for(i = 1; i < *t->ptr; ++i) { + printf("%s: %u\n", t->timestamps[i - 1].id, t->timestamps[i].time - time); + time = t->timestamps[i].time; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/timetable.h b/timetable.h new file mode 100644 index 000000000..46aced967 --- /dev/null +++ b/timetable.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: timetable.h,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __TIMETABLE_H__ +#define __TIMETABLE_H__ + +#include "sys/cc.h" +#include "sys/rtimer.h" + + +struct timetable_timestamp { + const char *id; + rtimer_clock_t time; +#if TIMETABLE_WITH_TYPE + uint8_t type; +#endif /* TIMETABLE_WITH_TYPE */ +}; +struct timetable { + struct timetable_timestamp *timestamps; + const int size; + unsigned int * const ptr; +}; + +#define TIMETABLE_NONSTATIC(name) \ +struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ +unsigned int CC_CONCAT(name,_ptr); \ +struct timetable name = { \ + CC_CONCAT(name,_timestamps), \ + CC_CONCAT(name,_size), \ + &CC_CONCAT(name,_ptr)} + +#define TIMETABLE_STATIC(name) \ +static struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ +static unsigned int CC_CONCAT(name,_ptr); \ +static struct timetable name = { \ + CC_CONCAT(name,_timestamps), \ + CC_CONCAT(name,_size), \ + &CC_CONCAT(name,_ptr)} + +#define TIMETABLE_DECLARE(name) \ +extern unsigned int CC_CONCAT(name,_ptr); \ +extern struct timetable_timestamp CC_CONCAT(name, _timestamps)[CC_CONCAT(name,_size)]; \ +extern struct timetable name + +#define TIMETABLE(name) TIMETABLE_STATIC(name) + +#define TIMETABLE_TIMESTAMP(name, str) \ +do { \ + CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ + CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ + CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ + CC_CONCAT(name,_size); \ +} while(0) + +#if TIMETABLE_WITH_TYPE +#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) \ +do { \ + CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ + CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].type = t; \ + CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ + CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ + CC_CONCAT(name,_size); \ +} while(0) +#else /* TIMETABLE_WITH_TYPE */ +#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) TIMETABLE_TIMESTAMP(name, str) +#endif /* TIMETABLE_WITH_TYPE */ + + +#define TIMETABLE_RESUME(name,num) \ + TIMETABLE_TIMESTAMP(CC_CONCAT(name,_timestamps[num].id)) + +#define TIMETABLE_COND_TIMESTAMP(cond,name,id) \ + do { if(cond) { \ + TIMETABLE_TIMESTAMP(id); \ + } while(0) + +#define TIMETABLE_COND_RESUME(cond,name,num) \ + TIMETABLE_COND_TIMESTAMP(cond,name, \ + CC_CONCAT(name,_timestamps[num].id)) + +#define TIMETABLE_ENTRY(name, num) CC_CONCAT(name,_timestamps)[num] +#define TIMETABLE_PTR(name) CC_CONCAT(name,_ptr) + +/** + * The time for taking a timestamp. + */ +extern rtimer_clock_t timetable_timestamp_time; + + +struct timetable_timestamp *timetable_entry(struct timetable *t, + int num); +int timetable_ptr(struct timetable *t); + +void timetable_clear(struct timetable *t); +rtimer_clock_t timetable_timediff(struct timetable *t, + const char *id1, const char *id2); +void timetable_init(void); + +void timetable_print(struct timetable *t); + +#include "sys/timetable-aggregate.h" + +#endif /* __TIMETABLE_H__ */ From 6900852b61a75ba6bca3497247ec76a409145239 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 23 Jan 2008 15:18:06 +0000 Subject: [PATCH 054/146] Rewrote the process code so that initialization events are posted synchronously instead of asynchronously, so that we don't have to explicitly wait for processes to be initialized. This also reduces the size of the event queue by half on the Tmote Sky platform since the queue was maximized during system bootup. This change also prompted an update of the process invokation code to ensure that a process is not invoked again when processing an event. General cleanup of the code also. --- process.c | 155 ++++++++++++++++++++++-------------------------------- process.h | 19 +++++-- 2 files changed, 77 insertions(+), 97 deletions(-) diff --git a/process.c b/process.c index 10cb2616b..ff3a14e3f 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.5 2007/04/04 09:19:18 nifi Exp $ + * @(#)$Id: process.c,v 1.6 2008/01/23 15:18:06 adamdunkels Exp $ */ /** @@ -49,6 +49,8 @@ #include "sys/process.h" #include "sys/arg.h" +PROCESS_NAME(simple_cc2420_process); + /* * Pointer to the currently running process structure. */ @@ -66,20 +68,18 @@ struct event_data { struct process *p; }; -#ifdef PROCESS_CONF_FASTPOLL -#define NPOLLS PROCESS_CONF_FASTPOLL -static volatile unsigned npolls; -static struct process *needpoll[NPOLLS]; -#endif static process_num_events_t nevents, fevent; static struct event_data events[PROCESS_CONF_NUMEVENTS]; +#if PROCESS_CONF_STATS +process_num_events_t process_maxevents; +#endif + static volatile unsigned char poll_requested; #define PROCESS_STATE_NONE 0 -#define PROCESS_STATE_INIT 1 -#define PROCESS_STATE_RUNNING 2 -#define PROCESS_STATE_NEEDS_POLL 3 +#define PROCESS_STATE_RUNNING 1 +#define PROCESS_STATE_CALLED 2 static void call_process(struct process *p, process_event_t ev, process_data_t data); @@ -99,7 +99,7 @@ process_alloc_event(void) } /*---------------------------------------------------------------------------*/ void -process_start(struct process *p, char *arg) +process_start(struct process *p, const char *arg) { struct process *q; @@ -114,13 +114,13 @@ process_start(struct process *p, char *arg) /* Put on the procs list.*/ p->next = process_list; process_list = p; - - p->state = PROCESS_STATE_INIT; - + p->state = PROCESS_STATE_RUNNING; PT_INIT(&p->pt); - - /* Post an asynchronous event to the process. */ - process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); + + PRINTF("process: starting '%s'\n", p->name); + + /* Post a synchronous initialization event to the process. */ + process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg); } /*---------------------------------------------------------------------------*/ static void @@ -129,7 +129,9 @@ exit_process(struct process *p, struct process *fromprocess) register struct process *q; struct process *old_current = process_current; - if(p->state != PROCESS_STATE_NONE) { + PRINTF("process: exit_process '%s'\n", p->name); + + if(process_is_running(p)) { /* Process was running */ p->state = PROCESS_STATE_NONE; @@ -168,20 +170,13 @@ exit_process(struct process *p, struct process *fromprocess) for(n = nevents; n > 0; n--) { if(events[i].p == p) { events[i].p = PROCESS_ZOMBIE; -#if 0 +#if DEBUG printf("soft panic: exiting process has remaining event 0x%x\n", events[i].ev); #endif } i = (i + 1) % PROCESS_CONF_NUMEVENTS; } -#ifdef NPOLLS - for(i = 0; i < NPOLLS && i < npolls; i++) { - if(needpoll[i] == p) { - needpoll[i] = PROCESS_ZOMBIE; - } - } -#endif } process_current = old_current; } @@ -190,17 +185,25 @@ static void call_process(struct process *p, process_event_t ev, process_data_t data) { int ret; + +#if DEBUG + if(p->state == PROCESS_STATE_CALLED) { + printf("process: process '%s' called again with event %d\n", p->name, ev); + } +#endif /* DEBUG */ - if((p->state == PROCESS_STATE_RUNNING || - p->state == PROCESS_STATE_NEEDS_POLL) && + if((p->state & PROCESS_STATE_RUNNING) && p->thread != NULL) { + PRINTF("process: calling process '%s' with event %d\n", p->name, ev); process_current = p; - + p->state = PROCESS_STATE_CALLED; ret = p->thread(&p->pt, ev, data); if(ret == PT_EXITED || ret == PT_ENDED || ev == PROCESS_EVENT_EXIT) { exit_process(p, p); + } else { + p->state = PROCESS_STATE_RUNNING; } } } @@ -217,6 +220,9 @@ process_init(void) lastevent = PROCESS_EVENT_MAX; nevents = fevent = 0; +#if PROCESS_CONF_STATS + process_maxevents = 0; +#endif /* PROCESS_CONF_STATS */ process_current = process_list = NULL; } @@ -229,56 +235,18 @@ static void do_poll(void) { struct process *p; - - poll_requested = 0; - -#ifdef NPOLLS - unsigned i; - int s; - /* Fastpoll */ - //printf("F %d\n", npolls); - for(i = 0; i < npolls; i++) { - do_more: - if(i == NPOLLS) { - goto slowpoll; - } - if(needpoll[i] != PROCESS_ZOMBIE - && needpoll[i]->state == PROCESS_STATE_NEEDS_POLL) { - needpoll[i]->state = PROCESS_STATE_RUNNING; - call_process(needpoll[i], PROCESS_EVENT_POLL, NULL); - } - } - s = splhigh(); - if(i == npolls) { - npolls = 0; - splx(s); - return; - } - splx(s); - goto do_more; - - /* Call poll handlers. */ - slowpoll: - //printf("S %d\n", npolls); - npolls = 0; -#endif - /* Call poll handlers. */ - for(p = process_list; p != NULL; p = p->next) { - if(p->state == PROCESS_STATE_NEEDS_POLL) { - p->state = PROCESS_STATE_RUNNING; - call_process(p, PROCESS_EVENT_POLL, NULL); - } - -#if 0 - /* If a poll has been requested for one of the processes, we start - from the beginning again. */ - if(poll_requested) { - poll_requested = 0; - p = process_list; + do { + poll_requested = 0; + /* Call the processes that needs to be polled. */ + for(p = process_list; p != NULL; p = p->next) { + if(p->needspoll) { + p->state = PROCESS_STATE_RUNNING; + p->needspoll = 0; + call_process(p, PROCESS_EVENT_POLL, NULL); + } } -#endif - } + } while(poll_requested); } /*---------------------------------------------------------------------------*/ /* @@ -347,12 +315,12 @@ do_event(void) int process_run(void) { - /* Process "poll" events. */ + /* Process poll events. */ if(poll_requested) { do_poll(); } - - /* Process one event */ + + /* Process one event from the queue */ do_event(); return nevents + poll_requested; @@ -361,11 +329,7 @@ process_run(void) int process_nevents(void) { -#ifdef NPOLLS - return nevents + npolls; -#else return nevents + poll_requested; -#endif } /*---------------------------------------------------------------------------*/ int @@ -390,6 +354,12 @@ process_post(struct process *p, process_event_t ev, process_data_t data) events[snum].p = p; ++nevents; +#if PROCESS_CONF_STATS + if(nevents > process_maxevents) { + process_maxevents = nevents; + } +#endif /* PROCESS_CONF_STATS */ + return PROCESS_ERR_OK; } /*---------------------------------------------------------------------------*/ @@ -406,19 +376,18 @@ void process_poll(struct process *p) { if(p != NULL) { - if(p->state == PROCESS_STATE_RUNNING) { - p->state = PROCESS_STATE_NEEDS_POLL; + if(p->state == PROCESS_STATE_RUNNING || + p->state == PROCESS_STATE_CALLED) { + p->needspoll = 1; poll_requested = 1; -#ifdef NPOLLS - int s = splhigh(); - if(npolls < NPOLLS) { - needpoll[npolls] = p; - } - if(npolls != ~0u) npolls++; /* Beware of overflow! */ - splx(s); -#endif } } } /*---------------------------------------------------------------------------*/ +int +process_is_running(struct process *p) +{ + return p->state != PROCESS_STATE_NONE; +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/process.h b/process.h index e14ad3a0e..92bd7e57e 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.12 2007/11/17 22:11:19 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.13 2008/01/23 15:18:06 adamdunkels Exp $ */ /** @@ -275,7 +275,6 @@ typedef unsigned char process_num_events_t; static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) - #if PROCESS_LOADABLE #define PROCESS_LOAD(name) const struct process *process_load = &name #else /* PROCESS_LOADABLE */ @@ -320,7 +319,7 @@ struct process { const char *name; PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); struct pt pt; - unsigned char state; + unsigned char state, needspoll; }; /** @@ -337,7 +336,7 @@ struct process { * process * */ -void process_start(struct process *p, char *arg); +void process_start(struct process *p, const char *arg); /** * Post an asynchronous event. @@ -497,6 +496,18 @@ void process_init(void); */ int process_run(void); + +/** + * Check if a process is running. + * + * This function checks if a specific process is running. + * + * \param p The process. + * \retval Non-zero if the process is running. + * \retval Zero if the process is not running. + */ +int process_is_running(struct process *p); + /** * Number of events waiting to be processed. * From 3c0b8a0cc658b3487d789a6b289333a216c2282a Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 23 Jan 2008 21:06:25 +0000 Subject: [PATCH 055/146] Removed remaining debug code --- process.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/process.c b/process.c index ff3a14e3f..ba9816e1a 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.6 2008/01/23 15:18:06 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.7 2008/01/23 21:06:25 adamdunkels Exp $ */ /** @@ -49,8 +49,6 @@ #include "sys/process.h" #include "sys/arg.h" -PROCESS_NAME(simple_cc2420_process); - /* * Pointer to the currently running process structure. */ From 3127f0180bcef6d6d7affaa1a13a59511d1905a4 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 24 Jan 2008 21:00:51 +0000 Subject: [PATCH 056/146] Process only one poll request at a time to avoid starvation if one process keeps calling process_poll() from its poll handler --- process.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/process.c b/process.c index ba9816e1a..5f5655157 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.7 2008/01/23 21:06:25 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.8 2008/01/24 21:00:51 adamdunkels Exp $ */ /** @@ -234,17 +234,15 @@ do_poll(void) { struct process *p; - do { - poll_requested = 0; - /* Call the processes that needs to be polled. */ - for(p = process_list; p != NULL; p = p->next) { - if(p->needspoll) { - p->state = PROCESS_STATE_RUNNING; - p->needspoll = 0; - call_process(p, PROCESS_EVENT_POLL, NULL); - } + poll_requested = 0; + /* Call the processes that needs to be polled. */ + for(p = process_list; p != NULL; p = p->next) { + if(p->needspoll) { + p->state = PROCESS_STATE_RUNNING; + p->needspoll = 0; + call_process(p, PROCESS_EVENT_POLL, NULL); } - } while(poll_requested); + } } /*---------------------------------------------------------------------------*/ /* From 146bd31ea2d0b235bd446735b7ebdae2974a0051 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 7 Feb 2008 15:43:37 +0000 Subject: [PATCH 057/146] Removed support for the old method of starting a dynamically loaded process based on the symbol 'process_load'. All loaders now have to use the new method based on the symbol 'autostart_processes'. --- process.h | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/process.h b/process.h index 92bd7e57e..fc883cf7e 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.13 2008/01/23 15:18:06 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.14 2008/02/07 15:43:37 oliverschmidt Exp $ */ /** @@ -275,12 +275,6 @@ typedef unsigned char process_num_events_t; static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) -#if PROCESS_LOADABLE -#define PROCESS_LOAD(name) const struct process *process_load = &name -#else /* PROCESS_LOADABLE */ -#define PROCESS_LOAD(name) extern int _dummy -#endif /* PROCESS_LOADABLE */ -CLIF extern const struct process *process_load; /** * Declare the name of a process. @@ -292,10 +286,6 @@ CLIF extern const struct process *process_load; */ #define PROCESS_NAME(name) extern struct process name -#define PROCESS_NOLOAD(name, strname) \ - PROCESS_THREAD(name, ev, data); \ - struct process name = { NULL, strname, \ - process_thread_##name } /** * Declare a process. * @@ -308,9 +298,10 @@ CLIF extern const struct process *process_load; * * \hideinitializer */ -#define PROCESS(name, strname) \ - PROCESS_NOLOAD(name, strname); \ - PROCESS_LOAD(name) +#define PROCESS(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, strname, \ + process_thread_##name } /** @} */ From d51e3afa17c4e740c3b531a6dd9e2307e221f811 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 7 Feb 2008 15:47:28 +0000 Subject: [PATCH 058/146] Declare 'autostart_processes' as CLIF (Contiki Loadable Interface) to trigger exporting the symbol from shared libraries on Win32. --- autostart.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autostart.h b/autostart.h index ae8c57a3f..5525268de 100644 --- a/autostart.h +++ b/autostart.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.h,v 1.3 2007/11/18 12:27:45 ksb Exp $ + * $Id: autostart.h,v 1.4 2008/02/07 15:47:28 oliverschmidt Exp $ */ /** @@ -46,7 +46,7 @@ #if ! CC_NO_VA_ARGS #if AUTOSTART_ENABLE #define AUTOSTART_PROCESSES(...) \ -struct process * const autostart_processes[] = {__VA_ARGS__, NULL} +CLIF struct process * const autostart_processes[] = {__VA_ARGS__, NULL} #else /* AUTOSTART_ENABLE */ #define AUTOSTART_PROCESSES(...) \ extern int _dummy From 00c8bdc1d75e503b0d4999794e22b4b33bc1aed4 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 7 Feb 2008 23:04:35 +0000 Subject: [PATCH 059/146] Declare some more functions as CCIF (Contiki Core Interface) to trigger exporting the symbols from the main binary on Win32. --- clock.h | 4 ++-- etimer.h | 4 ++-- process.h | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clock.h b/clock.h index 144c646e9..72bd208ff 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.3 2007/09/07 10:20:30 fros4943 Exp $ + * $Id: clock.h,v 1.4 2008/02/07 23:04:35 oliverschmidt Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -78,7 +78,7 @@ void clock_init(void); * * \return The current clock time, measured in system ticks. */ -clock_time_t clock_time(void); +CCIF clock_time_t clock_time(void); void clock_delay(unsigned int); diff --git a/etimer.h b/etimer.h index aa4b5734b..a965089b9 100644 --- a/etimer.h +++ b/etimer.h @@ -58,7 +58,7 @@ * * Author: Adam Dunkels * - * $Id: etimer.h,v 1.2 2006/08/26 23:59:39 oliverschmidt Exp $ + * $Id: etimer.h,v 1.3 2008/02/07 23:04:35 oliverschmidt Exp $ */ #ifndef __ETIMER_H__ #define __ETIMER_H__ @@ -113,7 +113,7 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval); * * \sa etimer_restart() */ -void etimer_reset(struct etimer *et); +CCIF void etimer_reset(struct etimer *et); /** * \brief Restart an event timer from the current point in time diff --git a/process.h b/process.h index fc883cf7e..0d2639b46 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.14 2008/02/07 15:43:37 oliverschmidt Exp $ + * @(#)$Id: process.h,v 1.15 2008/02/07 23:04:35 oliverschmidt Exp $ */ /** @@ -327,7 +327,7 @@ struct process { * process * */ -void process_start(struct process *p, const char *arg); +CCIF void process_start(struct process *p, const char *arg); /** * Post an asynchronous event. @@ -362,8 +362,8 @@ CCIF int process_post(struct process *p, process_event_t ev, void* data); * \param data A pointer to additional data that is posted together * with the event. */ -void process_post_synch(struct process *p, - process_event_t ev, void* data); +CCIF void process_post_synch(struct process *p, + process_event_t ev, void* data); /** * \brief Cause a process to exit @@ -438,7 +438,7 @@ process_current = p * \note There currently is no way to deallocate an allocated event * number. */ -process_event_t process_alloc_event(void); +CCIF process_event_t process_alloc_event(void); /** @} */ @@ -497,7 +497,7 @@ int process_run(void); * \retval Non-zero if the process is running. * \retval Zero if the process is not running. */ -int process_is_running(struct process *p); +CCIF int process_is_running(struct process *p); /** * Number of events waiting to be processed. From 9b3b4d575c0dde8d560a482fede0b0f1abc1e150 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Sun, 10 Feb 2008 11:17:33 +0000 Subject: [PATCH 060/146] Decorate declaration rather than definition with export attribute. --- autostart.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autostart.h b/autostart.h index 5525268de..c457bb4d2 100644 --- a/autostart.h +++ b/autostart.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.h,v 1.4 2008/02/07 15:47:28 oliverschmidt Exp $ + * $Id: autostart.h,v 1.5 2008/02/10 11:17:33 oliverschmidt Exp $ */ /** @@ -46,7 +46,7 @@ #if ! CC_NO_VA_ARGS #if AUTOSTART_ENABLE #define AUTOSTART_PROCESSES(...) \ -CLIF struct process * const autostart_processes[] = {__VA_ARGS__, NULL} +struct process * const autostart_processes[] = {__VA_ARGS__, NULL} #else /* AUTOSTART_ENABLE */ #define AUTOSTART_PROCESSES(...) \ extern int _dummy @@ -55,7 +55,7 @@ extern int _dummy #error "C compiler must support __VA_ARGS__ macro" #endif -extern struct process * const autostart_processes[]; +CLIF extern struct process * const autostart_processes[]; void autostart_start(struct process * const processes[]); void autostart_exit(struct process * const processes[]); From 9317debd6cd827a6308e1dfbb624a48c25fbdf05 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 28 Feb 2008 22:11:30 +0000 Subject: [PATCH 061/146] Adjusted tabs. --- timetable.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/timetable.h b/timetable.h index 46aced967..7b5fca00b 100644 --- a/timetable.h +++ b/timetable.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.h,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + * $Id: timetable.h,v 1.2 2008/02/28 22:11:30 oliverschmidt Exp $ */ /** @@ -58,24 +58,24 @@ struct timetable { unsigned int * const ptr; }; -#define TIMETABLE_NONSTATIC(name) \ -struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ -unsigned int CC_CONCAT(name,_ptr); \ -struct timetable name = { \ - CC_CONCAT(name,_timestamps), \ - CC_CONCAT(name,_size), \ +#define TIMETABLE_NONSTATIC(name) \ +struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ +unsigned int CC_CONCAT(name,_ptr); \ +struct timetable name = { \ + CC_CONCAT(name,_timestamps), \ + CC_CONCAT(name,_size), \ &CC_CONCAT(name,_ptr)} -#define TIMETABLE_STATIC(name) \ -static struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ -static unsigned int CC_CONCAT(name,_ptr); \ -static struct timetable name = { \ - CC_CONCAT(name,_timestamps), \ - CC_CONCAT(name,_size), \ +#define TIMETABLE_STATIC(name) \ +static struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ +static unsigned int CC_CONCAT(name,_ptr); \ +static struct timetable name = { \ + CC_CONCAT(name,_timestamps), \ + CC_CONCAT(name,_size), \ &CC_CONCAT(name,_ptr)} -#define TIMETABLE_DECLARE(name) \ -extern unsigned int CC_CONCAT(name,_ptr); \ +#define TIMETABLE_DECLARE(name) \ +extern unsigned int CC_CONCAT(name,_ptr); \ extern struct timetable_timestamp CC_CONCAT(name, _timestamps)[CC_CONCAT(name,_size)]; \ extern struct timetable name @@ -86,17 +86,17 @@ do { \ CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ - CC_CONCAT(name,_size); \ + CC_CONCAT(name,_size); \ } while(0) #if TIMETABLE_WITH_TYPE -#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) \ +#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) \ do { \ CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].type = t; \ CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ - CC_CONCAT(name,_size); \ + CC_CONCAT(name,_size); \ } while(0) #else /* TIMETABLE_WITH_TYPE */ #define TIMETABLE_TIMESTAMP_TYPE(name, str, t) TIMETABLE_TIMESTAMP(name, str) From fabcb34d52051769e71c3d1261d1a5befed82958 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Thu, 28 Feb 2008 22:43:40 +0000 Subject: [PATCH 062/146] The cc65 compiler has a bug that doesn't allow to initialize an automatic struct with references to automatic variables. Therefore I changed the timetable used for measuring the timestamping time from automatic to static - which wastes some bytes in the data segment. If this isn't generally acceptable then an #ifdef __CC65__ seems to be the appropriate approach. --- timetable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/timetable.c b/timetable.c index ce226acf4..100f024d0 100644 --- a/timetable.c +++ b/timetable.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.c,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + * $Id: timetable.c,v 1.2 2008/02/28 22:43:40 oliverschmidt Exp $ */ /** @@ -101,7 +101,7 @@ timetable_init(void) { char dummy1, dummy2; #define temp_size 4 - TIMETABLE_NONSTATIC(temp); + TIMETABLE_STATIC(temp); timetable_clear(&temp); From e35e56fea9519fa220dc5aec7e6ada1425238421 Mon Sep 17 00:00:00 2001 From: fros4943 Date: Thu, 13 Mar 2008 14:27:34 +0000 Subject: [PATCH 063/146] added timetable aggregate reset function --- timetable-aggregate.c | 12 +++++++++++- timetable-aggregate.h | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/timetable-aggregate.c b/timetable-aggregate.c index dabe4189e..5c35b035d 100644 --- a/timetable-aggregate.c +++ b/timetable-aggregate.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable-aggregate.c,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + * $Id: timetable-aggregate.c,v 1.2 2008/03/13 14:27:34 fros4943 Exp $ */ /** @@ -115,6 +115,16 @@ timetable_aggregate_print_detailed(struct timetable_aggregate *a) } /*---------------------------------------------------------------------------*/ void +timetable_aggregate_reset(struct timetable_aggregate *a) +{ + int i; + for(i = 0; i < a->ptr; ++i) { + a->entries[i].time = 0; + a->entries[i].episodes = 0; + } +} +/*---------------------------------------------------------------------------*/ +void timetable_aggregate_print_categories(struct timetable_aggregate *a) { int i; diff --git a/timetable-aggregate.h b/timetable-aggregate.h index d7bc72b6e..24477c54c 100644 --- a/timetable-aggregate.h +++ b/timetable-aggregate.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable-aggregate.h,v 1.1 2008/01/17 12:19:26 adamdunkels Exp $ + * $Id: timetable-aggregate.h,v 1.2 2008/03/13 14:27:34 fros4943 Exp $ */ /** @@ -81,6 +81,8 @@ void timetable_aggregate_print_detailed(struct timetable_aggregate *a); void timetable_aggregate_print_categories(struct timetable_aggregate *a); +void timetable_aggregate_reset(struct timetable_aggregate *a); + void timetable_aggregate_compute_detailed(struct timetable_aggregate *a, struct timetable *timetable); void timetable_aggregate_compute_categories(struct timetable_aggregate *a, From e4b1a346ecb2b35fc535291624707a3444993570 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 27 May 2008 14:00:09 +0000 Subject: [PATCH 064/146] Removed old unused documentation that messed up Doxygen --- mt.h | 132 +---------------------------------------------------------- 1 file changed, 1 insertion(+), 131 deletions(-) diff --git a/mt.h b/mt.h index d8330b0a7..2724adeed 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.4 2007/04/03 18:47:21 oliverschmidt Exp $ + * $Id: mt.h,v 1.5 2008/05/27 14:00:09 adamdunkels Exp $ */ /** \addtogroup sys @@ -236,29 +236,6 @@ void mt_start(struct mt_thread *thread, void (* function)(void *), void *data); */ void mt_exec(struct mt_thread *thread); -/** - * Post an event to a thread. - * - * This function posts an event to a thread. The thread will be - * scheduled if the thread currently is waiting for the posted event - * number. If the thread is not waiting for the event, this function - * does nothing. - * - * \note The thread library must first be initialized with the mt_init() - * function. - * - * \param thread A pointer to a struct mt_thread block that must be - * allocated by the caller. - * - * \param s The event that is posted to the thread. - * - * \param data An opaque pointer to a user specified structure - * containing additonal information, or NULL if no additional - * information is needed. - */ -/*void mt_exec_event(struct mt_thread *thread, process_event_t s, - process_data_t data);*/ - /** * Voluntarily give up the processor. * @@ -268,42 +245,6 @@ void mt_exec(struct mt_thread *thread); */ void mt_yield(void); -/** - * Post an event to another process. - * - * This function is called by a running thread and will emit a signal - * to another Contiki process. This will cause the currently executing - * thread to yield. - * - * \param p The process receiving the signal, or PROCESS_BROADCAST - * for a broadcast event. - * - * \param ev The event to be posted. - * - * \param data A pointer to a message that is to be delivered together - * with the signal. - * - */ -/*void mt_post(struct process *p, process_event_t ev, process_data_t data);*/ - -/** - * Block and wait for an event to occur. - * - * This function can be called by a running thread in order to block - * and wait for an event. The function returns when an event has - * occured. The event number and the associated data are placed in the - * variables pointed to by the function arguments. - * - * \param ev A pointer to a process_event_t variable. The variable - * will be filled with the number event that woke the thread. - * - * \param data A pointer to a process_data_t variable. The variable - * will be filled with the data associated with the event that woke - * the thread. - * - */ -/*void mt_wait(process_event_t *ev, process_data_t *data);*/ - /** * Exit a thread. * @@ -325,77 +266,6 @@ void mt_exit(void); */ void mt_stop(struct mt_thread *thread); -#if 0 -/** - * \defgroup mtp Multi-threading library convenience functions - * @{ - * - * The Contiki multi-threading library has an interface that might be - * hard to use. Therefore, the mtp module provides a simpler - * interface. - * - * Example: -\code -static void -example_thread_code(void *data) -{ - while(1) { - printf("Test\n"); - mt_yield(); - } -} -MTP(example_thread, "Example thread", p1, t1, t1_idle); - -int -main(int argc, char *argv[]) -{ - mtp_start(&example_thread, example_thread_code, NULL); -} -\endcode -* -*/ - - -/** - * Declare a multithreaded process. - * - * This macro is used to declare a multithreaded process. - * - * \hideinitializer - */ -#define MT_PROCESS(name, strname) \ -extern struct mt_process name##mt_process; \ -struct process name = { NULL, strname, mt_process_thread }; \ -static struct mt_process thread = {&name} - -struct mt_process { - struct process *p; - struct mt_thread t; -}; - -/** - * Start a thread. - * - * This function starts the process in which the thread is to run, and - * also sets up the thread to run within the process. The function - * should be passed variable names declared with the MTP() macro. - * - * \param t A pointer to a thread structure previously declared with MTP(). - * - * \param function A pointer to the function that the thread should - * start executing. - * - * \param data A pointer that the function should be passed when first - * invocated. - */ -void mtp_start(struct mt_process *p, - void (* function)(void *), void *data); - -void mtp_exit(void); -void mtp_eventhandler(process_event_t ev, process_data_t data); - -/** @} */ -#endif /* 0 */ /** @} */ /** @} */ #endif /* __MT_H__ */ From 623e7f27c7c414f5342b7c805456b7b175372854 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 2 Jul 2008 08:35:29 +0000 Subject: [PATCH 065/146] Added configuration option to circumvent C compilers that have problems with const function pointers (i.e., sdcc) --- cc.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cc.h b/cc.h index 1d1c8bdde..7250f6a87 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.5 2008/01/14 09:22:22 adamdunkels Exp $ + * $Id: cc.h,v 1.6 2008/07/02 08:35:29 adamdunkels Exp $ * */ #ifndef __CC_H__ @@ -77,6 +77,15 @@ #define CC_FASTCALL #endif /* CC_CONF_FASTCALL */ +/** + * Configure if the C compiler have problems with const function pointers + */ +#ifdef CC_CONF_CONST_FUNCTION_BUG +#define CC_CONST_FUNCTION +#else /* CC_CONF_FASTCALL */ +#define CC_CONST_FUNCTION const +#endif /* CC_CONF_FASTCALL */ + /** * Configure work-around for unsigned char bugs with sdcc. */ From 28169eada6bc360b67502b83f39f0a450ef6eb61 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 3 Jul 2008 23:36:30 +0000 Subject: [PATCH 066/146] Moved energest.{c,h} from core/lib to core/sys: power profiling is a system mechanism, not a library --- energest.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++ energest.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 energest.c create mode 100644 energest.h diff --git a/energest.c b/energest.c new file mode 100644 index 000000000..60c52d0d4 --- /dev/null +++ b/energest.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: energest.c,v 1.1 2008/07/03 23:36:30 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of the energy estimation module + * \author + * Adam Dunkels + */ + +#include "sys/energest.h" +#include "contiki-conf.h" + +#if ENERGEST_CONF_ON + +int energest_total_count; +energest_t energest_total_time[ENERGEST_TYPE_MAX]; +unsigned short energest_current_time[ENERGEST_TYPE_MAX]; +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS +energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVICE_LEVELS]; +#endif +unsigned char energest_current_mode[ENERGEST_TYPE_MAX]; + +/*---------------------------------------------------------------------------*/ +void +energest_init(void) +{ + int i; + for(i = 0; i < ENERGEST_TYPE_MAX; ++i) { + energest_total_time[i].current = energest_current_time[i] = 0; + energest_current_mode[i] = 0; + } +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS + for(i = 0; i < ENERGEST_CONF_LEVELDEVICE_LEVELS; ++i) { + energest_leveldevice_current_leveltime[i].current = 0; + } +#endif +} +/*---------------------------------------------------------------------------*/ +unsigned long +energest_type_time(int type) +{ + /* Note: does not support ENERGEST_CONF_LEVELDEVICE_LEVELS! */ +#ifndef ENERGEST_CONF_LEVELDEVICE_LEVELS + if(energest_current_mode[type]) { + rtimer_clock_t now = RTIMER_NOW(); + energest_total_time[type].current += (unsigned long) + ((signed short)now - (signed short)energest_current_time[type]); + energest_current_time[type] = now; + } +#endif /* ENERGEST_CONF_LEVELDEVICE_LEVELS */ + return energest_total_time[type].current; +} +/*---------------------------------------------------------------------------*/ +unsigned long +energest_leveldevice_leveltime(int powerlevel) +{ +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS + return energest_leveldevice_current_leveltime[powerlevel].current; +#else + return 0; +#endif +} +/*---------------------------------------------------------------------------*/ +void +energest_type_set(int type, unsigned long val) +{ + energest_total_time[type].current = val; +} +/*---------------------------------------------------------------------------*/ +/* Note: does not support ENERGEST_CONF_LEVELDEVICE_LEVELS! */ +void +energest_flush(void) +{ + rtimer_clock_t now; + int i; + for(i = 0; i < ENERGEST_TYPE_MAX; i++) { + if(energest_current_mode[i]) { + now = RTIMER_NOW(); + energest_total_time[i].current += (unsigned long) + ((signed short)now - (signed short)energest_current_time[i]); + energest_current_time[i] = now; + } + } +} +/*---------------------------------------------------------------------------*/ +#else /* ENERGEST_CONF_ON */ +void energest_type_set(int type, unsigned long val) {} +void energest_init(void) {} +unsigned long energest_type_time(int type) { return 0; } +void energest_flush(void) {} +#endif /* ENERGEST_CONF_ON */ diff --git a/energest.h b/energest.h new file mode 100644 index 000000000..5327c1212 --- /dev/null +++ b/energest.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: energest.h,v 1.1 2008/07/03 23:36:30 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the energy estimation mechanism + * \author + * Adam Dunkels + */ + +#ifndef __ENERGEST_H__ +#define __ENERGEST_H__ + +#include "sys/rtimer.h" + +typedef struct { + /* unsigned long cummulative[2];*/ + unsigned long current; +} energest_t; + +enum energest_type { + ENERGEST_TYPE_CPU, + ENERGEST_TYPE_LPM, + ENERGEST_TYPE_IRQ, + ENERGEST_TYPE_LED_GREEN, + ENERGEST_TYPE_LED_YELLOW, + ENERGEST_TYPE_LED_RED, + ENERGEST_TYPE_TRANSMIT, + ENERGEST_TYPE_LISTEN, + + ENERGEST_TYPE_SENSORS, + + ENERGEST_TYPE_SERIAL, + + ENERGEST_TYPE_MAX +}; + +void energest_init(void); +unsigned long energest_type_time(int type); +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS +unsigned long energest_leveldevice_leveltime(int powerlevel); +#endif +void energest_type_set(int type, unsigned long value); +void energest_flush(void); + +#if ENERGEST_CONF_ON +/*extern int energest_total_count;*/ +extern energest_t energest_total_time[ENERGEST_TYPE_MAX]; +extern unsigned short energest_current_time[ENERGEST_TYPE_MAX]; +extern unsigned char energest_current_mode[ENERGEST_TYPE_MAX]; + +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS +extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVICE_LEVELS]; +#endif + +#define ENERGEST_ON(type) do { \ + /*++energest_total_count;*/ \ + energest_current_time[type] = RTIMER_NOW(); \ + energest_current_mode[type] = 1; \ + } while(0) + +#define ENERGEST_OFF(type) do { \ + energest_total_time[type].current += (unsigned long)((signed short)RTIMER_NOW() - \ + (signed short)energest_current_time[type]); \ + energest_current_mode[type] = 0; \ + } while(0) + +#define ENERGEST_OFF_LEVEL(type,level) do { \ + energest_leveldevice_current_leveltime[level].current += (unsigned long)((signed short)RTIMER_NOW() - \ + (signed short)energest_current_time[type]); \ + energest_current_mode[type] = 0; \ + } while(0) + + +#else /* ENERGEST_CONF_ON */ +#define ENERGEST_ON(type) do { } while(0) +#define ENERGEST_OFF(type) do { } while(0) +#define ENERGEST_OFF_LEVEL(type,level) do { } while(0) +#endif /* ENERGEST_CONF_ON */ + +#define ENERGEST_SECOND RTIMER_ARCH_SECOND + +unsigned long energest_arch_current_estimate(void); +unsigned short energest_arch_now(void); + +#endif /* __ENERGEST_H__ */ From b1e0906f40d2a1033a1ce3ec34dbc853083359af Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 7 Jul 2008 23:38:46 +0000 Subject: [PATCH 067/146] Added a clock_seconds() function prototype to core/sys/clock.h, that returns seconds in 32 bit format. --- clock.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clock.h b/clock.h index 72bd208ff..966dc4a2d 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.4 2008/02/07 23:04:35 oliverschmidt Exp $ + * $Id: clock.h,v 1.5 2008/07/07 23:38:46 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -96,6 +96,8 @@ void clock_delay(unsigned int); int clock_fine_max(void); unsigned short clock_fine(void); +unsigned long clock_seconds(void); + #endif /* __CLOCK_H__ */ From 3007fcfa99baeaf4337614435eff5ed6a5d04bb4 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 9 Jul 2008 22:14:34 +0000 Subject: [PATCH 068/146] Moved to core/net/rime long ago... --- timesynch.c | 183 ---------------------------------------------------- timesynch.h | 144 ----------------------------------------- 2 files changed, 327 deletions(-) delete mode 100644 timesynch.c delete mode 100644 timesynch.h diff --git a/timesynch.c b/timesynch.c deleted file mode 100644 index adb808bd7..000000000 --- a/timesynch.c +++ /dev/null @@ -1,183 +0,0 @@ -/** - * \addtogroup timesynch - * @{ - */ - - -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: timesynch.c,v 1.5 2008/01/08 07:54:16 adamdunkels Exp $ - */ - -/** - * \file - * A simple time synchronization mechanism - * \author - * Adam Dunkels - */ - -#include "sys/timesynch.h" -#include "net/rime/rimebuf.h" -#include "net/rime.h" -#include "dev/simple-cc2420.h" - -static const struct mac_driver *mac; -static void (* receiver_callback)(const struct mac_driver *); - -#include - -static int authority_level; -static rtimer_clock_t offset; - -/*---------------------------------------------------------------------------*/ -int -timesynch_authority_level(void) -{ - return authority_level; -} -/*---------------------------------------------------------------------------*/ -void -timesynch_set_authority_level(int level) -{ - authority_level = level; -} -/*---------------------------------------------------------------------------*/ -rtimer_clock_t -timesynch_time(void) -{ - return rtimer_arch_now() + offset; -} -/*---------------------------------------------------------------------------*/ -rtimer_clock_t -timesynch_time_to_rtimer(rtimer_clock_t synched_time) -{ - return synched_time - offset; -} -/*---------------------------------------------------------------------------*/ -rtimer_clock_t -timesynch_offset(void) -{ - return offset; -} -/*---------------------------------------------------------------------------*/ -static int -send_packet(void) -{ - return mac->send(); -} -/*---------------------------------------------------------------------------*/ -static void -adjust_offset(rtimer_clock_t authoritative_time, rtimer_clock_t local_time) -{ - offset = offset + authoritative_time - local_time; -} -/*---------------------------------------------------------------------------*/ -static int -read_packet(void) -{ - int len; - - len = mac->read(); - - if(len == 0) { - return 0; - } - - /* We check the authority level of the sender of the incoming - packet. If the sending node has a lower authority level than we - have, we synchronize to the time of the sending node and set our - own authority level to be one more than the sending node. */ - if(simple_cc2420_authority_level_of_sender < authority_level) { - - adjust_offset(simple_cc2420_time_of_departure, - simple_cc2420_time_of_arrival); - if(simple_cc2420_authority_level_of_sender + 1 != authority_level) { - authority_level = simple_cc2420_authority_level_of_sender + 1; - } - - } - - return len; -} -/*---------------------------------------------------------------------------*/ -#if 0 -static void -periodic_authority_increase(void *ptr) -{ - /* XXX the authority level should be increased over time except - for the sink node (which has authority 0). */ -} -#endif -/*---------------------------------------------------------------------------*/ -static void -set_receive_function(void (* recv)(const struct mac_driver *)) -{ - receiver_callback = recv; -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return mac->on(); -} -/*---------------------------------------------------------------------------*/ -static int -off(void) -{ - return mac->off(); -} -/*---------------------------------------------------------------------------*/ -static const struct mac_driver timesynch_driver = { - send_packet, - read_packet, - set_receive_function, - on, - off, -}; -/*---------------------------------------------------------------------------*/ -static void -input_packet(const struct mac_driver *d) -{ - if(receiver_callback) { - receiver_callback(×ynch_driver); - } -} -/*---------------------------------------------------------------------------*/ -const struct mac_driver * -timesynch_init(const struct mac_driver *d) -{ - mac = d; - mac->set_receive_function(input_packet); - mac->on(); - return ×ynch_driver; -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/timesynch.h b/timesynch.h deleted file mode 100644 index e975b8247..000000000 --- a/timesynch.h +++ /dev/null @@ -1,144 +0,0 @@ -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup timesynch Implicit network time synchronization - * @{ - * - * This crude and simple network time synchronization module - * synchronizes clocks of all nodes in a network. The time - * synchronization is implicit in that no explicit time - * synchronization messages are sent: the module relies on the - * underlying network device driver to timestamp all radio messages, - * both outgoing and incoming. The code currently only works on the - * Tmote Sky platform and the simple-cc2420 driver. - * - * Every node has an authority level, which is included in every - * outgoing packet. If a message is received from a node with higher - * authority (lower authority number), the node adjusts its clock - * towards the clock of the sending node. - * - * The timesynch module is implemented as a meta-MAC protocol, so that - * the module is invoked for every incoming packet. - * - */ - -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: timesynch.h,v 1.1 2007/12/16 14:29:56 adamdunkels Exp $ - */ - -/** - * \file - * Header file for a simple time synchronization mechanism - * \author - * Adam Dunkels - */ - -#ifndef __TIMESYNCH_H__ -#define __TIMESYNCH_H__ - -#include "net/mac/mac.h" -#include "sys/rtimer.h" - -/** - * \brief Initialize the timesynch module; should be called during the MAC initialization procedure - * \param r The underlying MAC driver - * \return A pointer to the timesynch module's meta MAC driver - * - * This function initializes the timesynch module. The - * function should be called as part of the MAC - * initialization procedure. - * - */ -const struct mac_driver *timesynch_init(const struct mac_driver *r); - -/** - * \brief Get the current time-synchronized time - * \return The current time-synchronized time - * - * This function returns the current time-synchronized - * time. - * - */ -rtimer_clock_t timesynch_time(void); - -/** - * \brief Get the current time-synchronized rtimer time, suitable for use with the rtimer module - * \return The current time-synchronized rtimer time - * - * This function returns the (local) rtimer-equivalent - * time corresponding to the current time-synchronized - * (global) time. The rtimer-equivalent time is used for - * setting rtimer timers that are synchronized to other - * nodes in the network. - * - */ -rtimer_clock_t timesynch_time_to_rtimer(rtimer_clock_t synched_time); - -/** - * \brief Get the current time-synchronized offset from the rtimer clock, which is used mainly for debugging - * \return The current time-synchronized offset from the rtimer clock - * - * This function returns the current time-synchronized - * offset from the rtimer arch clock. This is mainly - * useful for debugging the timesynch module. - * - */ -rtimer_clock_t timesynch_offset(void); - -/** - * \brief Get the current authority level of the time-synchronized time - * \return The current authority level of the time-synchronized time - * - * This function returns the current authority level of - * the time-synchronized time. A node with a lower - * authority level is defined to have a better notion of - * time than a node with a higher authority - * level. Authority level 0 is best and should be used by - * a sink node that has a connection to an outside, - * "true", clock source. - * - */ -int timesynch_authority_level(void); - -/** - * \brief Set the authority level of the current time - * \param level The authority level - */ -void timesynch_set_authority_level(int level); - -#endif /* __TIMESYNCH_H__ */ - -/** @} */ -/** @} */ From e073b1c56c1a74a43edd32531ee0c6c9974a9c91 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 10 Jul 2008 17:09:32 +0000 Subject: [PATCH 069/146] Added CCIF to make clock_seconds() function name visible for win32 --- clock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clock.h b/clock.h index 966dc4a2d..f06e8a436 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.5 2008/07/07 23:38:46 adamdunkels Exp $ + * $Id: clock.h,v 1.6 2008/07/10 17:09:32 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -96,7 +96,7 @@ void clock_delay(unsigned int); int clock_fine_max(void); unsigned short clock_fine(void); -unsigned long clock_seconds(void); +CCIF unsigned long clock_seconds(void); #endif /* __CLOCK_H__ */ From 42683a5f0082fa31473401f32bbfdf19a0af4511 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 15 Aug 2008 19:16:09 +0000 Subject: [PATCH 070/146] Hardy Griech's timer bugfix: avoid direct comparison for timer values since they may wrap. Instead, use the CLOCK_LT() that works correctly even for wrapped timers. --- clock.h | 13 +++++++++++-- timer.c | 56 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/clock.h b/clock.h index f06e8a436..1fdcb0efa 100644 --- a/clock.h +++ b/clock.h @@ -53,14 +53,23 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.6 2008/07/10 17:09:32 adamdunkels Exp $ + * $Id: clock.h,v 1.7 2008/08/15 19:16:09 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ #include "contiki-conf.h" -#define CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) +/** + * Check if a clock time value is less than another clock time value. + * + * This macro checks if a clock time value is less than another clock + * time value. This macro is needed to correctly handle wrap-around of + * clock time values. + * + */ +#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < \ + ((clock_time_t)(~((clock_time_t)0)) >> 1)) /** * Initialize the clock library. diff --git a/timer.c b/timer.c index 2719834db..064af4b74 100644 --- a/timer.c +++ b/timer.c @@ -12,37 +12,37 @@ /* * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * + * * Author: Adam Dunkels * - * $Id: timer.c,v 1.2 2007/05/27 11:11:28 oliverschmidt Exp $ + * $Id: timer.c,v 1.3 2008/08/15 19:16:09 adamdunkels Exp $ */ #include "contiki-conf.h" @@ -121,7 +121,7 @@ timer_restart(struct timer *t) int timer_expired(struct timer *t) { - return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; + return CLOCK_LT(clock_time(), t->start + t->interval); } /*---------------------------------------------------------------------------*/ From 95bb70eba8439a5ae701e26a229f3dbc05f7f9df Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 21 Sep 2008 08:58:05 +0000 Subject: [PATCH 071/146] Added a timer_remaining() function that returns the time until the timer expires --- timer.c | 18 +++++++++++++++++- timer.h | 4 +++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/timer.c b/timer.c index 064af4b74..5807bc1a6 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.3 2008/08/15 19:16:09 adamdunkels Exp $ + * $Id: timer.c,v 1.4 2008/09/21 08:58:05 adamdunkels Exp $ */ #include "contiki-conf.h" @@ -124,5 +124,21 @@ timer_expired(struct timer *t) return CLOCK_LT(clock_time(), t->start + t->interval); } /*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +clock_time_t +timer_remaining(struct timer *t) +{ + return t->start + t->interval - clock_time(); +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/timer.h b/timer.h index aefd34e48..40f2be80b 100644 --- a/timer.h +++ b/timer.h @@ -69,7 +69,7 @@ * * Author: Adam Dunkels * - * $Id: timer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: timer.h,v 1.2 2008/09/21 08:58:05 adamdunkels Exp $ */ #ifndef __TIMER_H__ #define __TIMER_H__ @@ -93,6 +93,8 @@ void timer_set(struct timer *t, clock_time_t interval); void timer_reset(struct timer *t); void timer_restart(struct timer *t); int timer_expired(struct timer *t); +clock_time_t timer_remaining(struct timer *t); + #endif /* __TIMER_H__ */ From fa30a759a5e3ad6e7d502e8cf1d5060bee332a9d Mon Sep 17 00:00:00 2001 From: joxe Date: Mon, 29 Sep 2008 11:44:37 +0000 Subject: [PATCH 072/146] fixed energest to always add positive values and to use all bits, removed energest arch --- energest.c | 12 ++++++------ energest.h | 25 ++++++++++--------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/energest.c b/energest.c index 60c52d0d4..b7e59c271 100644 --- a/energest.c +++ b/energest.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.c,v 1.1 2008/07/03 23:36:30 adamdunkels Exp $ + * $Id: energest.c,v 1.2 2008/09/29 11:44:37 joxe Exp $ */ /** @@ -45,7 +45,7 @@ int energest_total_count; energest_t energest_total_time[ENERGEST_TYPE_MAX]; -unsigned short energest_current_time[ENERGEST_TYPE_MAX]; +rtimer_clock_t energest_current_time[ENERGEST_TYPE_MAX]; #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVICE_LEVELS]; #endif @@ -74,8 +74,8 @@ energest_type_time(int type) #ifndef ENERGEST_CONF_LEVELDEVICE_LEVELS if(energest_current_mode[type]) { rtimer_clock_t now = RTIMER_NOW(); - energest_total_time[type].current += (unsigned long) - ((signed short)now - (signed short)energest_current_time[type]); + energest_total_time[type].current += (rtimer_clock_t) + (now - energest_current_time[type]); energest_current_time[type] = now; } #endif /* ENERGEST_CONF_LEVELDEVICE_LEVELS */ @@ -107,8 +107,8 @@ energest_flush(void) for(i = 0; i < ENERGEST_TYPE_MAX; i++) { if(energest_current_mode[i]) { now = RTIMER_NOW(); - energest_total_time[i].current += (unsigned long) - ((signed short)now - (signed short)energest_current_time[i]); + energest_total_time[i].current += (rtimer_clock_t) + (now - energest_current_time[i]); energest_current_time[i] = now; } } diff --git a/energest.h b/energest.h index 5327c1212..9b207974c 100644 --- a/energest.h +++ b/energest.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.h,v 1.1 2008/07/03 23:36:30 adamdunkels Exp $ + * $Id: energest.h,v 1.2 2008/09/29 11:44:37 joxe Exp $ */ /** @@ -57,11 +57,11 @@ enum energest_type { ENERGEST_TYPE_LED_RED, ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN, - + ENERGEST_TYPE_SENSORS, ENERGEST_TYPE_SERIAL, - + ENERGEST_TYPE_MAX }; @@ -76,7 +76,7 @@ void energest_flush(void); #if ENERGEST_CONF_ON /*extern int energest_total_count;*/ extern energest_t energest_total_time[ENERGEST_TYPE_MAX]; -extern unsigned short energest_current_time[ENERGEST_TYPE_MAX]; +extern rtimer_clock_t energest_current_time[ENERGEST_TYPE_MAX]; extern unsigned char energest_current_mode[ENERGEST_TYPE_MAX]; #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS @@ -90,16 +90,16 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI } while(0) #define ENERGEST_OFF(type) do { \ - energest_total_time[type].current += (unsigned long)((signed short)RTIMER_NOW() - \ - (signed short)energest_current_time[type]); \ + energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ + energest_current_time[type]); \ energest_current_mode[type] = 0; \ - } while(0) + } while(0) #define ENERGEST_OFF_LEVEL(type,level) do { \ - energest_leveldevice_current_leveltime[level].current += (unsigned long)((signed short)RTIMER_NOW() - \ - (signed short)energest_current_time[type]); \ + energest_leveldevice_current_leveltime[level].current += (rtimer_clock_t)(RTIMER_NOW() - \ + energest_current_time[type]); \ energest_current_mode[type] = 0; \ - } while(0) + } while(0) #else /* ENERGEST_CONF_ON */ @@ -108,9 +108,4 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI #define ENERGEST_OFF_LEVEL(type,level) do { } while(0) #endif /* ENERGEST_CONF_ON */ -#define ENERGEST_SECOND RTIMER_ARCH_SECOND - -unsigned long energest_arch_current_estimate(void); -unsigned short energest_arch_now(void); - #endif /* __ENERGEST_H__ */ From 740e30ca73739fd046abe6c347fb43ac6684229f Mon Sep 17 00:00:00 2001 From: nvt-se Date: Thu, 2 Oct 2008 10:17:48 +0000 Subject: [PATCH 073/146] a timer of seconds --- stimer.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ stimer.h | 99 +++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 stimer.c create mode 100644 stimer.h diff --git a/stimer.c b/stimer.c new file mode 100644 index 000000000..917bc12f2 --- /dev/null +++ b/stimer.c @@ -0,0 +1,147 @@ +/** + * \addtogroup stimer + * @{ + */ + +/** + * \file + * Timer of seconds library implementation. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/* + * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels , Nicolas Tsiftes + * + * $Id: stimer.c,v 1.1 2008/10/02 10:17:48 nvt-se Exp $ + */ + +#include "contiki-conf.h" +#include "sys/clock.h" +#include "sys/stimer.h" + +#define SCLOCK_LT(a, b) ((unsigned long)((a) - (b)) < \ + ((unsigned long)(~((unsigned long)0)) >> 1)) + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function stimer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +stimer_set(struct stimer *t, unsigned long interval) +{ + t->interval = interval; + t->start = clock_seconds(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the stimer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * stimer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa stimer_restart() + */ +void +stimer_reset(struct stimer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the stimer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the stimer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa stimer_reset() + */ +void +stimer_restart(struct stimer *t) +{ + t->start = clock_seconds(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +stimer_expired(struct stimer *t) +{ + return SCLOCK_LT(clock_seconds(), t->start + t->interval); +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +unsigned long +stimer_remaining(struct stimer *t) +{ + return t->start + t->interval - clock_seconds(); +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/stimer.h b/stimer.h new file mode 100644 index 000000000..3d1fc9d3c --- /dev/null +++ b/stimer.h @@ -0,0 +1,99 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup timer Seconds timer library + * + * The stimer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c stimer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The stimer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The stimer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the seconds. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + + +/** + * \file + * Second timer library header file. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/* + * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels , Nicolas Tsiftes + * + * $Id: stimer.h,v 1.1 2008/10/02 10:17:48 nvt-se Exp $ + */ +#ifndef __STIMER_H__ +#define __STIMER_H__ + +#include "sys/clock.h" + +typedef unsigned long clock_second_t; + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with stimer_set() before it can be used. + * + * \hideinitializer + */ +struct stimer { + clock_second_t start; + clock_second_t interval; +}; + +void stimer_set(struct stimer *t, clock_second_t interval); +void stimer_reset(struct stimer *t); +void stimer_restart(struct stimer *t); +int stimer_expired(struct stimer *t); +clock_second_t stimer_remaining(struct stimer *t); + + +#endif /* __STIMER_H__ */ + +/** @} */ +/** @} */ From be109f042964344df2b73fe4736e75f37f827b38 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Thu, 2 Oct 2008 15:04:37 +0000 Subject: [PATCH 074/146] use unsigned long since clock_seconds() returns that. --- stimer.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/stimer.h b/stimer.h index 3d1fc9d3c..98ed234d3 100644 --- a/stimer.h +++ b/stimer.h @@ -64,15 +64,13 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.h,v 1.1 2008/10/02 10:17:48 nvt-se Exp $ + * $Id: stimer.h,v 1.2 2008/10/02 15:04:37 nvt-se Exp $ */ #ifndef __STIMER_H__ #define __STIMER_H__ #include "sys/clock.h" -typedef unsigned long clock_second_t; - /** * A timer. * @@ -82,15 +80,15 @@ typedef unsigned long clock_second_t; * \hideinitializer */ struct stimer { - clock_second_t start; - clock_second_t interval; + unsigned long start; + unsigned long interval; }; -void stimer_set(struct stimer *t, clock_second_t interval); +void stimer_set(struct stimer *t, unsigned long interval); void stimer_reset(struct stimer *t); void stimer_restart(struct stimer *t); int stimer_expired(struct stimer *t); -clock_second_t stimer_remaining(struct stimer *t); +unsigned long stimer_remaining(struct stimer *t); #endif /* __STIMER_H__ */ From 928147c6593223ae6590518a68d61f8d8c1af2b5 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Tue, 14 Oct 2008 12:46:39 +0000 Subject: [PATCH 075/146] fixed documentation typos. --- dsc.h | 4 ++-- energest.h | 4 ++-- lc-switch.h | 6 +++--- loader.h | 4 ++-- mt.h | 12 ++++++------ process.h | 8 ++++---- pt-sem.h | 4 ++-- pt.h | 4 ++-- rtimer.h | 6 +++--- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/dsc.h b/dsc.h index 3a688709d..29892343e 100644 --- a/dsc.h +++ b/dsc.h @@ -56,7 +56,7 @@ * * This file is part of the Contiki desktop environment * - * $Id: dsc.h,v 1.3 2007/08/30 14:39:17 matsutsuka Exp $ + * $Id: dsc.h,v 1.4 2008/10/14 12:46:39 nvt-se Exp $ * */ #ifndef __DSC_H__ @@ -96,7 +96,7 @@ struct dsc { }; /** - * Intantiating macro for the DSC structure. + * Instantiating macro for the DSC structure. * * \param dscname The name of the C variable which is to contain the * DSC. diff --git a/energest.h b/energest.h index 9b207974c..ff0339887 100644 --- a/energest.h +++ b/energest.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.h,v 1.2 2008/09/29 11:44:37 joxe Exp $ + * $Id: energest.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -44,7 +44,7 @@ #include "sys/rtimer.h" typedef struct { - /* unsigned long cummulative[2];*/ + /* unsigned long cumulative[2];*/ unsigned long current; } energest_t; diff --git a/lc-switch.h b/lc-switch.h index f9542c0f5..6939004af 100644 --- a/lc-switch.h +++ b/lc-switch.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: lc-switch.h,v 1.2 2007/03/28 19:52:50 adamdunkels Exp $ + * $Id: lc-switch.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -40,14 +40,14 @@ /** * \file - * Implementation of local continuations based on switch() statment + * Implementation of local continuations based on switch() statement * \author Adam Dunkels * * This implementation of local continuations uses the C switch() * statement to resume execution of a function somewhere inside the * function's body. The implementation is based on the fact that * switch() statements are able to jump directly into the bodies of - * control structures such as if() or while() statmenets. + * control structures such as if() or while() statements. * * This implementation borrows heavily from Simon Tatham's coroutines * implementation in C: diff --git a/loader.h b/loader.h index cff06e849..88e4762b0 100644 --- a/loader.h +++ b/loader.h @@ -49,7 +49,7 @@ * * This file is part of the Contiki desktop OS * - * $Id: loader.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: loader.h,v 1.2 2008/10/14 12:46:39 nvt-se Exp $ * */ #ifndef __LOADER_H__ @@ -76,7 +76,7 @@ * Load and execute a program. * * This macro is used for loading and executing a program, and - * requires support from the architecture dependant code. The actual + * requires support from the architecture dependent code. The actual * program loading is made by architecture specific functions. * * \note A program loaded with LOADER_LOAD() must call the diff --git a/mt.h b/mt.h index 2724adeed..29dbe6ef4 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.5 2008/05/27 14:00:09 adamdunkels Exp $ + * $Id: mt.h,v 1.6 2008/10/14 12:46:39 nvt-se Exp $ */ /** \addtogroup sys @@ -43,7 +43,7 @@ * The event driven Contiki kernel does not provide multi-threading * by itself - instead, preemptive multi-threading is implemented * as a library that optionally can be linked with applications. This - * library constists of two parts: a platform independent part, which is + * library consists of two parts: a platform independent part, which is * the same for all platforms on which Contiki runs, and a platform * specific part, which must be implemented specifically for the * platform that the multi-threading library should run. @@ -56,7 +56,7 @@ * @{ * * The Contiki multi-threading library requires some architecture - * specific support for seting up and switching stacks. This support + * specific support for setting up and switching stacks. This support * requires four stack manipulation functions to be implemented: * mtarch_start(), which sets up the stack frame for a new thread, * mtarch_exec(), which switches in the stack of a thread, @@ -66,9 +66,9 @@ * (if any) must be implemented: mtarch_pstart() and mtarch_pstop(). * If no preemption is used, these functions can be implemented as * empty functions. Finally, the function mtarch_init() is called by - * mt_init(), and can be used for initalization of timer interrupts, + * mt_init(), and can be used for initialization of timer interrupts, * or any other mechanisms required for correct operation of the - * architecture specific support funcions while mtarch_remove() is + * architecture specific support functions while mtarch_remove() is * called by mt_remove() to clean up those resources. * */ @@ -101,7 +101,7 @@ struct mtarch_thread; * This function is implemented by the architecture specific functions * for the multi-thread library and is called by the mt_init() * function as part of the initialization of the library. The - * mtarch_init() function can be used for, e.g., starting preemtion + * mtarch_init() function can be used for, e.g., starting preemption * timers or other architecture specific mechanisms required for the * operation of the library. */ diff --git a/process.h b/process.h index 0d2639b46..f1bea6aaf 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.15 2008/02/07 23:04:35 oliverschmidt Exp $ + * @(#)$Id: process.h,v 1.16 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -257,7 +257,7 @@ typedef unsigned char process_num_events_t; /** @} */ /** - * \name Process declaration and definion + * \name Process declaration and definition * @{ */ @@ -294,7 +294,7 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ * and a human readable string name, which is used when debugging. * * \param name The variable name of the process structure. - * \param strname The string repressentation of the process' name. + * \param strname The string representation of the process' name. * * \hideinitializer */ @@ -340,7 +340,7 @@ CCIF void process_start(struct process *p, const char *arg); * * \param ev The event to be posted. * - * \param data The auxillary data to be sent with the event + * \param data The auxiliary data to be sent with the event * * \param p The process to which the event should be posted, or * PROCESS_BROADCAST if the event should be posted to all processes. diff --git a/pt-sem.h b/pt-sem.h index 042c54b1d..01234ff36 100644 --- a/pt-sem.h +++ b/pt-sem.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: pt-sem.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * $Id: pt-sem.h,v 1.2 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -48,7 +48,7 @@ * checks the semaphore counter and blocks the thread if the counter * is zero. The "signal" operation increases the semaphore counter but * does not block. If another thread has blocked waiting for the - * semaphore that is signalled, the blocked thread will become + * semaphore that is signaled, the blocked thread will become * runnable again. * * Semaphores can be used to implement other, more structured, diff --git a/pt.h b/pt.h index 1c3efa275..3f1467c62 100644 --- a/pt.h +++ b/pt.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: pt.h,v 1.2 2006/09/26 20:57:58 adamdunkels Exp $ + * $Id: pt.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -259,7 +259,7 @@ struct pt { /** * Schedule a protothread. * - * This function shedules a protothread. The return value of the + * This function schedules a protothread. The return value of the * function is non-zero if the protothread is running or zero if the * protothread has exited. * diff --git a/rtimer.h b/rtimer.h index 5223da260..366cef210 100644 --- a/rtimer.h +++ b/rtimer.h @@ -2,7 +2,7 @@ * \defgroup rt Real-time task scheduling * * The real-time module handles the scheduling and execution of - * real-time tasks (with predictible execution times). + * real-time tasks (with predictable execution times). * * @{ */ @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.6 2007/10/23 20:33:19 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.7 2008/10/14 12:46:39 nvt-se Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -66,7 +66,7 @@ struct rtimer; typedef void (* rtimer_callback_t)(struct rtimer *t, void *ptr); /** - * \brief Repressentation of a real-time task + * \brief Representation of a real-time task * * This structure represents a real-time task and is used * by the real-time module and the architecture specific From a7e46fcc52760b15fa3a7613bc9a33de0ce95ca8 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Tue, 14 Oct 2008 13:27:55 +0000 Subject: [PATCH 076/146] added parameter descriptions --- rtimer.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtimer.h b/rtimer.h index 366cef210..49caeab12 100644 --- a/rtimer.h +++ b/rtimer.h @@ -45,7 +45,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.7 2008/10/14 12:46:39 nvt-se Exp $ + * @(#)$Id: rtimer.h,v 1.8 2008/10/14 13:27:55 nvt-se Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -89,14 +89,17 @@ enum { * \brief Post a real-time task. * \param task A pointer to the task variable previously declared with RTIMER_TASK(). * \param time The time when the task is to be executed. + * \param duration Unused argument. + * \param func A function to be called when the task is executed. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. * \return Non-zero (true) if the task could be scheduled, zero * (false) if the task could not be scheduled. * - * This function schedules a real-time task a specified + * This function schedules a real-time task at a specified * time in the future. * */ -int rtimer_set(struct rtimer *t, rtimer_clock_t time, +int rtimer_set(struct rtimer *task, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr); /** From 0de5673d49b652d41c807932f0f81e0159e4e706 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Wed, 5 Nov 2008 19:34:36 +0000 Subject: [PATCH 077/146] corrected macro name --- stimer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stimer.c b/stimer.c index 917bc12f2..b300afb3d 100644 --- a/stimer.c +++ b/stimer.c @@ -42,15 +42,15 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.c,v 1.1 2008/10/02 10:17:48 nvt-se Exp $ + * $Id: stimer.c,v 1.2 2008/11/05 19:34:36 nvt-se Exp $ */ #include "contiki-conf.h" #include "sys/clock.h" #include "sys/stimer.h" -#define SCLOCK_LT(a, b) ((unsigned long)((a) - (b)) < \ - ((unsigned long)(~((unsigned long)0)) >> 1)) +#define SCLOCK_GEQ(a, b) ((unsigned long)((a) - (b)) < \ + ((unsigned long)(~((unsigned long)0)) >> 1)) /*---------------------------------------------------------------------------*/ /** @@ -124,7 +124,7 @@ stimer_restart(struct stimer *t) int stimer_expired(struct stimer *t) { - return SCLOCK_LT(clock_seconds(), t->start + t->interval); + return SCLOCK_GEQ(clock_seconds(), t->start + t->interval); } /*---------------------------------------------------------------------------*/ /** From 942309161bd256d6e17a78767e03d8e78d74cf4d Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 23 Jan 2009 16:13:57 +0000 Subject: [PATCH 078/146] Reverted CLOCK_LT to the previous version, which upon closer examination seems to be correct. The new version did not work correctly on the minimal-net platform. --- clock.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clock.h b/clock.h index 1fdcb0efa..11c5c3d74 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.7 2008/08/15 19:16:09 adamdunkels Exp $ + * $Id: clock.h,v 1.8 2009/01/23 16:13:57 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -68,8 +68,7 @@ * clock time values. * */ -#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < \ - ((clock_time_t)(~((clock_time_t)0)) >> 1)) +#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) /** * Initialize the clock library. From eaabecb46ef4f110252f7a7759c0722a3aea5478 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 23 Jan 2009 17:16:38 +0000 Subject: [PATCH 079/146] Fixed missing parenthesis --- clock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clock.h b/clock.h index 11c5c3d74..47f87959e 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.8 2009/01/23 16:13:57 adamdunkels Exp $ + * $Id: clock.h,v 1.9 2009/01/23 17:16:38 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -68,7 +68,7 @@ * clock time values. * */ -#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) +#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b))) /** * Initialize the clock library. From 40a62e6f44bd761096d89488682e9a328a94e85b Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 24 Jan 2009 10:54:44 +0000 Subject: [PATCH 080/146] Fixed the CLOCK_LT again. The previous revert was incorrect: the conditional was missing due to a bad copy-and-paste on my part :( --- clock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clock.h b/clock.h index 47f87959e..93c451324 100644 --- a/clock.h +++ b/clock.h @@ -53,7 +53,7 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.9 2009/01/23 17:16:38 adamdunkels Exp $ + * $Id: clock.h,v 1.10 2009/01/24 10:54:44 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ @@ -68,7 +68,7 @@ * clock time values. * */ -#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b))) +#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < 0) /** * Initialize the clock library. From 68922cb98774935419b22b377eb457ed87341081 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sat, 24 Jan 2009 15:20:11 +0000 Subject: [PATCH 081/146] Reverted the timer_expired() back to the previous version (which should be correct). Removed the definition of CLOCK_LT() because it seems to only cause problems. --- clock.h | 6 ++++-- timer.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clock.h b/clock.h index 93c451324..b14db6112 100644 --- a/clock.h +++ b/clock.h @@ -53,13 +53,14 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.10 2009/01/24 10:54:44 adamdunkels Exp $ + * $Id: clock.h,v 1.11 2009/01/24 15:20:11 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ #include "contiki-conf.h" +#if 0 /* XXX problems with signedness and use in timer_expired(). #if:ed it out for now. */ /** * Check if a clock time value is less than another clock time value. * @@ -68,7 +69,8 @@ * clock time values. * */ -#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < 0) +#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < ((clock_time_t)(~((clock_time_t)0)) >> 1)) +#endif /* 0 */ /** * Initialize the clock library. diff --git a/timer.c b/timer.c index 5807bc1a6..821f2a2bc 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.4 2008/09/21 08:58:05 adamdunkels Exp $ + * $Id: timer.c,v 1.5 2009/01/24 15:20:11 adamdunkels Exp $ */ #include "contiki-conf.h" @@ -121,7 +121,7 @@ timer_restart(struct timer *t) int timer_expired(struct timer *t) { - return CLOCK_LT(clock_time(), t->start + t->interval); + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; } /*---------------------------------------------------------------------------*/ /** From 5f032aa8b0a49c758395e5b8a2f080e9867fa197 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 20 Feb 2009 21:24:17 +0000 Subject: [PATCH 082/146] Removed PROCESS_ZOMBIE code, which does not compile with sdcc, added some optional debugging printouts --- process.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/process.c b/process.c index 5f5655157..3b349a7e9 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.8 2008/01/24 21:00:51 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.9 2009/02/20 21:24:17 adamdunkels Exp $ */ /** @@ -161,13 +161,14 @@ exit_process(struct process *p, struct process *fromprocess) } } } - + +#if 0 { int n; int i = fevent; for(n = nevents; n > 0; n--) { if(events[i].p == p) { - events[i].p = PROCESS_ZOMBIE; + events[i].p = (struct process *)PROCESS_ZOMBIE; #if DEBUG printf("soft panic: exiting process has remaining event 0x%x\n", events[i].ev); @@ -176,6 +177,7 @@ exit_process(struct process *p, struct process *fromprocess) i = (i + 1) % PROCESS_CONF_NUMEVENTS; } } +#endif /* 0 */ process_current = old_current; } /*---------------------------------------------------------------------------*/ @@ -291,8 +293,10 @@ do_event(void) } call_process(p, ev, data); } - } else if(receiver == PROCESS_ZOMBIE) { +#if 0 + } else if(receiver == (struct process *)PROCESS_ZOMBIE) { /* This process has exited. */ +#endif /* 0 */ } else { /* This is not a broadcast event, so we deliver it to the specified process. */ @@ -332,6 +336,15 @@ int process_post(struct process *p, process_event_t ev, process_data_t data) { static unsigned char snum; + + if(PROCESS_CURRENT() == NULL) { + PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", + ev, p->name, nevents); + } else { + PRINTF("process_post: Process '%s' posts event %d to process '%s', nevents %d\n", + PROCESS_CURRENT()->name, ev, + p == PROCESS_BROADCAST? "": p->name, nevents); + } if(nevents == PROCESS_CONF_NUMEVENTS) { #if DEBUG From 2a44b80bcf16e6708e59bbdc64fcf2cc69736432 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 1 Mar 2009 09:31:43 +0000 Subject: [PATCH 083/146] Documentation bugfix: rtimer should be in sys group and the stimer library should have the correct documetation group --- rtimer.h | 6 +++++- stimer.h | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/rtimer.h b/rtimer.h index 49caeab12..3e1a56b1d 100644 --- a/rtimer.h +++ b/rtimer.h @@ -1,3 +1,6 @@ +/** \addtogroup sys + * @{ */ + /** * \defgroup rt Real-time task scheduling * @@ -45,7 +48,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.8 2008/10/14 13:27:55 nvt-se Exp $ + * @(#)$Id: rtimer.h,v 1.9 2009/03/01 09:31:43 adamdunkels Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ @@ -147,3 +150,4 @@ void rtimer_arch_schedule(rtimer_clock_t t); #endif /* __RTIMER_H__ */ /** @} */ +/** @} */ diff --git a/stimer.h b/stimer.h index 98ed234d3..11bd1dee6 100644 --- a/stimer.h +++ b/stimer.h @@ -2,7 +2,7 @@ * @{ */ /** - * \defgroup timer Seconds timer library + * \defgroup stimer Seconds timer library * * The stimer library provides functions for setting, resetting and * restarting timers, and for checking if a timer has expired. An @@ -64,7 +64,7 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.h,v 1.2 2008/10/02 15:04:37 nvt-se Exp $ + * $Id: stimer.h,v 1.3 2009/03/01 09:31:43 adamdunkels Exp $ */ #ifndef __STIMER_H__ #define __STIMER_H__ From 926fb6306269e6088eff027e9e8ea0ff86576618 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Sun, 1 Mar 2009 20:32:03 +0000 Subject: [PATCH 084/146] Communication power accounting: this module keeps track of the energy expenditure of individial communication activities, such as transmission or reception of individual packets or idle listening. --- compower.c | 95 +++++++++++++++++++++++++++++++++++++ compower.h | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 compower.c create mode 100644 compower.h diff --git a/compower.c b/compower.c new file mode 100644 index 000000000..5fb02dea8 --- /dev/null +++ b/compower.c @@ -0,0 +1,95 @@ +/** + * \addtogroup compower + * @{ + */ + +/* + * Copyright (c) 2009, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: compower.c,v 1.1 2009/03/01 20:32:03 adamdunkels Exp $ + */ + +/** + * \file + * Communication power accounting module + * \author + * Adam Dunkels + */ + +#include "contiki-conf.h" +#include "sys/energest.h" +#include "sys/compower.h" +#include "net/rime/rimebuf.h" + +struct compower_activity compower_idle_activity; + +/*---------------------------------------------------------------------------*/ +void +compower_init(void) +{ + compower_clear(&compower_idle_activity); +} +/*---------------------------------------------------------------------------*/ +void +compower_accumulate(struct compower_activity *e) +{ + static uint32_t last_listen, last_transmit; + uint32_t listen, transmit; + + listen = energest_type_time(ENERGEST_TYPE_LISTEN); + e->listen += listen - last_listen; + last_listen = listen; + + transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT); + e->transmit += transmit - last_transmit; + last_transmit = transmit; +} +/*---------------------------------------------------------------------------*/ +void +compower_clear(struct compower_activity *e) +{ + e->listen = e->transmit = 0; +} +/*---------------------------------------------------------------------------*/ +void +compower_attrconv(struct compower_activity *e) +{ + rimebuf_set_attr(RIMEBUF_ATTR_LISTEN_ENERGY, e->listen); + rimebuf_set_attr(RIMEBUF_ATTR_TRANSMIT_ENERGY, e->transmit); +} +/*---------------------------------------------------------------------------*/ +void +compower_accumulate_attrs(struct compower_activity *e) +{ + e->listen += rimebuf_attr(RIMEBUF_ATTR_LISTEN_ENERGY); + e->transmit += rimebuf_attr(RIMEBUF_ATTR_TRANSMIT_ENERGY); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/compower.h b/compower.h new file mode 100644 index 000000000..007e0dbba --- /dev/null +++ b/compower.h @@ -0,0 +1,136 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup compower Communication power accounting + * @{ + * + * The compower module accumulates power consumption information and + * attributes it to communication activities. Examples of + * communication activities are packet transmission, packet reception, + * and idle listening. + * + */ + +/* + * Copyright (c) 2009, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: compower.h,v 1.1 2009/03/01 20:32:03 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the communication power accounting module + * \author + * Adam Dunkels + */ + +#ifndef __COMPOWER_H__ +#define __COMPOWER_H__ + +/** + * \brief An activity record that contains power consumption information for a specific communication activity. + * + * This is a structure that holds power information about + * a communication activity. It is an opaque structure + * with no user-visible elements. + */ +struct compower_activity { + uint32_t listen, transmit; +}; + +/** + * \brief The default idle communication activity. + * + * This is the idle communication activity, to which all + * energy that is not possible to attribute to individual + * packets, is attributed. Examples include idle listening + * for incoming packets and MAC-level beacon + * transmissions. + */ +extern struct compower_activity compower_idle_activity; + +/** + * \brief Initialize the communication power accounting module. + * + * This function initializes the communication power + * accounting module. The function is called by the system + * during boot-up. + */ +void compower_init(void); + +/** + * \brief Accumulate power contumption for a communication activity + * \param a A pointer to an activity structure. + * + * This function accumulates power consumption information + * for a communication activity. The function typically is + * called by a power-saving MAC protocol when the radio is + * switched off, or when a packet is received or + * transmitted. + * + */ +void compower_accumulate(struct compower_activity *a); + +/** + * \brief Clear power consumption information for a communication activity + * \param a A pointer to an activity structure. + * + * This function clears any power contumption information + * that has previously been accumulated in an activity + * structure. + * + */ +void compower_clear(struct compower_activity *a); + +/** + * \brief Convert power contumption information to packet attributes + * \param a A pointer to an activity structure. + * + * This function converts accumulated power consumption + * information for a communication activity to packet + * attributes (see \ref rimebufattr "packet attributes"). + */ +void compower_attrconv(struct compower_activity *a); + +/** + * \brief Accumulate power contumption for a communication activity based on energy data in packet attributes + * \param a A pointer to an activity structure. + * + * This function accumulates power consumption information + * for a communication activity from packet attributes + * (see \ref rimebufattr "packet attributes"). + */ +void compower_accumulate_attrs(struct compower_activity *a); + +#endif /* __COMPOWER_H__ */ + +/** @} */ +/** @} */ From 9052734389e035890ccf67614baabe3862c1110e Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 2 Mar 2009 22:00:41 +0000 Subject: [PATCH 085/146] Changed listen and transmit energy attributes so that they are named _TIME rather than _ENERGY, to indicate that they contain the time during which the radio was switched on and not the energy --- compower.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compower.c b/compower.c index 5fb02dea8..0d203a46f 100644 --- a/compower.c +++ b/compower.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.c,v 1.1 2009/03/01 20:32:03 adamdunkels Exp $ + * $Id: compower.c,v 1.2 2009/03/02 22:00:41 adamdunkels Exp $ */ /** @@ -81,15 +81,15 @@ compower_clear(struct compower_activity *e) void compower_attrconv(struct compower_activity *e) { - rimebuf_set_attr(RIMEBUF_ATTR_LISTEN_ENERGY, e->listen); - rimebuf_set_attr(RIMEBUF_ATTR_TRANSMIT_ENERGY, e->transmit); + rimebuf_set_attr(RIMEBUF_ATTR_LISTEN_TIME, e->listen); + rimebuf_set_attr(RIMEBUF_ATTR_TRANSMIT_TIME, e->transmit); } /*---------------------------------------------------------------------------*/ void compower_accumulate_attrs(struct compower_activity *e) { - e->listen += rimebuf_attr(RIMEBUF_ATTR_LISTEN_ENERGY); - e->transmit += rimebuf_attr(RIMEBUF_ATTR_TRANSMIT_ENERGY); + e->listen += rimebuf_attr(RIMEBUF_ATTR_LISTEN_TIME); + e->transmit += rimebuf_attr(RIMEBUF_ATTR_TRANSMIT_TIME); } /*---------------------------------------------------------------------------*/ /** @} */ From 82cff7aaddb50a9b64a0a327348dcd4f06be4c31 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Thu, 12 Mar 2009 21:58:20 +0000 Subject: [PATCH 086/146] Renamed the rimebuf module to packetbuf to signal that the module is used outside of a pure Rime context (e.g., the sicslowpan code uses it). --- compower.c | 12 ++++++------ compower.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compower.c b/compower.c index 0d203a46f..e0e4a8f65 100644 --- a/compower.c +++ b/compower.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.c,v 1.2 2009/03/02 22:00:41 adamdunkels Exp $ + * $Id: compower.c,v 1.3 2009/03/12 21:58:21 adamdunkels Exp $ */ /** @@ -46,7 +46,7 @@ #include "contiki-conf.h" #include "sys/energest.h" #include "sys/compower.h" -#include "net/rime/rimebuf.h" +#include "net/rime/packetbuf.h" struct compower_activity compower_idle_activity; @@ -81,15 +81,15 @@ compower_clear(struct compower_activity *e) void compower_attrconv(struct compower_activity *e) { - rimebuf_set_attr(RIMEBUF_ATTR_LISTEN_TIME, e->listen); - rimebuf_set_attr(RIMEBUF_ATTR_TRANSMIT_TIME, e->transmit); + packetbuf_set_attr(PACKETBUF_ATTR_LISTEN_TIME, e->listen); + packetbuf_set_attr(PACKETBUF_ATTR_TRANSMIT_TIME, e->transmit); } /*---------------------------------------------------------------------------*/ void compower_accumulate_attrs(struct compower_activity *e) { - e->listen += rimebuf_attr(RIMEBUF_ATTR_LISTEN_TIME); - e->transmit += rimebuf_attr(RIMEBUF_ATTR_TRANSMIT_TIME); + e->listen += packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME); + e->transmit += packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/compower.h b/compower.h index 007e0dbba..b5797a055 100644 --- a/compower.h +++ b/compower.h @@ -42,7 +42,7 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.h,v 1.1 2009/03/01 20:32:03 adamdunkels Exp $ + * $Id: compower.h,v 1.2 2009/03/12 21:58:21 adamdunkels Exp $ */ /** @@ -116,7 +116,7 @@ void compower_clear(struct compower_activity *a); * * This function converts accumulated power consumption * information for a communication activity to packet - * attributes (see \ref rimebufattr "packet attributes"). + * attributes (see \ref packetbufattr "packet attributes"). */ void compower_attrconv(struct compower_activity *a); @@ -126,7 +126,7 @@ void compower_attrconv(struct compower_activity *a); * * This function accumulates power consumption information * for a communication activity from packet attributes - * (see \ref rimebufattr "packet attributes"). + * (see \ref packetbufattr "packet attributes"). */ void compower_accumulate_attrs(struct compower_activity *a); From 2626fadcb7c1c8e9b4b8b446b4d1cbed3acfad79 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Mon, 11 May 2009 15:26:24 +0000 Subject: [PATCH 087/146] Added flash reads and writes to energest. --- energest.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/energest.h b/energest.h index ff0339887..c453755fe 100644 --- a/energest.h +++ b/energest.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ + * $Id: energest.h,v 1.4 2009/05/11 15:26:24 nvt-se Exp $ */ /** @@ -58,6 +58,9 @@ enum energest_type { ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN, + ENERGEST_TYPE_FLASH_READ, + ENERGEST_TYPE_FLASH_WRITE, + ENERGEST_TYPE_SENSORS, ENERGEST_TYPE_SERIAL, From 954d802cafc6f362ee242204eefda7c6fd844974 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Thu, 3 Sep 2009 12:57:57 +0000 Subject: [PATCH 088/146] removed unused state codes and unused printf statements --- mt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/mt.c b/mt.c index 367392960..bf3bd46e4 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.6 2007/05/22 20:58:14 adamdunkels Exp $ + * $Id: mt.c,v 1.7 2009/09/03 12:57:58 nvt-se Exp $ */ /** @@ -49,8 +49,6 @@ #define MT_STATE_READY 1 #define MT_STATE_RUNNING 2 -#define MT_STATE_WAITING 3 -#define MT_STATE_PEEK 4 #define MT_STATE_EXITED 5 static struct mt_thread *current; @@ -81,13 +79,11 @@ mt_start(struct mt_thread *thread, void (* function)(void *), void *data) void mt_exec(struct mt_thread *thread) { - if(thread->state == MT_STATE_READY || - thread->state == MT_STATE_PEEK) { + if(thread->state == MT_STATE_READY) { thread->state = MT_STATE_RUNNING; current = thread; /* Switch context to the thread. The function call will not return until the the thread has yielded, or is preempted. */ - /*printf("swtis\n");*/ mtarch_exec(&thread->thread); } } From b44e4fa9e838aa7d1e367b5eae8d10d0b27829e6 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 9 Sep 2009 21:10:35 +0000 Subject: [PATCH 089/146] Fixed compiler warning --- timetable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/timetable.c b/timetable.c index 100f024d0..3187e5102 100644 --- a/timetable.c +++ b/timetable.c @@ -28,16 +28,16 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.c,v 1.2 2008/02/28 22:43:40 oliverschmidt Exp $ + * $Id: timetable.c,v 1.3 2009/09/09 21:10:35 adamdunkels Exp $ */ /** * \file - * A brief description of what this file is. + * Implementation of timetable, a data structure containing timestamps for events * \author * Adam Dunkels */ - +#include "sys/clock.h" #include "sys/timetable.h" #include From db54b53b8c18e8b341ea776391f1a7c1a5a46188 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 20 Oct 2009 20:19:27 +0000 Subject: [PATCH 090/146] Bugfix: attribute energy expenditure to a device only if the device was actually switched on --- energest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/energest.h b/energest.h index c453755fe..8929b3547 100644 --- a/energest.h +++ b/energest.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.h,v 1.4 2009/05/11 15:26:24 nvt-se Exp $ + * $Id: energest.h,v 1.5 2009/10/20 20:19:27 adamdunkels Exp $ */ /** @@ -92,7 +92,7 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_mode[type] = 1; \ } while(0) -#define ENERGEST_OFF(type) do { \ +#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ energest_current_time[type]); \ energest_current_mode[type] = 0; \ From fa57bbba83594c64352f3eedd5a51dbc487571d1 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 8 Dec 2009 23:55:17 +0000 Subject: [PATCH 091/146] There were many bugs in the rtimer code, particularly one that made only one rtimer at a time work. We have a new rtimer system that we're testing, but in the meantime, I rewrote the rtimer code to explicitly support only one rtimer. Makes the code significantly simpler (and fixes a bug that was very hard to track down). --- rtimer.c | 103 ++++++++++--------------------------------------------- 1 file changed, 18 insertions(+), 85 deletions(-) diff --git a/rtimer.c b/rtimer.c index 3430c4b71..fd63eacab 100644 --- a/rtimer.c +++ b/rtimer.c @@ -42,7 +42,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.5 2007/10/23 20:33:19 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.6 2009/12/08 23:55:17 adamdunkels Exp $ */ #include "sys/rtimer.h" @@ -51,7 +51,7 @@ #ifdef RTIMER_CONF_NUM #define LIST_SIZE RTIMER_CONF_NUM #else -#define LIST_SIZE 4 +#define LIST_SIZE 8 #endif static struct rtimer *rtimers[LIST_SIZE]; @@ -65,6 +65,8 @@ static u8_t next, firstempty; #define PRINTF(...) #endif +static struct rtimer *next_rtimer; + /*---------------------------------------------------------------------------*/ void rtimer_init(void) @@ -79,108 +81,39 @@ rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr) { - int i; + int first = 0; PRINTF("rtimer_set time %d\n", time); + if(next_rtimer == NULL) { + first = 1; + } + rtimer->func = func; rtimer->ptr = ptr; - - /* Check if rtimer queue is full. */ - if(firstempty == (next - 1) % LIST_SIZE) { - PRINTF("rtimer_set: next %d firstempty %d full\n", next, firstempty); - return RTIMER_ERR_FULL; - } - - /* Check if it is possible to run this rtimer at the requested - time. */ - for(i = next; i != firstempty; - i = (i + 1) % LIST_SIZE) { - if(rtimers[i] == rtimer) { - /* Check if timer is already scheduled. If so, we do not - schedule it again. */ - return RTIMER_ERR_ALREADY_SCHEDULED; - - } - /* XXX: should check a range of time not just the same precise - moment. */ - if(rtimers[i]->time == time) { - PRINTF("rtimer_set: next %d firstempty %d time %d == %d\n", - next, firstempty, rtimers[i]->time, time); - return RTIMER_ERR_TIME; - } - } - /* Put the rtimer at the end of the rtimer list. */ rtimer->time = time; - rtimers[firstempty] = rtimer; - PRINTF("rtimer_post: putting rtimer %p as %d\n", rtimer, firstempty); - - firstempty = (firstempty + 1) % LIST_SIZE; + next_rtimer = rtimer; - /* PRINTF("rtimer_post: next %d firstempty %d scheduling soon\n", - next, firstempty);*/ - - /* Check if this is the first rtimer on the list. If so, we need to - run the rtimer_arch_schedule() function to get the ball rolling. */ - if(firstempty == (next + 1) % LIST_SIZE) { - - PRINTF("rtimer_set scheduling %d %p (%d)\n", - next, rtimers[next], rtimers[next]->time); - rtimer_arch_schedule(rtimers[next]->time); + if(first == 1) { + rtimer_arch_schedule(time); } - return RTIMER_OK; } /*---------------------------------------------------------------------------*/ void rtimer_run_next(void) { - int i, n; struct rtimer *t; - - /* Do not run timer if list is empty. */ - if(next == firstempty) { + if(next_rtimer == NULL) { return; } - - t = rtimers[next]; - - /* Increase the pointer to the next rtimer. */ - next = (next + 1) % LIST_SIZE; - - /* Run the rtimer. */ - PRINTF("rtimer_run_next running %p\n", t); + t = next_rtimer; + next_rtimer = NULL; t->func(t, t->ptr); - - if(next == firstempty) { - PRINTF("rtimer_run_next: empty rtimer list\n"); - /* The list is empty, no more rtimers to schedule. */ - return; - } - - /* Find the next rtimer to run. */ - n = next; - for(i = next; i != firstempty; i = (i + 1) % LIST_SIZE) { - PRINTF("rtimer_run_next checking %p (%d) against %p (%d)\n", - rtimers[i], rtimers[i]->time, - rtimers[n], rtimers[n]->time); - if(RTIMER_CLOCK_LT(rtimers[i]->time, rtimers[n]->time)) { - n = i; - } + if(next_rtimer != NULL) { + rtimer_arch_schedule(next_rtimer->time); } - - PRINTF("rtimer_run_next next rtimer is %d %p (%d)\n", - n, rtimers[n], rtimers[n]->time); - - /* Put the next rtimer first in the rtimer list. */ - t = rtimers[next]; - rtimers[next] = rtimers[n]; - rtimers[n] = t; - - PRINTF("rtimer_run_next scheduling %d %p (%d)\n", - next, rtimers[next], rtimers[next]->time); - - rtimer_arch_schedule(rtimers[next]->time); + return; } /*---------------------------------------------------------------------------*/ From 4f4a1fff3c8ed81f79973ccae6d2230ad7da89c5 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 19 Jan 2010 13:08:24 +0000 Subject: [PATCH 092/146] Remove compiler warnings --- rtimer.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/rtimer.c b/rtimer.c index fd63eacab..eb92625d6 100644 --- a/rtimer.c +++ b/rtimer.c @@ -42,21 +42,12 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.6 2009/12/08 23:55:17 adamdunkels Exp $ + * @(#)$Id: rtimer.c,v 1.7 2010/01/19 13:08:24 adamdunkels Exp $ */ #include "sys/rtimer.h" #include "contiki.h" -#ifdef RTIMER_CONF_NUM -#define LIST_SIZE RTIMER_CONF_NUM -#else -#define LIST_SIZE 8 -#endif - -static struct rtimer *rtimers[LIST_SIZE]; -static u8_t next, firstempty; - #define DEBUG 0 #if DEBUG #include @@ -71,8 +62,6 @@ static struct rtimer *next_rtimer; void rtimer_init(void) { - next = 0; - firstempty = 0; rtimer_arch_init(); } /*---------------------------------------------------------------------------*/ From f5b4cca4ec0a44787269f91194ee111272475e12 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 2 Feb 2010 21:13:27 +0000 Subject: [PATCH 093/146] Removed unused code; a number of fixed by Anthony Asterisk --- process.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/process.c b/process.c index 3b349a7e9..284796d9c 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.9 2009/02/20 21:24:17 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.10 2010/02/02 21:13:27 adamdunkels Exp $ */ /** @@ -162,22 +162,6 @@ exit_process(struct process *p, struct process *fromprocess) } } -#if 0 - { - int n; - int i = fevent; - for(n = nevents; n > 0; n--) { - if(events[i].p == p) { - events[i].p = (struct process *)PROCESS_ZOMBIE; -#if DEBUG - printf("soft panic: exiting process has remaining event 0x%x\n", - events[i].ev); -#endif - } - i = (i + 1) % PROCESS_CONF_NUMEVENTS; - } - } -#endif /* 0 */ process_current = old_current; } /*---------------------------------------------------------------------------*/ @@ -293,10 +277,6 @@ do_event(void) } call_process(p, ev, data); } -#if 0 - } else if(receiver == (struct process *)PROCESS_ZOMBIE) { - /* This process has exited. */ -#endif /* 0 */ } else { /* This is not a broadcast event, so we deliver it to the specified process. */ @@ -335,7 +315,7 @@ process_nevents(void) int process_post(struct process *p, process_event_t ev, process_data_t data) { - static unsigned char snum; + static process_num_events_t snum; if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", @@ -357,7 +337,7 @@ process_post(struct process *p, process_event_t ev, process_data_t data) return PROCESS_ERR_FULL; } - snum = (fevent + nevents) % PROCESS_CONF_NUMEVENTS; + snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS; events[snum].ev = ev; events[snum].data = data; events[snum].p = p; From 7c146c397233383224c6e0779917b57c693e5e4a Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 23 Feb 2010 18:39:00 +0000 Subject: [PATCH 094/146] Improved per-packet power profiling: if a packet is retransmitted, the new energy is added to the old energy so that it is possible to measure the full energy for all transmissions of the packet --- compower.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compower.c b/compower.c index e0e4a8f65..c1f8cdc90 100644 --- a/compower.c +++ b/compower.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.c,v 1.3 2009/03/12 21:58:21 adamdunkels Exp $ + * $Id: compower.c,v 1.4 2010/02/23 18:39:00 adamdunkels Exp $ */ /** @@ -81,8 +81,10 @@ compower_clear(struct compower_activity *e) void compower_attrconv(struct compower_activity *e) { - packetbuf_set_attr(PACKETBUF_ATTR_LISTEN_TIME, e->listen); - packetbuf_set_attr(PACKETBUF_ATTR_TRANSMIT_TIME, e->transmit); + packetbuf_set_attr(PACKETBUF_ATTR_LISTEN_TIME, + packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME) + e->listen); + packetbuf_set_attr(PACKETBUF_ATTR_TRANSMIT_TIME, + packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME) + e->transmit); } /*---------------------------------------------------------------------------*/ void From 9923b5626303bf49017befabe265d960a26e98fe Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 23 Feb 2010 18:40:08 +0000 Subject: [PATCH 095/146] Ugly workaround for internal error in mspgcc when applying the >= operator to two 32-bit values --- timer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/timer.c b/timer.c index 821f2a2bc..756ea4759 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.5 2009/01/24 15:20:11 adamdunkels Exp $ + * $Id: timer.c,v 1.6 2010/02/23 18:40:08 adamdunkels Exp $ */ #include "contiki-conf.h" @@ -121,7 +121,10 @@ timer_restart(struct timer *t) int timer_expired(struct timer *t) { - return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; + clock_time_t diff = clock_time() - t->start; + /* This somewhat ugly way of returning (diff >= t->interval) is + required to avoid an internal error in mspgcc. */ + return diff > t->interval || diff == t->interval; } /*---------------------------------------------------------------------------*/ /** From 60c69c840cdfcb91cb73772a60f7a764dcdfb32b Mon Sep 17 00:00:00 2001 From: joxe Date: Mon, 15 Mar 2010 15:53:57 +0000 Subject: [PATCH 096/146] added function to retrieve elapsed time --- stimer.c | 19 ++++++++++++++++++- stimer.h | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/stimer.c b/stimer.c index b300afb3d..4307b8022 100644 --- a/stimer.c +++ b/stimer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.c,v 1.2 2008/11/05 19:34:36 nvt-se Exp $ + * $Id: stimer.c,v 1.3 2010/03/15 15:53:57 joxe Exp $ */ #include "contiki-conf.h" @@ -142,6 +142,23 @@ stimer_remaining(struct stimer *t) { return t->start + t->interval - clock_seconds(); } +/*---------------------------------------------------------------------------*/ +/** + * The time elapsed since the timer started + * + * This function returns the time elapsed. + * + * \param t A pointer to the timer + * + * \return The time elapsed since the last start of the timer + * + */ +unsigned long +stimer_elapsed(struct stimer *t) +{ + return clock_seconds() - t->start; +} + /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/stimer.h b/stimer.h index 11bd1dee6..84279f711 100644 --- a/stimer.h +++ b/stimer.h @@ -64,7 +64,7 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.h,v 1.3 2009/03/01 09:31:43 adamdunkels Exp $ + * $Id: stimer.h,v 1.4 2010/03/15 15:53:57 joxe Exp $ */ #ifndef __STIMER_H__ #define __STIMER_H__ @@ -89,6 +89,7 @@ void stimer_reset(struct stimer *t); void stimer_restart(struct stimer *t); int stimer_expired(struct stimer *t); unsigned long stimer_remaining(struct stimer *t); +unsigned long stimer_elapsed(struct stimer *t); #endif /* __STIMER_H__ */ From c926941428c998b3093e0a302a764b04cb8ae2a9 Mon Sep 17 00:00:00 2001 From: fros4943 Date: Tue, 23 Mar 2010 13:24:38 +0000 Subject: [PATCH 097/146] allows rtimer_clock_t to be defined from contiki-conf.h --- rtimer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtimer.h b/rtimer.h index 3e1a56b1d..039a5b79a 100644 --- a/rtimer.h +++ b/rtimer.h @@ -48,13 +48,15 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.9 2009/03/01 09:31:43 adamdunkels Exp $ + * @(#)$Id: rtimer.h,v 1.10 2010/03/23 13:24:38 fros4943 Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ +#ifndef RTIMER_CLOCK_LT typedef unsigned short rtimer_clock_t; #define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) +#endif /* RTIMER_CLOCK_LT */ /** * \brief Initialize the real-time scheduler. From f8e362f62e2e0967913bcc33c017c3d156a59efb Mon Sep 17 00:00:00 2001 From: fros4943 Date: Tue, 23 Mar 2010 13:35:00 +0000 Subject: [PATCH 098/146] moved inclusion of rtimer-arch.h to top of rtimer.h, to avoid circular rtimer_clock_t dependencies --- rtimer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtimer.h b/rtimer.h index 039a5b79a..db4539e36 100644 --- a/rtimer.h +++ b/rtimer.h @@ -48,11 +48,13 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.10 2010/03/23 13:24:38 fros4943 Exp $ + * @(#)$Id: rtimer.h,v 1.11 2010/03/23 13:35:00 fros4943 Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ +#include "rtimer-arch.h" + #ifndef RTIMER_CLOCK_LT typedef unsigned short rtimer_clock_t; #define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) @@ -147,8 +149,6 @@ void rtimer_arch_schedule(rtimer_clock_t t); #define RTIMER_SECOND RTIMER_ARCH_SECOND -#include "rtimer-arch.h" - #endif /* __RTIMER_H__ */ /** @} */ From ebf34e9b4643d3997e130a943ee1341ecdc54c60 Mon Sep 17 00:00:00 2001 From: anthony-a Date: Tue, 6 Apr 2010 19:10:21 +0000 Subject: [PATCH 099/146] merge change from branch into mainline. --- timetable.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/timetable.c b/timetable.c index 3187e5102..5fc1481b1 100644 --- a/timetable.c +++ b/timetable.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.c,v 1.3 2009/09/09 21:10:35 adamdunkels Exp $ + * $Id: timetable.c,v 1.4 2010/04/06 19:10:21 anthony-a Exp $ */ /** @@ -71,7 +71,11 @@ rtimer_clock_t timetable_timediff(struct timetable *t, const char *id1, const char *id2) { +#ifdef SDCC_mcs51 + char i; /* SDCC tracker 2982753 */ +#else int i; +#endif int t1, t2; t1 = t2 = t->size; From 2cb9bac23820c3f9ff5d98921ba7d3d29337b637 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 14 Jun 2010 07:34:36 +0000 Subject: [PATCH 100/146] Moved ctimer.[ch] from their old and illogical location in core/net/rime to a more appropriate place in core/sys --- ctimer.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ctimer.h | 149 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 ctimer.c create mode 100644 ctimer.h diff --git a/ctimer.c b/ctimer.c new file mode 100644 index 000000000..ffcde952d --- /dev/null +++ b/ctimer.c @@ -0,0 +1,172 @@ +/** + * \addtogroup ctimer + * @{ + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: ctimer.c,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $ + */ + +/** + * \file + * Callback timer implementation + * \author + * Adam Dunkels + */ + +#include "sys/ctimer.h" +#include "contiki.h" +#include "lib/list.h" + +LIST(ctimer_list); + +static char initialized; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +PROCESS(ctimer_process, "Ctimer process"); +PROCESS_THREAD(ctimer_process, ev, data) +{ + struct ctimer *c; + PROCESS_BEGIN(); + + for(c = list_head(ctimer_list); c != NULL; c = c->next) { + etimer_set(&c->etimer, c->etimer.timer.interval); + } + initialized = 1; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER); + for(c = list_head(ctimer_list); c != NULL; c = c->next) { + if(&c->etimer == data) { + list_remove(ctimer_list, c); + PROCESS_CONTEXT_BEGIN(c->p); + if(c->f != NULL) { + c->f(c->ptr); + } + PROCESS_CONTEXT_END(c->p); + break; + } + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_init(void) +{ + initialized = 0; + list_init(ctimer_list); + process_start(&ctimer_process, NULL); +} +/*---------------------------------------------------------------------------*/ +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(); + c->f = f; + c->ptr = ptr; + if(initialized) { + PROCESS_CONTEXT_BEGIN(&ctimer_process); + etimer_set(&c->etimer, t); + PROCESS_CONTEXT_END(&ctimer_process); + } else { + c->etimer.timer.interval = t; + } + + list_remove(ctimer_list, c); + list_add(ctimer_list, c); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_reset(struct ctimer *c) +{ + if(initialized) { + PROCESS_CONTEXT_BEGIN(&ctimer_process); + 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); + } + for(t = list_head(ctimer_list); t != NULL; t = t->next) { + if(t == c) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/ctimer.h b/ctimer.h new file mode 100644 index 000000000..70239c008 --- /dev/null +++ b/ctimer.h @@ -0,0 +1,149 @@ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup ctimer Callback timer + * @{ + * + * The ctimer module provides a timer mechanism that calls a specified + * C function when a ctimer expires. + * + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: ctimer.h,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the callback timer + * \author + * Adam Dunkels + */ + +#ifndef __CTIMER_H__ +#define __CTIMER_H__ + +#include "sys/etimer.h" + +struct ctimer { + struct ctimer *next; + struct etimer etimer; + struct process *p; + void (*f)(void *); + void *ptr; +}; + +/** + * \brief Reset a callback timer with the same interval as was + * previously set. + * \param c A pointer to the callback timer. + * + * This function resets the callback timer with the same + * interval that was given to the callback timer with the + * ctimer_set() function. The start point of the interval + * is the exact time that the callback timer last + * expired. Therefore, this function will cause the timer + * to be stable over time, unlike the ctimer_restart() + * function. + * + * \sa ctimer_restart() + */ +void ctimer_reset(struct ctimer *c); + +/** + * \brief Restart a callback timer from the current point in time + * \param c A pointer to the callback timer. + * + * This function restarts the callback timer with the same + * interval that was given to the ctimer_set() + * function. The callback timer will start at the current + * time. + * + * \note A periodic timer will drift if this function is + * used to reset it. For periodic timers, use the + * ctimer_reset() function instead. + * + * \sa ctimer_reset() + */ +void ctimer_restart(struct ctimer *c); + +/** + * \brief Set a callback timer. + * \param c A pointer to the callback timer. + * \param t The interval before the timer expires. + * \param f A function to be called when the timer expires. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. + * + * This function is used to set a callback timer for a time + * sometime in the future. When the callback timer expires, + * the callback function f will be called with ptr as argument. + * + */ +void ctimer_set(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr); + +/** + * \brief Stop a pending callback timer. + * \param c A pointer to the pending callback timer. + * + * This function stops a callback timer that has previously + * been set with ctimer_set(), ctimer_reset(), or ctimer_restart(). + * After this function has been called, the callback timer will be + * expired and will not call the callback function. + * + */ +void ctimer_stop(struct ctimer *c); + +/** + * \brief Check if a callback timer has expired. + * \param c A pointer to the callback timer + * \return Non-zero if the timer has expired, zero otherwise. + * + * This function tests if a callback timer has expired and + * returns true or false depending on its status. + */ +int ctimer_expired(struct ctimer *c); + +/** + * \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); + +#endif /* __CTIMER_H__ */ +/** @} */ +/** @} */ From 794c1af23925c33b634d0fd73d52bc765d98408a Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 14 Jun 2010 07:35:53 +0000 Subject: [PATCH 101/146] Documentation group set accordingly --- ctimer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ctimer.h b/ctimer.h index 70239c008..cf027fcc8 100644 --- a/ctimer.h +++ b/ctimer.h @@ -1,5 +1,5 @@ /** - * \addtogroup rime + * \addtogroup sys * @{ */ @@ -42,7 +42,7 @@ * * This file is part of the Contiki operating system. * - * $Id: ctimer.h,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $ + * $Id: ctimer.h,v 1.2 2010/06/14 07:35:53 adamdunkels Exp $ */ /** From 14ce0f019bca5d6af9637776ab303d6946ae1fdf Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Mon, 14 Jun 2010 19:19:16 +0000 Subject: [PATCH 102/146] Moved the modules packetbuf, queuebuf, and packetqueue from net/rime to net/, since they are not Rime-specific --- compower.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compower.c b/compower.c index c1f8cdc90..dc465b80e 100644 --- a/compower.c +++ b/compower.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.c,v 1.4 2010/02/23 18:39:00 adamdunkels Exp $ + * $Id: compower.c,v 1.5 2010/06/14 19:19:17 adamdunkels Exp $ */ /** @@ -46,7 +46,7 @@ #include "contiki-conf.h" #include "sys/energest.h" #include "sys/compower.h" -#include "net/rime/packetbuf.h" +#include "net/packetbuf.h" struct compower_activity compower_idle_activity; From eba2eafe5ba19490f56c21a095662d7a7f888066 Mon Sep 17 00:00:00 2001 From: joxe Date: Mon, 21 Jun 2010 09:41:49 +0000 Subject: [PATCH 103/146] changed timer comparison to avoid crashing mspgcc4 --- timer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/timer.c b/timer.c index 756ea4759..d8a602daa 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.6 2010/02/23 18:40:08 adamdunkels Exp $ + * $Id: timer.c,v 1.7 2010/06/21 09:41:49 joxe Exp $ */ #include "contiki-conf.h" @@ -122,9 +122,10 @@ int timer_expired(struct timer *t) { clock_time_t diff = clock_time() - t->start; - /* This somewhat ugly way of returning (diff >= t->interval) is - required to avoid an internal error in mspgcc. */ - return diff > t->interval || diff == t->interval; + /* Can not return diff >= t->interval so we need to return + t->interval < diff - required to avoid an internal error in mspgcc. */ + return t->interval < diff; + } /*---------------------------------------------------------------------------*/ /** From 70e476214453e1ebf4fe63b2885b3a1f2db170d4 Mon Sep 17 00:00:00 2001 From: joxe Date: Mon, 21 Jun 2010 19:07:24 +0000 Subject: [PATCH 104/146] fixed timer bug - did not do equality comparison --- timer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/timer.c b/timer.c index d8a602daa..9fcb54b06 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,7 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.7 2010/06/21 09:41:49 joxe Exp $ + * $Id: timer.c,v 1.8 2010/06/21 19:07:24 joxe Exp $ */ #include "contiki-conf.h" @@ -121,9 +121,9 @@ timer_restart(struct timer *t) int timer_expired(struct timer *t) { - clock_time_t diff = clock_time() - t->start; - /* Can not return diff >= t->interval so we need to return + /* Note: Can not return diff >= t->interval so we add 1 to diff and return t->interval < diff - required to avoid an internal error in mspgcc. */ + clock_time_t diff = (clock_time() - t->start) + 1; return t->interval < diff; } From 161b1b22d9808a19d3ca0432f0a1dd9cf9104561 Mon Sep 17 00:00:00 2001 From: nifi Date: Mon, 13 Sep 2010 20:46:02 +0000 Subject: [PATCH 105/146] Moved down inclusion of rtimer-arch.h to allow rtimer_clock_t to be used in rtimer-arch.h --- rtimer.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rtimer.h b/rtimer.h index db4539e36..db7c053ea 100644 --- a/rtimer.h +++ b/rtimer.h @@ -48,18 +48,20 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.11 2010/03/23 13:35:00 fros4943 Exp $ + * @(#)$Id: rtimer.h,v 1.12 2010/09/13 20:46:02 nifi Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ -#include "rtimer-arch.h" +#include "contiki-conf.h" #ifndef RTIMER_CLOCK_LT typedef unsigned short rtimer_clock_t; #define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) #endif /* RTIMER_CLOCK_LT */ +#include "rtimer-arch.h" + /** * \brief Initialize the real-time scheduler. * From 11925be68edbc286b949de1c8412dfbf3e692c7d Mon Sep 17 00:00:00 2001 From: dak664 Date: Tue, 14 Sep 2010 18:55:04 +0000 Subject: [PATCH 106/146] Add option to remove process name strings to save RAM --- process.c | 20 ++++++++++---------- process.h | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/process.c b/process.c index 284796d9c..da04bde9a 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.10 2010/02/02 21:13:27 adamdunkels Exp $ + * @(#)$Id: process.c,v 1.11 2010/09/14 18:55:04 dak664 Exp $ */ /** @@ -115,7 +115,7 @@ process_start(struct process *p, const char *arg) p->state = PROCESS_STATE_RUNNING; PT_INIT(&p->pt); - PRINTF("process: starting '%s'\n", p->name); + PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p)); /* Post a synchronous initialization event to the process. */ process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg); @@ -127,7 +127,7 @@ exit_process(struct process *p, struct process *fromprocess) register struct process *q; struct process *old_current = process_current; - PRINTF("process: exit_process '%s'\n", p->name); + PRINTF("process: exit_process '%s'\n", PROCESS_NAME_STRING(p)); if(process_is_running(p)) { /* Process was running */ @@ -172,13 +172,13 @@ call_process(struct process *p, process_event_t ev, process_data_t data) #if DEBUG if(p->state == PROCESS_STATE_CALLED) { - printf("process: process '%s' called again with event %d\n", p->name, ev); + printf("process: process '%s' called again with event %d\n", PROCESS_NAME_STRING(p), ev); } #endif /* DEBUG */ if((p->state & PROCESS_STATE_RUNNING) && p->thread != NULL) { - PRINTF("process: calling process '%s' with event %d\n", p->name, ev); + PRINTF("process: calling process '%s' with event %d\n", PROCESS_NAME_STRING(p), ev); process_current = p; p->state = PROCESS_STATE_CALLED; ret = p->thread(&p->pt, ev, data); @@ -319,19 +319,19 @@ process_post(struct process *p, process_event_t ev, process_data_t data) if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", - ev, p->name, nevents); + ev,PROCESS_NAME_STRING(p), nevents); } else { PRINTF("process_post: Process '%s' posts event %d to process '%s', nevents %d\n", - PROCESS_CURRENT()->name, ev, - p == PROCESS_BROADCAST? "": p->name, nevents); + PROCESS_NAME_STRING(PROCESS_CURRENT()), ev, + p == PROCESS_BROADCAST? "": PROCESS_NAME_STRING(p), nevents); } if(nevents == PROCESS_CONF_NUMEVENTS) { #if DEBUG if(p == PROCESS_BROADCAST) { - printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, process_current->name); + printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current)); } else { - printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, p->name, process_current->name); + printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); } #endif /* DEBUG */ return PROCESS_ERR_FULL; diff --git a/process.h b/process.h index f1bea6aaf..097ac03cf 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.16 2008/10/14 12:46:39 nvt-se Exp $ + * @(#)$Id: process.h,v 1.17 2010/09/14 18:55:04 dak664 Exp $ */ /** @@ -292,22 +292,35 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \ * This macro declares a process. The process has two names: the * variable of the process structure, which is used by the C program, * and a human readable string name, which is used when debugging. + * A configuration option allows removal of the readable name to save RAM. * * \param name The variable name of the process structure. * \param strname The string representation of the process' name. * * \hideinitializer */ +#if PROCESS_CONF_NO_PROCESS_NAMES +#define PROCESS(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, \ + process_thread_##name } +#else #define PROCESS(name, strname) \ PROCESS_THREAD(name, ev, data); \ struct process name = { NULL, strname, \ process_thread_##name } +#endif /** @} */ struct process { struct process *next; +#if PROCESS_CONF_NO_PROCESS_NAMES +#define PROCESS_NAME_STRING(process) "" +#else const char *name; +#define PROCESS_NAME_STRING(process) (process)->name +#endif PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); struct pt pt; unsigned char state, needspoll; From d9865df937d3fff6b73a453439fd4a61eafc2668 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Wed, 20 Oct 2010 22:24:46 +0000 Subject: [PATCH 107/146] Defensive programming: make sure that a process is actually running before we try to kill it. --- process.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/process.c b/process.c index da04bde9a..70adf673c 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.11 2010/09/14 18:55:04 dak664 Exp $ + * @(#)$Id: process.c,v 1.12 2010/10/20 22:24:46 adamdunkels Exp $ */ /** @@ -129,6 +129,13 @@ exit_process(struct process *p, struct process *fromprocess) PRINTF("process: exit_process '%s'\n", PROCESS_NAME_STRING(p)); + /* Make sure the process is in the process list before we try to + exit it. */ + for(q = process_list; q != p && q != NULL; q = q->next); + if(q == NULL) { + return; + } + if(process_is_running(p)) { /* Process was running */ p->state = PROCESS_STATE_NONE; @@ -150,7 +157,7 @@ exit_process(struct process *p, struct process *fromprocess) p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL); } } - + if(p == process_list) { process_list = process_list->next; } else { From add98d567f2d87e22f12d090ef8a7ca51e0a55dd Mon Sep 17 00:00:00 2001 From: Lionel Debroux Date: Sat, 19 Feb 2011 08:25:29 +0000 Subject: [PATCH 108/146] Several compiler warning fixes: * msp430: fix "implicit declaration of function" warnings in clock.c, by including watchdog.h; * sky: fix a couple pointer target signedness warnings; * core: fix several signed/unsigned comparison warnings; * framer-802154: "const static" -> "static const" to fix compiler warnings; * core: comment or remove unused variables and function definitions. Signed-off-by: Lionel Debroux Signed-off-by: Mariano Alvira --- timetable-aggregate.c | 5 +++-- timetable.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/timetable-aggregate.c b/timetable-aggregate.c index 5c35b035d..391f472dd 100644 --- a/timetable-aggregate.c +++ b/timetable-aggregate.c @@ -147,7 +147,7 @@ void timetable_aggregate_compute_detailed(struct timetable_aggregate *a, struct timetable *timetable) { - int i; + unsigned int i; rtimer_clock_t t; t = timetable->timestamps[0].time; @@ -179,7 +179,8 @@ void timetable_aggregate_compute_categories(struct timetable_aggregate *a, struct timetable *timetable) { - int i,j; + unsigned int i; + int j; rtimer_clock_t t; uint16_t categories[XXX_HACK_MAX_CATEGORIES]; int categories_ptr = 0; diff --git a/timetable.c b/timetable.c index 5fc1481b1..fe30ac166 100644 --- a/timetable.c +++ b/timetable.c @@ -118,7 +118,7 @@ timetable_init(void) void timetable_print(struct timetable *t) { - int i; + unsigned int i; int time; time = t->timestamps[0].time; From 2c9541419599e8b73747943763f3ac397b89f445 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 8 May 2011 22:25:38 +0200 Subject: [PATCH 109/146] Flush before computing accumulative power --- compower.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compower.c b/compower.c index dc465b80e..0872d6b39 100644 --- a/compower.c +++ b/compower.c @@ -63,6 +63,8 @@ compower_accumulate(struct compower_activity *e) static uint32_t last_listen, last_transmit; uint32_t listen, transmit; + energest_flush(); + listen = energest_type_time(ENERGEST_TYPE_LISTEN); e->listen += listen - last_listen; last_listen = listen; From 9e2ca918c45ff2fc9f7236e84d0410bee9f7fa90 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Wed, 17 Aug 2011 16:51:22 -0400 Subject: [PATCH 110/146] Account for 16 bit rtimer wraparound, else ENERGEST way underreports AVR times. --- energest.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/energest.h b/energest.h index 8929b3547..550f5eac9 100644 --- a/energest.h +++ b/energest.h @@ -91,7 +91,22 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type] = RTIMER_NOW(); \ energest_current_mode[type] = 1; \ } while(0) +#ifdef __AVR__ +/* Handle 16 bit rtimer wraparound */ +#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ + if (RTIMER_NOW() < energest_current_time[type]) energest_total_time[type].current += RTIMER_ARCH_SECOND; \ + energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ + energest_current_time[type]); \ + energest_current_mode[type] = 0; \ + } while(0) +#define ENERGEST_OFF_LEVEL(type,level) do { \ + if (RTIMER_NOW() < energest_current_time[type]) energest_total_time[type].current += RTIMER_ARCH_SECOND; \ + energest_leveldevice_current_leveltime[level].current += (rtimer_clock_t)(RTIMER_NOW() - \ + energest_current_time[type]); \ + energest_current_mode[type] = 0; \ + } while(0) +#else #define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ energest_current_time[type]); \ @@ -103,6 +118,7 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) +#endif #else /* ENERGEST_CONF_ON */ From b8565b53adfd16f1f06533d613753c0cc866dc58 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 22 Nov 2011 09:36:27 +0100 Subject: [PATCH 111/146] Bugfix: PROCESS_PAUSE() must explicitly check the event type, otherwise we may cause the process event queue to fill up if we repeatedly call PROCESS_PAUSE() while other (broadcast) events are posted as well, such as timer events. --- process.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process.h b/process.h index 097ac03cf..4aadf9ca7 100644 --- a/process.h +++ b/process.h @@ -221,7 +221,7 @@ typedef unsigned char process_num_events_t; */ #define PROCESS_PAUSE() do { \ process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \ - PROCESS_WAIT_EVENT(); \ + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); \ } while(0) /** @} end of protothread functions */ From 2fea3c8692e734e9600c150a0e3b3bf7aa54b6f1 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Tue, 21 Feb 2012 11:23:54 -0500 Subject: [PATCH 112/146] Eliminate unused variable warnings. Dummy test of PT_YIELD_FLAG does not change program size. --- pt.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pt.h b/pt.h index 3f1467c62..9433a1086 100644 --- a/pt.h +++ b/pt.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: pt.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ */ /** @@ -112,7 +111,7 @@ struct pt { * * \hideinitializer */ -#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc) /** * Declare the end of a protothread. From 34472946df2461e061193eab27c1bf9e16da2f0b Mon Sep 17 00:00:00 2001 From: David Kopf Date: Mon, 9 Apr 2012 15:49:53 -0400 Subject: [PATCH 113/146] Add clock_delay_us and clock_set_seconds to clock.h. Modify clock_wait to use clock_time_t. Remove the troublesome avr/dev/delay.* files. Add PLATFORM_NAME and combine the confusing *_REVISION defines into a single PLATFORM_TYPE --- clock.h | 82 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/clock.h b/clock.h index b14db6112..986f6ae33 100644 --- a/clock.h +++ b/clock.h @@ -6,17 +6,28 @@ * \defgroup clock Clock library * * The clock library is the interface between Contiki and the platform - * specific clock functionality. The clock library performs a single - * function: measuring time. Additionally, the clock library provides - * a macro, CLOCK_SECOND, which corresponds to one second of system - * time. + * specific clock functionality. The clock library defines a macro, + * CLOCK_SECOND, to convert seconds into the tick resolution of the platform. + * Typically this is 1-10 milliseconds, e.g. 4*CLOCK_SECOND could be 512. + * A 16 bit counter would thus overflow every 1-10 minutes. + * Platforms use the tick interrupt to maintain a long term count + * of seconds since startup. + * + * Platforms may also implement rtimers for greater time resolution + * and for real-time interrupts, These use a corresponding RTIMER_SECOND. + * + * \note These timers do not necessarily have a common divisor or are phase locked. + * One may be crystal controlled and the other may not. Low power operation + * or sleep will often use one for wake and disable the other, then give + * it a tick correction after wakeup. * * \note The clock library need in many cases not be used - * directly. Rather, the \ref timer "timer library" or the \ref etimer - * "event timers" should be used. + * directly. Rather, the \ref timer "timer library", \ref etimer + * "event timers", or \ref trimer "rtimer library" should be used. * * \sa \ref timer "Timer library" * \sa \ref etimer "Event timers" + * \sa \ref rtimer "Realtime library" * * @{ */ @@ -53,24 +64,22 @@ * * Author: Adam Dunkels * - * $Id: clock.h,v 1.11 2009/01/24 15:20:11 adamdunkels Exp $ */ #ifndef __CLOCK_H__ #define __CLOCK_H__ #include "contiki-conf.h" -#if 0 /* XXX problems with signedness and use in timer_expired(). #if:ed it out for now. */ /** - * Check if a clock time value is less than another clock time value. - * - * This macro checks if a clock time value is less than another clock - * time value. This macro is needed to correctly handle wrap-around of - * clock time values. + * A second, measured in system clock time. * + * \hideinitializer */ -#define CLOCK_LT(a, b) ((clock_time_t)((a) - (b)) < ((clock_time_t)(~((clock_time_t)0)) >> 1)) -#endif /* 0 */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif /** * Initialize the clock library. @@ -90,24 +99,45 @@ void clock_init(void); */ CCIF clock_time_t clock_time(void); -void clock_delay(unsigned int); +/** + * Get the current value of the platform seconds. + * + * This could be the number of seconds since startup, or + * since a standard epoch. + * + * \return The value. + */ +CCIF unsigned long clock_seconds(void); /** - * A second, measured in system clock time. + * Set the value of the platform seconds. + * \param sec The value to set. * - * \hideinitializer */ -#ifdef CLOCK_CONF_SECOND -#define CLOCK_SECOND CLOCK_CONF_SECOND -#else -#define CLOCK_SECOND (clock_time_t)32 -#endif +void clock_set_seconds(unsigned long sec); -int clock_fine_max(void); -unsigned short clock_fine(void); +/** + * Wait for a given number of ticks. + * \param t How many ticks. + * + */ +void clock_wait(clock_time_t t); -CCIF unsigned long clock_seconds(void); +/** + * Delay a given number of microseconds. + * \param dt How many microseconds to delay. + * + * \note Interrupts could increase the delay by a variable amount. + */ +void clock_delay_usec(uint16_t dt); +/** + * Deprecated platform-specific routines. + * + */ +int clock_fine_max(void); +unsigned short clock_fine(void); +void clock_delay(unsigned int delay); #endif /* __CLOCK_H__ */ From 295ec61cfcf4612c191d426d2603fd53aa1cc63d Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Fri, 26 Oct 2012 15:54:49 +0200 Subject: [PATCH 114/146] Removed all old RCS tags in the Contiki source tree. Those RCS tags are not used any more, as we are now using git to manage the Contiki source tree --- arg.c | 1 - arg.h | 1 - autostart.c | 1 - autostart.h | 1 - cc.h | 1 - compower.c | 1 - compower.h | 1 - ctimer.c | 1 - ctimer.h | 1 - dsc.h | 1 - energest.c | 1 - energest.h | 1 - etimer.c | 1 - etimer.h | 1 - lc-addrlabels.h | 1 - lc-switch.h | 1 - lc.h | 1 - loader.h | 1 - log.h | 1 - mt.c | 1 - mt.h | 1 - process.c | 1 - process.h | 1 - procinit.c | 1 - procinit.h | 1 - profile-aggregates.c | 1 - profile.c | 1 - profile.h | 1 - pt-sem.h | 1 - rtimer.c | 1 - rtimer.h | 1 - stimer.c | 1 - stimer.h | 1 - subprocess.h | 1 - timer.c | 1 - timer.h | 1 - timetable-aggregate.c | 1 - timetable-aggregate.h | 1 - timetable.c | 1 - timetable.h | 1 - 40 files changed, 40 deletions(-) diff --git a/arg.c b/arg.c index 48594bc46..080dea9bb 100644 --- a/arg.c +++ b/arg.c @@ -60,7 +60,6 @@ * * This file is part of the Contiki desktop OS * - * $Id: arg.c,v 1.2 2006/08/14 23:39:23 oliverschmidt Exp $ * */ diff --git a/arg.h b/arg.h index 4abcb820d..df1ceb67d 100644 --- a/arg.h +++ b/arg.h @@ -29,7 +29,6 @@ * * This file is part of the Contiki desktop OS * - * $Id: arg.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ * */ #ifndef __ARG_H__ diff --git a/autostart.c b/autostart.c index 8bd2ccfa4..a0d8a77b4 100644 --- a/autostart.c +++ b/autostart.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.c,v 1.3 2007/11/18 12:27:45 ksb Exp $ */ /** diff --git a/autostart.h b/autostart.h index c457bb4d2..46c3333b8 100644 --- a/autostart.h +++ b/autostart.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: autostart.h,v 1.5 2008/02/10 11:17:33 oliverschmidt Exp $ */ /** diff --git a/cc.h b/cc.h index 7250f6a87..f4a6105a1 100644 --- a/cc.h +++ b/cc.h @@ -39,7 +39,6 @@ * * This file is part of the Contiki desktop OS * - * $Id: cc.h,v 1.6 2008/07/02 08:35:29 adamdunkels Exp $ * */ #ifndef __CC_H__ diff --git a/compower.c b/compower.c index 0872d6b39..b920c3e70 100644 --- a/compower.c +++ b/compower.c @@ -33,7 +33,6 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.c,v 1.5 2010/06/14 19:19:17 adamdunkels Exp $ */ /** diff --git a/compower.h b/compower.h index b5797a055..60866f660 100644 --- a/compower.h +++ b/compower.h @@ -42,7 +42,6 @@ * * This file is part of the Contiki operating system. * - * $Id: compower.h,v 1.2 2009/03/12 21:58:21 adamdunkels Exp $ */ /** diff --git a/ctimer.c b/ctimer.c index ffcde952d..e6090a9a8 100644 --- a/ctimer.c +++ b/ctimer.c @@ -33,7 +33,6 @@ * * This file is part of the Contiki operating system. * - * $Id: ctimer.c,v 1.1 2010/06/14 07:34:36 adamdunkels Exp $ */ /** diff --git a/ctimer.h b/ctimer.h index cf027fcc8..bc7bf2f98 100644 --- a/ctimer.h +++ b/ctimer.h @@ -42,7 +42,6 @@ * * This file is part of the Contiki operating system. * - * $Id: ctimer.h,v 1.2 2010/06/14 07:35:53 adamdunkels Exp $ */ /** diff --git a/dsc.h b/dsc.h index 29892343e..75ba4d9a9 100644 --- a/dsc.h +++ b/dsc.h @@ -56,7 +56,6 @@ * * This file is part of the Contiki desktop environment * - * $Id: dsc.h,v 1.4 2008/10/14 12:46:39 nvt-se Exp $ * */ #ifndef __DSC_H__ diff --git a/energest.c b/energest.c index b7e59c271..5b0f6cb86 100644 --- a/energest.c +++ b/energest.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.c,v 1.2 2008/09/29 11:44:37 joxe Exp $ */ /** diff --git a/energest.h b/energest.h index 550f5eac9..70b46ab6c 100644 --- a/energest.h +++ b/energest.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: energest.h,v 1.5 2009/10/20 20:19:27 adamdunkels Exp $ */ /** diff --git a/etimer.c b/etimer.c index 089ddbc8b..0f8fba4b3 100644 --- a/etimer.c +++ b/etimer.c @@ -42,7 +42,6 @@ * * Author: Adam Dunkels * - * $Id: etimer.c,v 1.3 2007/10/07 19:59:27 joxe Exp $ */ #include "contiki-conf.h" diff --git a/etimer.h b/etimer.h index a965089b9..f46e24c13 100644 --- a/etimer.h +++ b/etimer.h @@ -58,7 +58,6 @@ * * Author: Adam Dunkels * - * $Id: etimer.h,v 1.3 2008/02/07 23:04:35 oliverschmidt Exp $ */ #ifndef __ETIMER_H__ #define __ETIMER_H__ diff --git a/lc-addrlabels.h b/lc-addrlabels.h index 10578bedb..b7f7028e4 100644 --- a/lc-addrlabels.h +++ b/lc-addrlabels.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: lc-addrlabels.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ */ /** diff --git a/lc-switch.h b/lc-switch.h index 6939004af..6ffb6c763 100644 --- a/lc-switch.h +++ b/lc-switch.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: lc-switch.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $ */ /** diff --git a/lc.h b/lc.h index 33c472c9a..2da0e4a9e 100644 --- a/lc.h +++ b/lc.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: lc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ */ /** diff --git a/loader.h b/loader.h index 88e4762b0..3b8656636 100644 --- a/loader.h +++ b/loader.h @@ -49,7 +49,6 @@ * * This file is part of the Contiki desktop OS * - * $Id: loader.h,v 1.2 2008/10/14 12:46:39 nvt-se Exp $ * */ #ifndef __LOADER_H__ diff --git a/log.h b/log.h index 2460210fa..93aecb765 100644 --- a/log.h +++ b/log.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: log.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ */ #ifndef __LOG_H__ #define __LOG_H__ diff --git a/mt.c b/mt.c index bf3bd46e4..cfa8a39a5 100644 --- a/mt.c +++ b/mt.c @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: mt.c,v 1.7 2009/09/03 12:57:58 nvt-se Exp $ */ /** diff --git a/mt.h b/mt.h index 29dbe6ef4..4d53fff4a 100644 --- a/mt.h +++ b/mt.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: mt.h,v 1.6 2008/10/14 12:46:39 nvt-se Exp $ */ /** \addtogroup sys diff --git a/process.c b/process.c index 70adf673c..8a7496d75 100644 --- a/process.c +++ b/process.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.12 2010/10/20 22:24:46 adamdunkels Exp $ */ /** diff --git a/process.h b/process.h index 4aadf9ca7..63fa75e14 100644 --- a/process.h +++ b/process.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.17 2010/09/14 18:55:04 dak664 Exp $ */ /** diff --git a/procinit.c b/procinit.c index 169b0cff4..dfac1bf00 100644 --- a/procinit.c +++ b/procinit.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: procinit.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ */ #include "contiki.h" diff --git a/procinit.h b/procinit.h index b590560ee..134b8d7d6 100644 --- a/procinit.h +++ b/procinit.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: procinit.h,v 1.2 2007/08/22 10:49:48 ksb Exp $ */ #ifndef __PROCINIT_H__ #define __PROCINIT_H__ diff --git a/profile-aggregates.c b/profile-aggregates.c index 4cd3bc232..93855474c 100644 --- a/profile-aggregates.c +++ b/profile-aggregates.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: profile-aggregates.c,v 1.4 2007/11/18 12:27:45 ksb Exp $ */ /** diff --git a/profile.c b/profile.c index 9f16c0b31..bff83c813 100644 --- a/profile.c +++ b/profile.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.c,v 1.4 2008/01/17 12:19:26 adamdunkels Exp $ */ /** diff --git a/profile.h b/profile.h index bd9c3226e..9bf6866db 100644 --- a/profile.h +++ b/profile.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: profile.h,v 1.3 2008/01/17 12:19:26 adamdunkels Exp $ */ /** diff --git a/pt-sem.h b/pt-sem.h index 01234ff36..3f8a4f9e9 100644 --- a/pt-sem.h +++ b/pt-sem.h @@ -30,7 +30,6 @@ * * Author: Adam Dunkels * - * $Id: pt-sem.h,v 1.2 2008/10/14 12:46:39 nvt-se Exp $ */ /** diff --git a/rtimer.c b/rtimer.c index eb92625d6..60b8b37c1 100644 --- a/rtimer.c +++ b/rtimer.c @@ -42,7 +42,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.c,v 1.7 2010/01/19 13:08:24 adamdunkels Exp $ */ #include "sys/rtimer.h" diff --git a/rtimer.h b/rtimer.h index db7c053ea..113dc7ded 100644 --- a/rtimer.h +++ b/rtimer.h @@ -48,7 +48,6 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: rtimer.h,v 1.12 2010/09/13 20:46:02 nifi Exp $ */ #ifndef __RTIMER_H__ #define __RTIMER_H__ diff --git a/stimer.c b/stimer.c index 4307b8022..0e13651d8 100644 --- a/stimer.c +++ b/stimer.c @@ -42,7 +42,6 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.c,v 1.3 2010/03/15 15:53:57 joxe Exp $ */ #include "contiki-conf.h" diff --git a/stimer.h b/stimer.h index 84279f711..16711e604 100644 --- a/stimer.h +++ b/stimer.h @@ -64,7 +64,6 @@ * * Author: Adam Dunkels , Nicolas Tsiftes * - * $Id: stimer.h,v 1.4 2010/03/15 15:53:57 joxe Exp $ */ #ifndef __STIMER_H__ #define __STIMER_H__ diff --git a/subprocess.h b/subprocess.h index b92527548..9f2761810 100644 --- a/subprocess.h +++ b/subprocess.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: subprocess.h,v 1.1 2006/09/26 20:53:27 adamdunkels Exp $ */ /** diff --git a/timer.c b/timer.c index 9fcb54b06..d13b61f98 100644 --- a/timer.c +++ b/timer.c @@ -42,7 +42,6 @@ * * Author: Adam Dunkels * - * $Id: timer.c,v 1.8 2010/06/21 19:07:24 joxe Exp $ */ #include "contiki-conf.h" diff --git a/timer.h b/timer.h index 40f2be80b..88a45850f 100644 --- a/timer.h +++ b/timer.h @@ -69,7 +69,6 @@ * * Author: Adam Dunkels * - * $Id: timer.h,v 1.2 2008/09/21 08:58:05 adamdunkels Exp $ */ #ifndef __TIMER_H__ #define __TIMER_H__ diff --git a/timetable-aggregate.c b/timetable-aggregate.c index 391f472dd..fb647f3ce 100644 --- a/timetable-aggregate.c +++ b/timetable-aggregate.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable-aggregate.c,v 1.2 2008/03/13 14:27:34 fros4943 Exp $ */ /** diff --git a/timetable-aggregate.h b/timetable-aggregate.h index 24477c54c..969f81c0d 100644 --- a/timetable-aggregate.h +++ b/timetable-aggregate.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable-aggregate.h,v 1.2 2008/03/13 14:27:34 fros4943 Exp $ */ /** diff --git a/timetable.c b/timetable.c index fe30ac166..40766a62c 100644 --- a/timetable.c +++ b/timetable.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.c,v 1.4 2010/04/06 19:10:21 anthony-a Exp $ */ /** diff --git a/timetable.h b/timetable.h index 7b5fca00b..350d3d950 100644 --- a/timetable.h +++ b/timetable.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: timetable.h,v 1.2 2008/02/28 22:11:30 oliverschmidt Exp $ */ /** From fc08b3e334cdad95657f72d5299bea7cdd389c75 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 20 Nov 2012 19:57:20 +0100 Subject: [PATCH 115/146] Cleanup of the node-id.h files. The node-id.h file contains declarations of functions for setting and getting a node ID number, a functionality that exists on many platforms. Since this functionality was not considered part of the Contiki core, each platform defined its own node-id.h file. This commit attempts to clean this up by collecting the node-id.h into a core/sys/node-id.h file that replaces the old node-id.h files from the platform directories. --- node-id.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 node-id.h diff --git a/node-id.h b/node-id.h new file mode 100644 index 000000000..f0435228a --- /dev/null +++ b/node-id.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +void node_id_restore(void); +void node_id_burn(unsigned short node_id); + +extern unsigned short node_id; + +#endif /* __NODE_ID_H__ */ From fee2071c22536c88dcac6fd2ed3256d798bd0fd6 Mon Sep 17 00:00:00 2001 From: rgrr Date: Wed, 13 Feb 2013 09:15:11 +0100 Subject: [PATCH 116/146] add_timer() does not set owning process --- etimer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etimer.c b/etimer.c index 0f8fba4b3..60e673544 100644 --- a/etimer.c +++ b/etimer.c @@ -155,17 +155,17 @@ add_timer(struct etimer *timer) etimer_request_poll(); if(timer->p != PROCESS_NONE) { - /* Timer not on list. */ - for(t = timerlist; t != NULL; t = t->next) { if(t == timer) { /* Timer already on list, bail out. */ + timer->p = PROCESS_CURRENT(); update_time(); return; } } } + /* Timer not on list. */ timer->p = PROCESS_CURRENT(); timer->next = timerlist; timerlist = timer; From 3152ff4e4d7dc90c7f3bc2848b980a31ae35d54c Mon Sep 17 00:00:00 2001 From: hardy Date: Mon, 18 Feb 2013 20:34:24 +0100 Subject: [PATCH 117/146] one blank less --- etimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etimer.c b/etimer.c index 60e673544..34917aa93 100644 --- a/etimer.c +++ b/etimer.c @@ -158,7 +158,7 @@ add_timer(struct etimer *timer) for(t = timerlist; t != NULL; t = t->next) { if(t == timer) { /* Timer already on list, bail out. */ - timer->p = PROCESS_CURRENT(); + timer->p = PROCESS_CURRENT(); update_time(); return; } From b6c4cb358b356d3847fe4fcf8da73a37db010386 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Wed, 31 Jul 2013 00:04:43 +0200 Subject: [PATCH 118/146] Recent changes in telnetd make exporting of those two necessary. --- timer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/timer.h b/timer.h index 88a45850f..3bfdfa81f 100644 --- a/timer.h +++ b/timer.h @@ -88,10 +88,10 @@ struct timer { clock_time_t interval; }; -void timer_set(struct timer *t, clock_time_t interval); +CCIF void timer_set(struct timer *t, clock_time_t interval); void timer_reset(struct timer *t); void timer_restart(struct timer *t); -int timer_expired(struct timer *t); +CCIF int timer_expired(struct timer *t); clock_time_t timer_remaining(struct timer *t); From 4b6b35be4772d460a826a66bb315b9a156b38881 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Tue, 19 Nov 2013 00:23:13 +0100 Subject: [PATCH 119/146] Removed old unused sys/ files --- profile-aggregates.c | 247 ------------------------------------------ profile.c | 196 --------------------------------- profile.h | 87 --------------- timetable-aggregate.c | 239 ---------------------------------------- timetable-aggregate.h | 92 ---------------- timetable.c | 131 ---------------------- timetable.h | 139 ------------------------ 7 files changed, 1131 deletions(-) delete mode 100644 profile-aggregates.c delete mode 100644 profile.c delete mode 100644 profile.h delete mode 100644 timetable-aggregate.c delete mode 100644 timetable-aggregate.h delete mode 100644 timetable.c delete mode 100644 timetable.h diff --git a/profile-aggregates.c b/profile-aggregates.c deleted file mode 100644 index 93855474c..000000000 --- a/profile-aggregates.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Compuation of aggregates for the Contiki profiling system - * \author - * Adam Dunkels - */ - -#include "sys/profile.h" - -#include -#include - -struct aggregate { - const char *ptr; - unsigned short episodes; - unsigned long cycles; -}; - -#define DETAILED_AGGREGATES 0 - -#define MAX_CATEGORIES 32 -#define LIST_LEN 100 - -static struct aggregate aggregates[LIST_LEN]; - -static int aggregates_list_ptr = 0; - -/*---------------------------------------------------------------------------*/ -static struct aggregate * -find_aggregate_category(const uint16_t cat) -{ - int i; - uint16_t acat; - -/* printf("find_aggregate_category 0x%04x %c%c\n", */ -/* cat, cat >> 8, cat & 0xff); */ - - for(i = 0; i < aggregates_list_ptr; ++i) { - acat = (aggregates[i].ptr[0] << 8) + aggregates[i].ptr[1]; - -/* printf("acat 0x%04x %c%c\n", */ -/* acat, acat >> 8, acat & 0xff); */ - - if(acat == cat) { - return &aggregates[i]; - } - } - - if(i == LIST_LEN) { - return NULL; - } - - aggregates[aggregates_list_ptr].ptr = NULL; - return &aggregates[aggregates_list_ptr++]; -} -/*---------------------------------------------------------------------------*/ -#if DETAILED_AGGREGATES -static struct aggregate * -find_aggregate(const unsigned char *ptr) -{ - int i; - for(i = 0; i < aggregates_list_ptr; ++i) { - if(aggregates[i].ptr == ptr) { - return &aggregates[i]; - } - } - if(i == LIST_LEN) { - return NULL; - } - - return &aggregates[aggregates_list_ptr++]; -} -#endif /* DETAILED_AGGREGATES */ -/*---------------------------------------------------------------------------*/ -void -profile_aggregates_print(void) -{ - int i; - -#if DETAILED_AGGREGATES - for(i = 0; i < aggregates_list_ptr; ++i) { - printf("-- %s: %lu / %u = %lu\n", aggregates[i].ptr, - aggregates[i].cycles, - aggregates[i].episodes, - aggregates[i].cycles / aggregates[i].episodes); - } -#else - for(i = 0; i < aggregates_list_ptr; ++i) { - printf("-- %c%c: %lu / %u = %lu\n", - aggregates[i].ptr[0], aggregates[i].ptr[1], - aggregates[i].cycles, - aggregates[i].episodes, - aggregates[i].cycles / aggregates[i].episodes); - } -#endif - - printf("Memory for aggregates: %d * %d = %d\n", - (int)sizeof(struct aggregate), aggregates_list_ptr, - (int)sizeof(struct aggregate) * aggregates_list_ptr); -} -/*---------------------------------------------------------------------------*/ -#if DETAILED_AGGREGATES -static void -detailed_profile_aggregates_compute(void) -{ - int i; - rtimer_clock_t t; - /* const char *str = "profile_aggregates_compute"; - - PROFILE_TIMESTAMP(str);*/ - - t = profile_timestamps[0].time; - - for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { - struct aggregate *a; - a = find_aggregate(profile_timestamps[i - 1].ptr); - if(a == NULL) { - /* The list is full, skip this entry */ - printf("profile_aggregates_compute: list full\n"); - } else if(a->ptr == NULL) { - a->ptr = profile_timestamps[i - 1].ptr; - a->cycles = (unsigned long)(profile_timestamps[i].time - t); - a->episodes = 1; - } else { - a->cycles += (unsigned long)(profile_timestamps[i].time - t); - a->episodes++; - } - t = profile_timestamps[i].time; - } - - /* PROFILE_TIMESTAMP(str);*/ - - /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", - profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, - aggregates_list_ptr, profile_timestamp_time);*/ - - - /* print_aggregates();*/ -} -#endif /* DETAILED_AGGREGATES */ -/*---------------------------------------------------------------------------*/ -static void -category_profile_aggregates_compute(void) -{ - int i,j; - rtimer_clock_t t; - uint16_t categories[MAX_CATEGORIES]; - int categories_ptr = 0; - /* const char *str = "profile_aggregates_compute"; - - PROFILE_TIMESTAMP(str);*/ - - t = profile_timestamps[0].time; - - for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { - struct aggregate *a; - uint16_t cat; - -/* printf("category_profile_aggregates_compute %s\n", */ -/* profile_timestamps[i - 1].ptr); */ - cat = (profile_timestamps[i - 1].ptr[0] << 8) + - (profile_timestamps[i - 1].ptr[1] & 0xff); - a = find_aggregate_category(cat); - if(a == NULL) { - /* The list is full, skip this entry */ - printf("profile_aggregates_compute: list full\n"); - } else if(a->ptr == NULL) { - a->ptr = profile_timestamps[i - 1].ptr; - a->cycles = (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); - a->episodes = 1; - } else { - - a->cycles += (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); - - /* Make sure that we only update the episodes of each category - once per run. We keep track of all updated categories in the - "categories" array. If the category is already present in the - array, we do not update it. Otherwise, we insert the category - in the array and update the episodes counter of the - category. */ - - for(j = 0; j < categories_ptr; ++j) { - if(categories[j] == cat) { - break; - } - } - if(j == categories_ptr) { - categories[j] = cat; - categories_ptr++; - a->episodes++; - } - } - t = profile_timestamps[i].time; - } - - /* PROFILE_TIMESTAMP(str);*/ - - /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", - profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, - aggregates_list_ptr, profile_timestamp_time);*/ - - - /* print_aggregates();*/ -} -/*---------------------------------------------------------------------------*/ -void -profile_aggregates_compute(void) -{ -#if DETAILED_AGGREGATES - detailed_profile_aggregates_compute(); -#else - category_profile_aggregates_compute(); -#endif -} -/*---------------------------------------------------------------------------*/ diff --git a/profile.c b/profile.c deleted file mode 100644 index bff83c813..000000000 --- a/profile.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Implementation of the Contiki profiling system - * \author - * Adam Dunkels - */ - -#include "sys/profile.h" -#include "sys/clock.h" - -#include - -/* XXX: the profiling code is under development and may not work at - present. */ - - -TIMETABLE_NONSTATIC(profile_timetable); - -TIMETABLE_NONSTATIC(profile_begin_timetable); -TIMETABLE_NONSTATIC(profile_end_timetable); -TIMETABLE_AGGREGATE(profile_aggregate, PROFILE_AGGREGATE_SIZE); - -static rtimer_clock_t episode_start_time; -static unsigned int invalid_episode_overflow, invalid_episode_toolong, - max_queuelen; - -/* The number of fine grained ticks per coarse grained ticks. We - currently (MSP430) have 2457600 ticks per second for the fine - grained timer, and 32678 / 8 ticks per second for the coarse. */ -#define XXX_HACK_FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8)) - -/*---------------------------------------------------------------------------*/ -void -profile_init(void) -{ - timetable_init(); - timetable_clear(&profile_begin_timetable); - timetable_clear(&profile_end_timetable); -} -/*---------------------------------------------------------------------------*/ -void -profile_episode_start(void) -{ - struct timetable_timestamp *e; - timetable_clear(&profile_begin_timetable); - timetable_clear(&profile_end_timetable); - episode_start_time = clock_time(); - - e = timetable_entry(&profile_begin_timetable, - PROFILE_TIMETABLE_SIZE - 1); - if(e != NULL) { - e->id = NULL; - } - e = timetable_entry(&profile_end_timetable, - PROFILE_TIMETABLE_SIZE - 1); - if(e != NULL) { - e->id = NULL; - } -} -/*---------------------------------------------------------------------------*/ -void -profile_episode_end(void) -{ - struct timetable_timestamp *e; - rtimer_clock_t episode_end_time = clock_time(); - -/* printf("timetable_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */ - e = timetable_entry(&profile_begin_timetable, - PROFILE_TIMETABLE_SIZE - 1); - if(e != NULL && e->id != NULL) { - /* Invalid episode because of list overflow. */ - invalid_episode_overflow++; - max_queuelen = PROFILE_TIMETABLE_SIZE; - } else if(episode_end_time - episode_start_time > - 65536/XXX_HACK_FINE_TICKS_PER_COARSE_TICK) { - /* Invalid episode because of timer overflow. */ - invalid_episode_toolong++; - } else { - /* Compute aggregates. */ - if(timetable_ptr(&profile_begin_timetable) > max_queuelen) { - max_queuelen = timetable_ptr(&profile_begin_timetable); - } - /* timetable_aggregates_compute();*/ - } -} -/*---------------------------------------------------------------------------*/ -/* - * - * Find a specific aggregate ID in the list of aggregates. - * - */ -static struct timetable_aggregate_entry * -find_aggregate(struct timetable_aggregate *a, - const char *id) -{ - int i; - for(i = 0; i < a->ptr; ++i) { - if(a->entries[i].id == id) { - return &a->entries[i]; - } - } - if(i == a->size) { - return NULL; - } - a->entries[a->ptr].id = NULL; - return &a->entries[a->ptr++]; -} -/*---------------------------------------------------------------------------*/ -void -profile_aggregate_print_detailed(void) -{ - int i; - struct timetable_aggregate *a = &profile_aggregate; - - /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/ - for(i = 0; i < a->ptr; ++i) { - printf("-- %s: %lu / %u = %lu\n", a->entries[i].id, - a->entries[i].time, - a->entries[i].episodes, - a->entries[i].time / a->entries[i].episodes); - } - - printf("Memory for entries: %d * %d = %d\n", - (int)sizeof(struct timetable_aggregate), a->ptr, - (int)sizeof(struct timetable_aggregate) * a->ptr); -} -/*---------------------------------------------------------------------------*/ -void -profile_aggregate_compute_detailed(void) -{ - int i; - int last; - rtimer_clock_t t; - struct timetable_aggregate *a = &profile_aggregate; - struct timetable *timetable = &profile_timetable; - struct timetable_aggregate_entry *entry; - - last = timetable_ptr(&profile_begin_timetable); - t = profile_begin_timetable.timestamps[0].time; - for(i = 0; i < last; ++i) { - - entry = find_aggregate(a, profile_begin_timetable.timestamps[i].id); - if(entry == NULL) { - /* The list is full, skip this entry */ - /* printf("detailed_timetable_aggregate_compute: list full\n");*/ - } else if(entry->id == NULL) { - /* The id was found in the list, so we add it. */ - entry->id = timetable->timestamps[i - 1].id; - entry->time = (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - entry->episodes = 1; - /* printf("New entry %s %lu\n", entry->id, entry->time);*/ - } else { - entry->time += (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - entry->episodes++; - } - t = timetable->timestamps[i].time; - /* printf("a ptr %d\n", a->ptr);*/ - - } - -} -/*---------------------------------------------------------------------------*/ diff --git a/profile.h b/profile.h deleted file mode 100644 index 9bf6866db..000000000 --- a/profile.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for the Contiki profiling system - * \author - * Adam Dunkels - */ - -#ifndef __PROFILE_H__ -#define __PROFILE_H__ - -/* XXX: the profiling code is under development and may not work at - present. */ - -#define TIMETABLE_WITH_TYPE 1 -#include "sys/timetable.h" - -#ifdef PROFILE_CONF_TIMETABLE_SIZE -#define PROFILE_TIMETABLE_SIZE PROFILE_CONF_TIMETABLE_SIZE -#else -#define PROFILE_TIMETABLE_SIZE 128 -#endif - -#ifdef PROFILE_CONF_AGGREGATE_SIZE -#define PROFILE_AGGREGATE_SIZE PROFILE_CONF_AGGREGATE_SIZE -#else -#define PROFILE_AGGREGATE_SIZE 128 -#endif - -#define PROFILE_BEGIN(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 1) -#define PROFILE_END(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 2) - -/*#define PROFILE_COND_BEGIN(cond, id) TIMETABLE_COND_TIMESTAMP(profile_begin_timetable, \ - cond, id) -#define PROFILE_COND_END(cond, id) TIMETABLE_COND_TIMESTAMP(profile_end_timetable, \ - cond, id) -*/ - -#define profile_begin_timetable_size PROFILE_TIMETABLE_SIZE -TIMETABLE_DECLARE(profile_begin_timetable); -#define profile_end_timetable_size PROFILE_TIMETABLE_SIZE -TIMETABLE_DECLARE(profile_end_timetable); - -#define profile_timetable_size PROFILE_TIMETABLE_SIZE -TIMETABLE_DECLARE(profile_timetable); - -void profile_init(void); - -void profile_episode_start(void); -void profile_episode_end(void); - -void profile_aggregate_print_detailed(void); -void profile_aggregate_compute_detailed(void); - - -#endif /* __PROFILE_H__ */ diff --git a/timetable-aggregate.c b/timetable-aggregate.c deleted file mode 100644 index fb647f3ce..000000000 --- a/timetable-aggregate.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A brief description of what this file is. - * \author - * Adam Dunkels - */ - -#include "sys/timetable-aggregate.h" - -#define XXX_HACK_MAX_CATEGORIES 32 - -#include - -/*---------------------------------------------------------------------------*/ -/* - * - * Find an aggregation category in the list of aggregates. If the - * category could not be found, the function returns a pointer to an - * empty entry. If the list is full, the function returns NULL. - * - */ -static struct timetable_aggregate_entry * -find_aggregate_category(struct timetable_aggregate *a, - const uint16_t cat) -{ - int i; - uint16_t acat; - - for(i = 0; i < a->ptr; ++i) { - acat = (a->entries[i].id[0] << 8) + a->entries[i].id[1]; - if(acat == cat) { - - return &a->entries[i]; - } - } - - if(i == a->size) { - return NULL; - } - - a->entries[a->ptr].id = NULL; - return &a->entries[a->ptr++]; -} -/*---------------------------------------------------------------------------*/ -/* - * - * Find a specific aggregate ID in the list of aggregates. - * - */ -static struct timetable_aggregate_entry * -find_aggregate(struct timetable_aggregate *a, - const char *id) -{ - int i; - for(i = 0; i < a->ptr; ++i) { - if(a->entries[i].id == id) { - return &a->entries[i]; - } - } - if(i == a->size) { - return NULL; - } - a->entries[a->ptr].id = NULL; - return &a->entries[a->ptr++]; -} -/*---------------------------------------------------------------------------*/ -void -timetable_aggregate_print_detailed(struct timetable_aggregate *a) -{ - int i; - /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/ - for(i = 0; i < a->ptr; ++i) { - printf("-- %s: %lu / %u = %lu\n", a->entries[i].id, - a->entries[i].time, - a->entries[i].episodes, - a->entries[i].time / a->entries[i].episodes); - } - - printf("Memory for entries: %d * %d = %d\n", - (int)sizeof(struct timetable_aggregate), a->ptr, - (int)sizeof(struct timetable_aggregate) * a->ptr); -} -/*---------------------------------------------------------------------------*/ -void -timetable_aggregate_reset(struct timetable_aggregate *a) -{ - int i; - for(i = 0; i < a->ptr; ++i) { - a->entries[i].time = 0; - a->entries[i].episodes = 0; - } -} -/*---------------------------------------------------------------------------*/ -void -timetable_aggregate_print_categories(struct timetable_aggregate *a) -{ - int i; - - /* printf("timetable_aggregate_print_categories: a ptr %d\n", a->ptr);*/ - for(i = 0; i < a->ptr; ++i) { - printf("-- %c%c: %lu / %u = %lu\n", - a->entries[i].id[0], a->entries[i].id[1], - a->entries[i].time, - a->entries[i].episodes, - a->entries[i].time / a->entries[i].episodes); - } - - printf("Memory for entries: %d * %d = %d\n", - (int)sizeof(struct timetable_aggregate), a->ptr, - (int)sizeof(struct timetable_aggregate) * a->ptr); -} -/*---------------------------------------------------------------------------*/ -void -timetable_aggregate_compute_detailed(struct timetable_aggregate *a, - struct timetable *timetable) -{ - unsigned int i; - rtimer_clock_t t; - - t = timetable->timestamps[0].time; - - for(i = 1; i < *timetable->ptr; ++i) { - struct timetable_aggregate_entry *entry; - entry = find_aggregate(a, timetable->timestamps[i - 1].id); - if(entry == NULL) { - /* The list is full, skip this entry */ - /* printf("detailed_timetable_aggregate_compute: list full\n");*/ - } else if(entry->id == NULL) { - /* The id was found in the list, so we add it. */ - entry->id = timetable->timestamps[i - 1].id; - entry->time = (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - entry->episodes = 1; - /* printf("New entry %s %lu\n", entry->id, entry->time);*/ - } else { - entry->time += (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - entry->episodes++; - } - t = timetable->timestamps[i].time; - /* printf("a ptr %d\n", a->ptr);*/ - } -} -/*---------------------------------------------------------------------------*/ -void -timetable_aggregate_compute_categories(struct timetable_aggregate *a, - struct timetable *timetable) -{ - unsigned int i; - int j; - rtimer_clock_t t; - uint16_t categories[XXX_HACK_MAX_CATEGORIES]; - int categories_ptr = 0; - - t = timetable->timestamps[0].time; - - for(i = 1; i < *timetable->ptr; ++i) { - struct timetable_aggregate_entry *entry; - uint16_t cat; - - /* printf("category_timetable_aggregate_compute %s %d\n", - timetable->timestamps[i - 1].id, i);*/ - cat = (timetable->timestamps[i - 1].id[0] << 8) + - (timetable->timestamps[i - 1].id[1] & 0xff); - entry = find_aggregate_category(a, cat); - if(entry == NULL) { - /* The list is full, skip this entry */ - /* printf("category_timetable_aggregate_compute: list full\n");*/ - } else if(entry->id == NULL) { - /* The category was not found in the list, so we add it. */ - entry->id = timetable->timestamps[i - 1].id; - entry->time = (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - entry->episodes = 1; - /* printf("New category %c%c time %lu\n", - timetable->timestamps[i - 1].id[0], - timetable->timestamps[i - 1].id[1], entry->time);*/ - } else { - - entry->time += (unsigned long)(timetable->timestamps[i].time - t - - timetable_timestamp_time); - /* printf("Adding time to %c%c time %lu\n", - timetable->timestamps[i - 1].id[0], - timetable->timestamps[i - 1].id[1], entry->time);*/ - - /* Make sure that we only update the episodes of each category - once per run. We keep track of all updated categories in the - "categories" array. If the category is already present in the - array, we do not update it. Otherwise, we insert the category - in the array and update the episodes counter of the - category. */ - - for(j = 0; j < categories_ptr; ++j) { - if(categories[j] == cat) { - break; - } - } - if(j == categories_ptr) { - categories[j] = cat; - categories_ptr++; - entry->episodes++; - } - } - t = timetable->timestamps[i].time; - } -} -/*---------------------------------------------------------------------------*/ diff --git a/timetable-aggregate.h b/timetable-aggregate.h deleted file mode 100644 index 969f81c0d..000000000 --- a/timetable-aggregate.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A brief description of what this file is. - * \author - * Adam Dunkels - */ - -#ifndef __TIMETABLE_AGGREGATE_H__ -#define __TIMETABLE_AGGREGATE_H__ - -#include "sys/timetable.h" -#include "sys/cc.h" - -struct timetable_aggregate_entry { - const char *id; - unsigned short episodes; - unsigned long time; -}; - -struct timetable_aggregate { - struct timetable_aggregate_entry *entries; - int ptr; - const int size; -}; - - -#define TIMETABLE_AGGREGATE_DECLARE(name) \ -struct timetable_aggregate name - - -#define TIMETABLE_AGGREGATE(name, size) \ -static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \ -static struct timetable_aggregate name = { \ - CC_CONCAT(name,_entries), \ - 0, \ - size \ -} - -#define TIMETABLE_AGGREGATE_NONSTATIC(name, size) \ -static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \ -struct timetable_aggregate name = { \ - CC_CONCAT(name,_entries), \ - 0, \ - size \ -} - -void timetable_aggregate_print_detailed(struct timetable_aggregate *a); - -void timetable_aggregate_print_categories(struct timetable_aggregate *a); - -void timetable_aggregate_reset(struct timetable_aggregate *a); - -void timetable_aggregate_compute_detailed(struct timetable_aggregate *a, - struct timetable *timetable); -void timetable_aggregate_compute_categories(struct timetable_aggregate *a, - struct timetable *timetable); - - - -#endif /* __TIMETABLE_AGGREGATE_H__ */ diff --git a/timetable.c b/timetable.c deleted file mode 100644 index 40766a62c..000000000 --- a/timetable.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Implementation of timetable, a data structure containing timestamps for events - * \author - * Adam Dunkels - */ -#include "sys/clock.h" -#include "sys/timetable.h" - -#include - -rtimer_clock_t timetable_timestamp_time; - - -/*---------------------------------------------------------------------------*/ -struct timetable_timestamp * -timetable_entry(struct timetable *t, int num) -{ - if(t == NULL) { - return NULL; - } - return &(t->timestamps[num]); -} -/*---------------------------------------------------------------------------*/ -int -timetable_ptr(struct timetable *t) -{ - return *t->ptr; -} -/*---------------------------------------------------------------------------*/ -void -timetable_clear(struct timetable *t) -{ - *t->ptr = 0; -} -/*---------------------------------------------------------------------------*/ -rtimer_clock_t -timetable_timediff(struct timetable *t, - const char *id1, const char *id2) -{ -#ifdef SDCC_mcs51 - char i; /* SDCC tracker 2982753 */ -#else - int i; -#endif - int t1, t2; - - t1 = t2 = t->size; - - for(i = *t->ptr - 1; i >= 0; --i) { - if(t->timestamps[i].id == id1) { - t1 = i; - break; - } - } - - for(i = i - 1; i >= 0; --i) { - if(t->timestamps[i].id == id2) { - t2 = i; - break; - } - } - if(t1 != t->size && t2 != t->size) { - return t->timestamps[t1].time - t->timestamps[t2].time; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -void -timetable_init(void) -{ - char dummy1, dummy2; -#define temp_size 4 - TIMETABLE_STATIC(temp); - - timetable_clear(&temp); - - /* Measure the time for taking a timestamp. */ - TIMETABLE_TIMESTAMP(temp, &dummy1); - TIMETABLE_TIMESTAMP(temp, &dummy2); - timetable_timestamp_time = timetable_timediff(&temp, &dummy1, &dummy2); -} -/*---------------------------------------------------------------------------*/ -void -timetable_print(struct timetable *t) -{ - unsigned int i; - int time; - - time = t->timestamps[0].time; - - printf("---\n"); - for(i = 1; i < *t->ptr; ++i) { - printf("%s: %u\n", t->timestamps[i - 1].id, t->timestamps[i].time - time); - time = t->timestamps[i].time; - } -} -/*---------------------------------------------------------------------------*/ diff --git a/timetable.h b/timetable.h deleted file mode 100644 index 350d3d950..000000000 --- a/timetable.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2008, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A brief description of what this file is. - * \author - * Adam Dunkels - */ - -#ifndef __TIMETABLE_H__ -#define __TIMETABLE_H__ - -#include "sys/cc.h" -#include "sys/rtimer.h" - - -struct timetable_timestamp { - const char *id; - rtimer_clock_t time; -#if TIMETABLE_WITH_TYPE - uint8_t type; -#endif /* TIMETABLE_WITH_TYPE */ -}; -struct timetable { - struct timetable_timestamp *timestamps; - const int size; - unsigned int * const ptr; -}; - -#define TIMETABLE_NONSTATIC(name) \ -struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ -unsigned int CC_CONCAT(name,_ptr); \ -struct timetable name = { \ - CC_CONCAT(name,_timestamps), \ - CC_CONCAT(name,_size), \ - &CC_CONCAT(name,_ptr)} - -#define TIMETABLE_STATIC(name) \ -static struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \ -static unsigned int CC_CONCAT(name,_ptr); \ -static struct timetable name = { \ - CC_CONCAT(name,_timestamps), \ - CC_CONCAT(name,_size), \ - &CC_CONCAT(name,_ptr)} - -#define TIMETABLE_DECLARE(name) \ -extern unsigned int CC_CONCAT(name,_ptr); \ -extern struct timetable_timestamp CC_CONCAT(name, _timestamps)[CC_CONCAT(name,_size)]; \ -extern struct timetable name - -#define TIMETABLE(name) TIMETABLE_STATIC(name) - -#define TIMETABLE_TIMESTAMP(name, str) \ -do { \ - CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ - CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ - CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ - CC_CONCAT(name,_size); \ -} while(0) - -#if TIMETABLE_WITH_TYPE -#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) \ -do { \ - CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \ - CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].type = t; \ - CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \ - CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \ - CC_CONCAT(name,_size); \ -} while(0) -#else /* TIMETABLE_WITH_TYPE */ -#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) TIMETABLE_TIMESTAMP(name, str) -#endif /* TIMETABLE_WITH_TYPE */ - - -#define TIMETABLE_RESUME(name,num) \ - TIMETABLE_TIMESTAMP(CC_CONCAT(name,_timestamps[num].id)) - -#define TIMETABLE_COND_TIMESTAMP(cond,name,id) \ - do { if(cond) { \ - TIMETABLE_TIMESTAMP(id); \ - } while(0) - -#define TIMETABLE_COND_RESUME(cond,name,num) \ - TIMETABLE_COND_TIMESTAMP(cond,name, \ - CC_CONCAT(name,_timestamps[num].id)) - -#define TIMETABLE_ENTRY(name, num) CC_CONCAT(name,_timestamps)[num] -#define TIMETABLE_PTR(name) CC_CONCAT(name,_ptr) - -/** - * The time for taking a timestamp. - */ -extern rtimer_clock_t timetable_timestamp_time; - - -struct timetable_timestamp *timetable_entry(struct timetable *t, - int num); -int timetable_ptr(struct timetable *t); - -void timetable_clear(struct timetable *t); -rtimer_clock_t timetable_timediff(struct timetable *t, - const char *id1, const char *id2); -void timetable_init(void); - -void timetable_print(struct timetable *t); - -#include "sys/timetable-aggregate.h" - -#endif /* __TIMETABLE_H__ */ From 6e09c333e2d99f026194603fd8742e7c5259e75d Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Sun, 24 Nov 2013 16:57:08 +0100 Subject: [PATCH 120/146] A massive all-tree automated update of all double inclusion guard #defines that changes from using two underscores as a prefix, which are reserved, to not using two underscores as a prefix --- arg.h | 6 +++--- autostart.h | 6 +++--- cc.h | 6 +++--- clock.h | 6 +++--- compower.h | 6 +++--- ctimer.h | 6 +++--- dsc.h | 6 +++--- energest.h | 6 +++--- etimer.h | 6 +++--- lc-addrlabels.h | 6 +++--- lc-switch.h | 6 +++--- lc.h | 6 +++--- loader.h | 6 +++--- log.h | 6 +++--- mt.h | 6 +++--- node-id.h | 6 +++--- process.h | 6 +++--- procinit.h | 6 +++--- pt-sem.h | 6 +++--- pt.h | 6 +++--- rtimer.h | 6 +++--- stimer.h | 6 +++--- subprocess.h | 6 +++--- timer.h | 6 +++--- 24 files changed, 72 insertions(+), 72 deletions(-) diff --git a/arg.h b/arg.h index df1ceb67d..6c2d0eb19 100644 --- a/arg.h +++ b/arg.h @@ -31,12 +31,12 @@ * * */ -#ifndef __ARG_H__ -#define __ARG_H__ +#ifndef ARG_H_ +#define ARG_H_ void arg_init(void); char *arg_alloc(char size); void arg_free(char *arg); -#endif /* __ARG_H__ */ +#endif /* ARG_H_ */ diff --git a/autostart.h b/autostart.h index 46c3333b8..a88dbd6b6 100644 --- a/autostart.h +++ b/autostart.h @@ -37,8 +37,8 @@ * Adam Dunkels */ -#ifndef __AUTOSTART_H__ -#define __AUTOSTART_H__ +#ifndef AUTOSTART_H_ +#define AUTOSTART_H_ #include "sys/process.h" @@ -59,4 +59,4 @@ CLIF extern struct process * const autostart_processes[]; void autostart_start(struct process * const processes[]); void autostart_exit(struct process * const processes[]); -#endif /* __AUTOSTART_H__ */ +#endif /* AUTOSTART_H_ */ diff --git a/cc.h b/cc.h index f4a6105a1..2fd9c2208 100644 --- a/cc.h +++ b/cc.h @@ -41,8 +41,8 @@ * * */ -#ifndef __CC_H__ -#define __CC_H__ +#ifndef CC_H_ +#define CC_H_ #include "contiki-conf.h" @@ -136,4 +136,4 @@ */ #define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) -#endif /* __CC_H__ */ +#endif /* CC_H_ */ diff --git a/clock.h b/clock.h index 986f6ae33..bbf5988ee 100644 --- a/clock.h +++ b/clock.h @@ -65,8 +65,8 @@ * Author: Adam Dunkels * */ -#ifndef __CLOCK_H__ -#define __CLOCK_H__ +#ifndef CLOCK_H_ +#define CLOCK_H_ #include "contiki-conf.h" @@ -139,7 +139,7 @@ int clock_fine_max(void); unsigned short clock_fine(void); void clock_delay(unsigned int delay); -#endif /* __CLOCK_H__ */ +#endif /* CLOCK_H_ */ /** @} */ /** @} */ diff --git a/compower.h b/compower.h index 60866f660..202065eb3 100644 --- a/compower.h +++ b/compower.h @@ -51,8 +51,8 @@ * Adam Dunkels */ -#ifndef __COMPOWER_H__ -#define __COMPOWER_H__ +#ifndef COMPOWER_H_ +#define COMPOWER_H_ /** * \brief An activity record that contains power consumption information for a specific communication activity. @@ -129,7 +129,7 @@ void compower_attrconv(struct compower_activity *a); */ void compower_accumulate_attrs(struct compower_activity *a); -#endif /* __COMPOWER_H__ */ +#endif /* COMPOWER_H_ */ /** @} */ /** @} */ diff --git a/ctimer.h b/ctimer.h index bc7bf2f98..27311ddfb 100644 --- a/ctimer.h +++ b/ctimer.h @@ -51,8 +51,8 @@ * Adam Dunkels */ -#ifndef __CTIMER_H__ -#define __CTIMER_H__ +#ifndef CTIMER_H_ +#define CTIMER_H_ #include "sys/etimer.h" @@ -143,6 +143,6 @@ int ctimer_expired(struct ctimer *c); */ void ctimer_init(void); -#endif /* __CTIMER_H__ */ +#endif /* CTIMER_H_ */ /** @} */ /** @} */ diff --git a/dsc.h b/dsc.h index 75ba4d9a9..5c3994741 100644 --- a/dsc.h +++ b/dsc.h @@ -58,8 +58,8 @@ * * */ -#ifndef __DSC_H__ -#define __DSC_H__ +#ifndef DSC_H_ +#define DSC_H_ #include "ctk/ctk.h" @@ -137,4 +137,4 @@ struct dsc { /** @} */ -#endif /* _DSC_H__ */ +#endif /*DSC_H__ */ diff --git a/energest.h b/energest.h index 70b46ab6c..6d43aaa11 100644 --- a/energest.h +++ b/energest.h @@ -37,8 +37,8 @@ * Adam Dunkels */ -#ifndef __ENERGEST_H__ -#define __ENERGEST_H__ +#ifndef ENERGEST_H_ +#define ENERGEST_H_ #include "sys/rtimer.h" @@ -126,4 +126,4 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI #define ENERGEST_OFF_LEVEL(type,level) do { } while(0) #endif /* ENERGEST_CONF_ON */ -#endif /* __ENERGEST_H__ */ +#endif /* ENERGEST_H_ */ diff --git a/etimer.h b/etimer.h index f46e24c13..10452dc2a 100644 --- a/etimer.h +++ b/etimer.h @@ -59,8 +59,8 @@ * Author: Adam Dunkels * */ -#ifndef __ETIMER_H__ -#define __ETIMER_H__ +#ifndef ETIMER_H_ +#define ETIMER_H_ #include "sys/timer.h" #include "sys/process.h" @@ -236,6 +236,6 @@ clock_time_t etimer_next_expiration_time(void); /** @} */ PROCESS_NAME(etimer_process); -#endif /* __ETIMER_H__ */ +#endif /* ETIMER_H_ */ /** @} */ /** @} */ diff --git a/lc-addrlabels.h b/lc-addrlabels.h index b7f7028e4..fc86f92ce 100644 --- a/lc-addrlabels.h +++ b/lc-addrlabels.h @@ -56,8 +56,8 @@ * implementation. */ -#ifndef __LC_ADDRLABELS_H__ -#define __LC_ADDRLABELS_H__ +#ifndef LC_ADDRLABELS_H_ +#define LC_ADDRLABELS_H_ /** \hideinitializer */ typedef void * lc_t; @@ -77,5 +77,5 @@ typedef void * lc_t; #define LC_END(s) -#endif /* __LC_ADDRLABELS_H__ */ +#endif /* LC_ADDRLABELS_H_ */ /** @} */ diff --git a/lc-switch.h b/lc-switch.h index 6ffb6c763..8fcef3449 100644 --- a/lc-switch.h +++ b/lc-switch.h @@ -53,8 +53,8 @@ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html */ -#ifndef __LC_SWITCH_H__ -#define __LC_SWITCH_H__ +#ifndef LC_SWITCH_H_ +#define LC_SWITCH_H_ /* WARNING! lc implementation using switch() does not work if an LC_SET() is done within another switch() statement! */ @@ -70,6 +70,6 @@ typedef unsigned short lc_t; #define LC_END(s) } -#endif /* __LC_SWITCH_H__ */ +#endif /* LC_SWITCH_H_ */ /** @} */ diff --git a/lc.h b/lc.h index 2da0e4a9e..3f57d879c 100644 --- a/lc.h +++ b/lc.h @@ -115,8 +115,8 @@ */ #endif /* DOXYGEN */ -#ifndef __LC_H__ -#define __LC_H__ +#ifndef LC_H_ +#define LC_H_ #ifdef LC_CONF_INCLUDE #include LC_CONF_INCLUDE @@ -124,7 +124,7 @@ #include "sys/lc-switch.h" #endif /* LC_CONF_INCLUDE */ -#endif /* __LC_H__ */ +#endif /* LC_H_ */ /** @} */ /** @} */ diff --git a/loader.h b/loader.h index 3b8656636..e54629aff 100644 --- a/loader.h +++ b/loader.h @@ -51,8 +51,8 @@ * * */ -#ifndef __LOADER_H__ -#define __LOADER_H__ +#ifndef LOADER_H_ +#define LOADER_H_ /* Errors that the LOADER_LOAD() function may return: */ @@ -125,7 +125,7 @@ #define LOADER_UNLOAD_DSC(dsc) #endif /* LOADER_UNLOAD */ -#endif /* __LOADER_H__ */ +#endif /* LOADER_H_ */ /** @} */ /** @} */ diff --git a/log.h b/log.h index 93aecb765..c6bc24737 100644 --- a/log.h +++ b/log.h @@ -31,8 +31,8 @@ * Author: Adam Dunkels * */ -#ifndef __LOG_H__ -#define __LOG_H__ +#ifndef LOG_H_ +#define LOG_H_ #include "contiki-conf.h" @@ -42,4 +42,4 @@ void log_message(const char *part1, const char *part2); #define log_message(p1, p2) #endif /* LOG_CONF_ENABLED */ -#endif /* __LOG_H__ */ +#endif /* LOG_H_ */ diff --git a/mt.h b/mt.h index 4d53fff4a..0e67dee0d 100644 --- a/mt.h +++ b/mt.h @@ -79,8 +79,8 @@ * Adam Dunkels * */ -#ifndef __MT_H__ -#define __MT_H__ +#ifndef MT_H_ +#define MT_H_ #include "contiki.h" @@ -267,4 +267,4 @@ void mt_stop(struct mt_thread *thread); /** @} */ /** @} */ -#endif /* __MT_H__ */ +#endif /* MT_H_ */ diff --git a/node-id.h b/node-id.h index f0435228a..0b6ebe6b1 100644 --- a/node-id.h +++ b/node-id.h @@ -32,12 +32,12 @@ * */ -#ifndef __NODE_ID_H__ -#define __NODE_ID_H__ +#ifndef NODE_ID_H_ +#define NODE_ID_H_ void node_id_restore(void); void node_id_burn(unsigned short node_id); extern unsigned short node_id; -#endif /* __NODE_ID_H__ */ +#endif /* NODE_ID_H_ */ diff --git a/process.h b/process.h index 63fa75e14..7063ee024 100644 --- a/process.h +++ b/process.h @@ -50,8 +50,8 @@ * Adam Dunkels * */ -#ifndef __PROCESS_H__ -#define __PROCESS_H__ +#ifndef PROCESS_H_ +#define PROCESS_H_ #include "sys/pt.h" #include "sys/cc.h" @@ -525,7 +525,7 @@ CCIF extern struct process *process_list; #define PROCESS_LIST() process_list -#endif /* __PROCESS_H__ */ +#endif /* PROCESS_H_ */ /** @} */ /** @} */ diff --git a/procinit.h b/procinit.h index 134b8d7d6..5e65a6de6 100644 --- a/procinit.h +++ b/procinit.h @@ -29,8 +29,8 @@ * This file is part of the Contiki operating system. * */ -#ifndef __PROCINIT_H__ -#define __PROCINIT_H__ +#ifndef PROCINIT_H_ +#define PROCINIT_H_ #include "sys/process.h" @@ -41,4 +41,4 @@ const struct process *procinit[] = {__VA_ARGS__, NULL} void procinit_init(void); -#endif /* __PROCINIT_H__ */ +#endif /* PROCINIT_H_ */ diff --git a/pt-sem.h b/pt-sem.h index 3f8a4f9e9..75d66452a 100644 --- a/pt-sem.h +++ b/pt-sem.h @@ -156,8 +156,8 @@ PT_THREAD(driver_thread(struct pt *pt)) * */ -#ifndef __PT_SEM_H__ -#define __PT_SEM_H__ +#ifndef PT_SEM_H_ +#define PT_SEM_H_ #include "sys/pt.h" @@ -220,7 +220,7 @@ struct pt_sem { */ #define PT_SEM_SIGNAL(pt, s) ++(s)->count -#endif /* __PT_SEM_H__ */ +#endif /* PT_SEM_H_ */ /** @} */ /** @} */ diff --git a/pt.h b/pt.h index 9433a1086..c9549119e 100644 --- a/pt.h +++ b/pt.h @@ -45,8 +45,8 @@ * */ -#ifndef __PT_H__ -#define __PT_H__ +#ifndef PT_H_ +#define PT_H_ #include "sys/lc.h" @@ -317,6 +317,6 @@ struct pt { /** @} */ -#endif /* __PT_H__ */ +#endif /* PT_H_ */ /** @} */ diff --git a/rtimer.h b/rtimer.h index 113dc7ded..7f393947d 100644 --- a/rtimer.h +++ b/rtimer.h @@ -49,8 +49,8 @@ * This file is part of the Contiki operating system. * */ -#ifndef __RTIMER_H__ -#define __RTIMER_H__ +#ifndef RTIMER_H_ +#define RTIMER_H_ #include "contiki-conf.h" @@ -150,7 +150,7 @@ void rtimer_arch_schedule(rtimer_clock_t t); #define RTIMER_SECOND RTIMER_ARCH_SECOND -#endif /* __RTIMER_H__ */ +#endif /* RTIMER_H_ */ /** @} */ /** @} */ diff --git a/stimer.h b/stimer.h index 16711e604..3615fc58c 100644 --- a/stimer.h +++ b/stimer.h @@ -65,8 +65,8 @@ * Author: Adam Dunkels , Nicolas Tsiftes * */ -#ifndef __STIMER_H__ -#define __STIMER_H__ +#ifndef STIMER_H_ +#define STIMER_H_ #include "sys/clock.h" @@ -91,7 +91,7 @@ unsigned long stimer_remaining(struct stimer *t); unsigned long stimer_elapsed(struct stimer *t); -#endif /* __STIMER_H__ */ +#endif /* STIMER_H_ */ /** @} */ /** @} */ diff --git a/subprocess.h b/subprocess.h index 9f2761810..d7b3760a4 100644 --- a/subprocess.h +++ b/subprocess.h @@ -49,8 +49,8 @@ * Adam Dunkels */ -#ifndef __SUBPROCESS_H__ -#define __SUBPROCESS_H__ +#ifndef SUBPROCESS_H_ +#define SUBPROCESS_H_ #define SUBPROCESS_BEGIN(strname) \ { \ @@ -66,4 +66,4 @@ } \ } -#endif /* __SUBPROCESS_H__ */ +#endif /* SUBPROCESS_H_ */ diff --git a/timer.h b/timer.h index 3bfdfa81f..06a25524c 100644 --- a/timer.h +++ b/timer.h @@ -70,8 +70,8 @@ * Author: Adam Dunkels * */ -#ifndef __TIMER_H__ -#define __TIMER_H__ +#ifndef TIMER_H_ +#define TIMER_H_ #include "sys/clock.h" @@ -95,7 +95,7 @@ CCIF int timer_expired(struct timer *t); clock_time_t timer_remaining(struct timer *t); -#endif /* __TIMER_H__ */ +#endif /* TIMER_H_ */ /** @} */ /** @} */ From baae793579ed80a0299cac79b135784b7d428964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Fri, 30 May 2014 11:01:20 +0200 Subject: [PATCH 121/146] Closing doxygen groups --- rtimer.c | 2 ++ subprocess.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/rtimer.c b/rtimer.c index 60b8b37c1..282c8d86b 100644 --- a/rtimer.c +++ b/rtimer.c @@ -105,3 +105,5 @@ rtimer_run_next(void) return; } /*---------------------------------------------------------------------------*/ + +/** @}*/ diff --git a/subprocess.h b/subprocess.h index d7b3760a4..ebb95501e 100644 --- a/subprocess.h +++ b/subprocess.h @@ -67,3 +67,6 @@ } #endif /* SUBPROCESS_H_ */ + +/** @}*/ +/** @}*/ From 72f35700703ace5e595cd38d7cfa0f57ae104a21 Mon Sep 17 00:00:00 2001 From: Ian Martin Date: Wed, 11 Jun 2014 18:44:59 -0400 Subject: [PATCH 122/146] Make protothread semaphores interrupt-safe. --- pt-sem.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pt-sem.h b/pt-sem.h index 75d66452a..27effa57a 100644 --- a/pt-sem.h +++ b/pt-sem.h @@ -162,9 +162,11 @@ PT_THREAD(driver_thread(struct pt *pt)) #include "sys/pt.h" struct pt_sem { - unsigned int count; + unsigned int head, tail; }; +#define PT_SEM_COUNT(s) ((s)->head - (s)->tail) + /** * Initialize a semaphore * @@ -179,7 +181,11 @@ struct pt_sem { * \param c (unsigned int) The initial count of the semaphore. * \hideinitializer */ -#define PT_SEM_INIT(s, c) (s)->count = c +#define PT_SEM_INIT(s, c) \ + do { \ + (s)->tail = 0; \ + (s)->head = (c); \ + } while(0) /** * Wait for a semaphore @@ -199,8 +205,8 @@ struct pt_sem { */ #define PT_SEM_WAIT(pt, s) \ do { \ - PT_WAIT_UNTIL(pt, (s)->count > 0); \ - --(s)->count; \ + PT_WAIT_UNTIL(pt, PT_SEM_COUNT(s) > 0); \ + ++(s)->tail; \ } while(0) /** @@ -218,7 +224,7 @@ struct pt_sem { * * \hideinitializer */ -#define PT_SEM_SIGNAL(pt, s) ++(s)->count +#define PT_SEM_SIGNAL(pt, s) (++(s)->head) #endif /* PT_SEM_H_ */ From 9ef6834b2e8bfd4c7434800323f94cc03213b7cc Mon Sep 17 00:00:00 2001 From: Roy Scheefhals Date: Thu, 12 Jun 2014 13:40:28 +0200 Subject: [PATCH 123/146] Changed the parameter 'char * data' of process_start to the type process_data_t. This was an artifact when the choice was made to use the void * type for the data parameter in processes. Changed parameter 'void * data' of process_post_synch to process_data_t for consistency. Checked all the uses of process_start() in contiki and fixed casts of the data parameter. --- process.c | 4 ++-- process.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/process.c b/process.c index 8a7496d75..ef28f80f4 100644 --- a/process.c +++ b/process.c @@ -96,7 +96,7 @@ process_alloc_event(void) } /*---------------------------------------------------------------------------*/ void -process_start(struct process *p, const char *arg) +process_start(struct process *p, process_data_t data) { struct process *q; @@ -117,7 +117,7 @@ process_start(struct process *p, const char *arg) PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p)); /* Post a synchronous initialization event to the process. */ - process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg); + process_post_synch(p, PROCESS_EVENT_INIT, data); } /*---------------------------------------------------------------------------*/ static void diff --git a/process.h b/process.h index 7063ee024..43547f3bd 100644 --- a/process.h +++ b/process.h @@ -339,7 +339,7 @@ struct process { * process * */ -CCIF void process_start(struct process *p, const char *arg); +CCIF void process_start(struct process *p, process_data_t data); /** * Post an asynchronous event. @@ -362,7 +362,7 @@ CCIF void process_start(struct process *p, const char *arg); * \retval PROCESS_ERR_FULL The event queue was full and the event could * not be posted. */ -CCIF int process_post(struct process *p, process_event_t ev, void* data); +CCIF int process_post(struct process *p, process_event_t ev, process_data_t data); /** * Post a synchronous event to a process. @@ -375,7 +375,7 @@ CCIF int process_post(struct process *p, process_event_t ev, void* data); * with the event. */ CCIF void process_post_synch(struct process *p, - process_event_t ev, void* data); + process_event_t ev, process_data_t data); /** * \brief Cause a process to exit From ddda331847bbfd65095b4f7b1002b4b979d53bbc Mon Sep 17 00:00:00 2001 From: Enrico Joerns Date: Wed, 4 Jun 2014 15:00:22 +0200 Subject: [PATCH 124/146] [core] timer: Added note that timer_reset must not be executed before timer expired Should save some users debugging time while adding no computation overhead that would be needed for range checks --- timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/timer.c b/timer.c index d13b61f98..47ff2d1c5 100644 --- a/timer.c +++ b/timer.c @@ -76,8 +76,9 @@ timer_set(struct timer *t, clock_time_t interval) * function will cause the timer to be stable over time, unlike the * timer_restart() function. * - * \param t A pointer to the timer. + * \note Must not be executed before timer expired * + * \param t A pointer to the timer. * \sa timer_restart() */ void From e358cd07747482e0ac412a474f8808d5c054e566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Thu, 19 Jun 2014 14:30:33 +0200 Subject: [PATCH 125/146] Correct several doxygen tags (\file) --- lc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lc.h b/lc.h index 3f57d879c..6062a21e2 100644 --- a/lc.h +++ b/lc.h @@ -51,7 +51,7 @@ */ /** - * \file lc.h + * \file core/sys/lc.h * Local continuations * \author * Adam Dunkels From 06ee182d3182704a3a473e2c9fdee75fde85c9a3 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 10 Nov 2014 13:41:33 +0100 Subject: [PATCH 126/146] Remove unnecessary list_remove in ctimer.c (list_add automatically removes first) --- ctimer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ctimer.c b/ctimer.c index e6090a9a8..9c3a9b6f3 100644 --- a/ctimer.c +++ b/ctimer.c @@ -111,7 +111,6 @@ ctimer_set(struct ctimer *c, clock_time_t t, c->etimer.timer.interval = t; } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ @@ -124,7 +123,6 @@ ctimer_reset(struct ctimer *c) PROCESS_CONTEXT_END(&ctimer_process); } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ @@ -137,7 +135,6 @@ ctimer_restart(struct ctimer *c) PROCESS_CONTEXT_END(&ctimer_process); } - list_remove(ctimer_list, c); list_add(ctimer_list, c); } /*---------------------------------------------------------------------------*/ From a920af0d5a4396837aab927db514094d5aa51d5b Mon Sep 17 00:00:00 2001 From: Enrico Joerns Date: Sat, 8 Nov 2014 01:15:42 +0100 Subject: [PATCH 127/146] [doc] Give files a common structure by placing license first (partial) Followed by doxyen file and group tags. This patch is only a first attempt to make provide a clean structure, many more files require rework, too. --- arg.c | 62 +++++++++++++++++++++---------------------- cc.h | 21 ++++++++------- clock.h | 67 +++++++++++++++++++++++----------------------- compower.c | 10 +++---- compower.h | 28 ++++++++++---------- ctimer.c | 10 +++---- ctimer.h | 28 ++++++++++---------- dsc.h | 55 +++++++++++++++++++------------------- etimer.c | 24 ++++++++--------- etimer.h | 56 +++++++++++++++++++-------------------- loader.h | 41 ++++++++++++++-------------- rtimer.c | 27 +++++++++---------- rtimer.h | 41 ++++++++++++++-------------- stimer.c | 24 ++++++++--------- stimer.h | 68 +++++++++++++++++++++++------------------------ timer.c | 24 ++++++++--------- timer.h | 78 +++++++++++++++++++++++++++--------------------------- 17 files changed, 334 insertions(+), 330 deletions(-) diff --git a/arg.c b/arg.c index 080dea9bb..090034380 100644 --- a/arg.c +++ b/arg.c @@ -1,34 +1,3 @@ -/** - * \file - * Argument buffer for passing arguments when starting processes - * \author Adam Dunkels - */ - -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup arg Argument buffer - * @{ - * - * The argument buffer can be used when passing an argument from an - * exiting process to a process that has not been created yet. Since - * the exiting process will have exited when the new process is - * started, the argument cannot be passed in any of the processes' - * addres spaces. In such situations, the argument buffer can be used. - * - * The argument buffer is statically allocated in memory and is - * globally accessible to all processes. - * - * An argument buffer is allocated with the arg_alloc() function and - * deallocated with the arg_free() function. The arg_free() function - * is designed so that it can take any pointer, not just an argument - * buffer pointer. If the pointer to arg_free() is not an argument - * buffer, the function does nothing. - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -63,6 +32,37 @@ * */ +/** + * \file + * Argument buffer for passing arguments when starting processes + * \author Adam Dunkels + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup arg Argument buffer + * @{ + * + * The argument buffer can be used when passing an argument from an + * exiting process to a process that has not been created yet. Since + * the exiting process will have exited when the new process is + * started, the argument cannot be passed in any of the processes' + * addres spaces. In such situations, the argument buffer can be used. + * + * The argument buffer is statically allocated in memory and is + * globally accessible to all processes. + * + * An argument buffer is allocated with the arg_alloc() function and + * deallocated with the arg_free() function. The arg_free() function + * is designed so that it can take any pointer, not just an argument + * buffer pointer. If the pointer to arg_free() is not an argument + * buffer, the function does nothing. + */ + #include "contiki.h" #include "sys/arg.h" diff --git a/cc.h b/cc.h index 2fd9c2208..53a5af4db 100644 --- a/cc.h +++ b/cc.h @@ -1,13 +1,3 @@ -/** - * \file - * Default definitions of C compiler quirk work-arounds. - * \author Adam Dunkels - * - * This file is used for making use of extra functionality of some C - * compilers used for Contiki, and defining work-arounds for various - * quirks and problems with some other C compilers. - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -41,6 +31,17 @@ * * */ + +/** + * \file + * Default definitions of C compiler quirk work-arounds. + * \author Adam Dunkels + * + * This file is used for making use of extra functionality of some C + * compilers used for Contiki, and defining work-arounds for various + * quirks and problems with some other C compilers. + */ + #ifndef CC_H_ #define CC_H_ diff --git a/clock.h b/clock.h index bbf5988ee..46232273e 100644 --- a/clock.h +++ b/clock.h @@ -1,3 +1,37 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + */ + /** \addtogroup sys * @{ */ @@ -32,39 +66,6 @@ * @{ */ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ #ifndef CLOCK_H_ #define CLOCK_H_ diff --git a/compower.c b/compower.c index b920c3e70..02a0f3c4c 100644 --- a/compower.c +++ b/compower.c @@ -1,8 +1,3 @@ -/** - * \addtogroup compower - * @{ - */ - /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup compower + * @{ + */ + #include "contiki-conf.h" #include "sys/energest.h" #include "sys/compower.h" diff --git a/compower.h b/compower.h index 202065eb3..03d984193 100644 --- a/compower.h +++ b/compower.h @@ -1,17 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup compower Communication power accounting - * @{ - * - * The compower module accumulates power consumption information and - * attributes it to communication activities. Examples of - * communication activities are packet transmission, packet reception, - * and idle listening. - * - */ - /* * Copyright (c) 2009, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,20 @@ * Adam Dunkels */ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup compower Communication power accounting + * @{ + * + * The compower module accumulates power consumption information and + * attributes it to communication activities. Examples of + * communication activities are packet transmission, packet reception, + * and idle listening. + * + */ + #ifndef COMPOWER_H_ #define COMPOWER_H_ diff --git a/ctimer.c b/ctimer.c index e6090a9a8..ebf5dba89 100644 --- a/ctimer.c +++ b/ctimer.c @@ -1,8 +1,3 @@ -/** - * \addtogroup ctimer - * @{ - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -42,6 +37,11 @@ * Adam Dunkels */ +/** + * \addtogroup ctimer + * @{ + */ + #include "sys/ctimer.h" #include "contiki.h" #include "lib/list.h" diff --git a/ctimer.h b/ctimer.h index 27311ddfb..bebe8a532 100644 --- a/ctimer.h +++ b/ctimer.h @@ -1,17 +1,3 @@ -/** - * \addtogroup sys - * @{ - */ - -/** - * \defgroup ctimer Callback timer - * @{ - * - * The ctimer module provides a timer mechanism that calls a specified - * C function when a ctimer expires. - * - */ - /* * Copyright (c) 2006, Swedish Institute of Computer Science. * All rights reserved. @@ -51,6 +37,20 @@ * Adam Dunkels */ +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup ctimer Callback timer + * @{ + * + * The ctimer module provides a timer mechanism that calls a specified + * C function when a ctimer expires. + * + */ + #ifndef CTIMER_H_ #define CTIMER_H_ diff --git a/dsc.h b/dsc.h index 5c3994741..ad7632390 100644 --- a/dsc.h +++ b/dsc.h @@ -1,30 +1,3 @@ -/** - * \file - * Declaration of the DSC program description structure. - * \author Adam Dunkels - * - */ - -/** - * \addtogroup loader - * @{ - */ - -/** - * \page dsc The program description structure - * - * The Contiki DSC structure is used for describing programs. It - * includes a string describing the program, the name of the program - * file on disk (or a pointer to the programs initialization function - * for systems without disk support), a bitmap icon and a text version - * of the same icon. - * - * The DSC is saved into a file which can be loaded by programs such - * as the "Directory" application which reads all DSC files on disk - * and presents the icons and descriptions in a window. - * - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -58,6 +31,34 @@ * * */ + +/** + * \file + * Declaration of the DSC program description structure. + * \author Adam Dunkels + * + */ + +/** + * \addtogroup loader + * @{ + */ + +/** + * \page dsc The program description structure + * + * The Contiki DSC structure is used for describing programs. It + * includes a string describing the program, the name of the program + * file on disk (or a pointer to the programs initialization function + * for systems without disk support), a bitmap icon and a text version + * of the same icon. + * + * The DSC is saved into a file which can be loaded by programs such + * as the "Directory" application which reads all DSC files on disk + * and presents the icons and descriptions in a window. + * + */ + #ifndef DSC_H_ #define DSC_H_ diff --git a/etimer.c b/etimer.c index 34917aa93..719401115 100644 --- a/etimer.c +++ b/etimer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup etimer - * @{ - */ - -/** - * \file - * Event timer library implementation. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \addtogroup etimer + * @{ + */ + +/** + * \file + * Event timer library implementation. + * \author + * Adam Dunkels + */ + #include "contiki-conf.h" #include "sys/etimer.h" diff --git a/etimer.h b/etimer.h index 10452dc2a..b1f57b01a 100644 --- a/etimer.h +++ b/etimer.h @@ -1,31 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup etimer Event timers - * - * Event timers provides a way to generate timed events. An event - * timer will post an event to the process that set the timer when the - * event timer expires. - * - * An event timer is declared as a \c struct \c etimer and all access - * to the event timer is made by a pointer to the declared event - * timer. - * - * \sa \ref timer "Simple timer library" - * \sa \ref clock "Clock library" (used by the timer library) - * - * @{ - */ - - -/** - * \file - * Event timer header file. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -59,6 +31,34 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Event timer header file. + * \author + * Adam Dunkels + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup etimer Event timers + * + * Event timers provides a way to generate timed events. An event + * timer will post an event to the process that set the timer when the + * event timer expires. + * + * An event timer is declared as a \c struct \c etimer and all access + * to the event timer is made by a pointer to the declared event + * timer. + * + * \sa \ref timer "Simple timer library" + * \sa \ref clock "Clock library" (used by the timer library) + * + * @{ + */ + #ifndef ETIMER_H_ #define ETIMER_H_ diff --git a/loader.h b/loader.h index e54629aff..7d2e264c6 100644 --- a/loader.h +++ b/loader.h @@ -1,23 +1,3 @@ -/** \addtogroup sys - * @{ - */ - -/** - * \defgroup loader The Contiki program loader - * - * The Contiki program loader is an abstract interface for loading and - * starting programs. - * - * @{ - */ - -/** - * \file - * Default definitions and error values for the Contiki program loader. - * \author Adam Dunkels - * - */ - /* * Copyright (c) 2003, Adam Dunkels. * All rights reserved. @@ -51,6 +31,27 @@ * * */ + +/** + * \file + * Default definitions and error values for the Contiki program loader. + * \author Adam Dunkels + * + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup loader The Contiki program loader + * + * The Contiki program loader is an abstract interface for loading and + * starting programs. + * + * @{ + */ + #ifndef LOADER_H_ #define LOADER_H_ diff --git a/rtimer.c b/rtimer.c index 282c8d86b..cf96a17bf 100644 --- a/rtimer.c +++ b/rtimer.c @@ -1,17 +1,3 @@ -/** - * \addtogroup rt - * @{ - */ - -/** - * \file - * Implementation of the architecture-agnostic parts of the real-time timer module. - * \author - * Adam Dunkels - * - */ - - /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -44,6 +30,19 @@ * */ +/** + * \file + * Implementation of the architecture-agnostic parts of the real-time timer module. + * \author + * Adam Dunkels + * + */ + +/** + * \addtogroup rt + * @{ + */ + #include "sys/rtimer.h" #include "contiki.h" diff --git a/rtimer.h b/rtimer.h index 7f393947d..11dde5fa1 100644 --- a/rtimer.h +++ b/rtimer.h @@ -1,23 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup rt Real-time task scheduling - * - * The real-time module handles the scheduling and execution of - * real-time tasks (with predictable execution times). - * - * @{ - */ - -/** - * \file - * Header file for the real-time timer module. - * \author - * Adam Dunkels - * - */ - /* * Copyright (c) 2005, Swedish Institute of Computer Science * All rights reserved. @@ -49,6 +29,27 @@ * This file is part of the Contiki operating system. * */ + +/** + * \file + * Header file for the real-time timer module. + * \author + * Adam Dunkels + * + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup rt Real-time task scheduling + * + * The real-time module handles the scheduling and execution of + * real-time tasks (with predictable execution times). + * + * @{ + */ + #ifndef RTIMER_H_ #define RTIMER_H_ diff --git a/stimer.c b/stimer.c index 0e13651d8..86545f59e 100644 --- a/stimer.c +++ b/stimer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup stimer - * @{ - */ - -/** - * \file - * Timer of seconds library implementation. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - /* * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \file + * Timer of seconds library implementation. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/** + * \addtogroup stimer + * @{ + */ + #include "contiki-conf.h" #include "sys/clock.h" #include "sys/stimer.h" diff --git a/stimer.h b/stimer.h index 3615fc58c..6ef7db5de 100644 --- a/stimer.h +++ b/stimer.h @@ -1,37 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup stimer Seconds timer library - * - * The stimer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c stimer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The stimer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The stimer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the seconds. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - - -/** - * \file - * Second timer library header file. - * \author - * Adam Dunkels , Nicolas Tsiftes - */ - /* * Copyright (c) 2004, 2008, Swedish Institute of Computer Science. * All rights reserved. @@ -65,6 +31,40 @@ * Author: Adam Dunkels , Nicolas Tsiftes * */ + +/** + * \file + * Second timer library header file. + * \author + * Adam Dunkels , Nicolas Tsiftes + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup stimer Seconds timer library + * + * The stimer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c stimer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The stimer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The stimer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the seconds. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + #ifndef STIMER_H_ #define STIMER_H_ diff --git a/timer.c b/timer.c index d13b61f98..ea0710911 100644 --- a/timer.c +++ b/timer.c @@ -1,15 +1,3 @@ -/** - * \addtogroup timer - * @{ - */ - -/** - * \file - * Timer library implementation. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -44,6 +32,18 @@ * */ +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/** + * \addtogroup timer + * @{ + */ + #include "contiki-conf.h" #include "sys/clock.h" #include "sys/timer.h" diff --git a/timer.h b/timer.h index 06a25524c..969137507 100644 --- a/timer.h +++ b/timer.h @@ -1,42 +1,3 @@ -/** \addtogroup sys - * @{ */ - -/** - * \defgroup timer Timer library - * - * The Contiki kernel does not provide support for timed - * events. Rather, an application that wants to use timers needs to - * explicitly use the timer library. - * - * The timer library provides functions for setting, resetting and - * restarting timers, and for checking if a timer has expired. An - * application must "manually" check if its timers have expired; this - * is not done automatically. - * - * A timer is declared as a \c struct \c timer and all access to the - * timer is made by a pointer to the declared timer. - * - * \note The timer library is not able to post events when a timer - * expires. The \ref etimer "Event timers" should be used for this - * purpose. - * - * \note The timer library uses the \ref clock "Clock library" to - * measure time. Intervals should be specified in the format used by - * the clock library. - * - * \sa \ref etimer "Event timers" - * - * @{ - */ - - -/** - * \file - * Timer library header file. - * \author - * Adam Dunkels - */ - /* * Copyright (c) 2004, Swedish Institute of Computer Science. * All rights reserved. @@ -70,6 +31,45 @@ * Author: Adam Dunkels * */ + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/** \addtogroup sys + * @{ */ + +/** + * \defgroup timer Timer library + * + * The Contiki kernel does not provide support for timed + * events. Rather, an application that wants to use timers needs to + * explicitly use the timer library. + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + #ifndef TIMER_H_ #define TIMER_H_ From 76dd6c2a2c4d1279cc6e7ba6c92c58094c931c50 Mon Sep 17 00:00:00 2001 From: marcas756 Date: Sat, 22 Nov 2014 15:49:45 +0100 Subject: [PATCH 128/146] Moved thread states from module to header --- mt.c | 4 ---- mt.h | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mt.c b/mt.c index cfa8a39a5..430440fe8 100644 --- a/mt.c +++ b/mt.c @@ -46,10 +46,6 @@ #include "sys/mt.h" #include "sys/cc.h" -#define MT_STATE_READY 1 -#define MT_STATE_RUNNING 2 -#define MT_STATE_EXITED 5 - static struct mt_thread *current; /*--------------------------------------------------------------------------*/ diff --git a/mt.h b/mt.h index 0e67dee0d..f6296e24a 100644 --- a/mt.h +++ b/mt.h @@ -84,6 +84,9 @@ #include "contiki.h" +#define MT_STATE_READY 1 +#define MT_STATE_RUNNING 2 +#define MT_STATE_EXITED 5 /** * An opaque structure that is used for holding the state of a thread. From aaff5883303c1eee07f6481bffcd357b03f6837b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 15 Feb 2015 17:06:44 +0100 Subject: [PATCH 129/146] Fix warnings caused by incorrect param names / undocumented params --- dsc.h | 2 +- process.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dsc.h b/dsc.h index ad7632390..b8b70433e 100644 --- a/dsc.h +++ b/dsc.h @@ -105,7 +105,7 @@ struct dsc { * * \param prgname The name of the program on disk. * - * \param initfunc A pointer to the initialization function of the + * \param process A pointer to the initialization function of the * program. * * \param icon A pointer to the CTK icon. diff --git a/process.h b/process.h index 43547f3bd..2d15ca89c 100644 --- a/process.h +++ b/process.h @@ -335,7 +335,7 @@ struct process { * * \param p A pointer to a process structure. * - * \param arg An argument pointer that can be passed to the new + * \param data An argument pointer that can be passed to the new * process * */ From 96ed3577311202a70a694305de125c648d216566 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 15 Feb 2015 17:08:00 +0100 Subject: [PATCH 130/146] Fix warnings caused by unescaped special doxygen chars --- cc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cc.h b/cc.h index 53a5af4db..90ef3e710 100644 --- a/cc.h +++ b/cc.h @@ -133,7 +133,7 @@ * strings. * * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow - * concatenation of two #defined macros. + * concatenation of two \#defined macros. */ #define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) From 1808dc8ece052c75e637773271836df9066c5ba4 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 15 Feb 2015 17:12:50 +0100 Subject: [PATCH 131/146] Fix some unresolved references * Either by removing them * Or by resolving them --- clock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clock.h b/clock.h index 46232273e..4cbfdb223 100644 --- a/clock.h +++ b/clock.h @@ -57,7 +57,7 @@ * * \note The clock library need in many cases not be used * directly. Rather, the \ref timer "timer library", \ref etimer - * "event timers", or \ref trimer "rtimer library" should be used. + * "event timers", or \ref rtimer "rtimer library" should be used. * * \sa \ref timer "Timer library" * \sa \ref etimer "Event timers" From c18dddd88ed7c33a15f4da28176f85b99ccf3754 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 15 Feb 2015 17:35:29 +0100 Subject: [PATCH 132/146] Fix minor typos --- process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process.c b/process.c index ef28f80f4..b2ed5701c 100644 --- a/process.c +++ b/process.c @@ -267,7 +267,7 @@ do_event(void) receiver = events[fevent].p; /* Since we have seen the new event, we move pointer upwards - and decrese the number of events. */ + and decrease the number of events. */ fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS; --nevents; @@ -337,7 +337,7 @@ process_post(struct process *p, process_event_t ev, process_data_t data) if(p == PROCESS_BROADCAST) { printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current)); } else { - printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); + printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current)); } #endif /* DEBUG */ return PROCESS_ERR_FULL; From d46c560dbe85cbd3989c272e207b29192617ddb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Mon, 1 Dec 2014 13:58:34 +0100 Subject: [PATCH 133/146] Move MAX, MIN and ABS to sys/cc.h --- cc.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cc.h b/cc.h index 90ef3e710..9416ea090 100644 --- a/cc.h +++ b/cc.h @@ -127,6 +127,19 @@ #define NULL 0 #endif /* NULL */ +#ifndef MAX +#define MAX(n, m) (((n) < (m)) ? (m) : (n)) +#endif + +#ifndef MIN +#define MIN(n, m) (((n) < (m)) ? (n) : (m)) +#endif + +#ifndef ABS +#define ABS(n) (((n) < 0) ? -(n) : (n)) +#endif + + #define CC_CONCAT2(s1, s2) s1##s2 /** * A C preprocessing macro for concatenating to From 293021cc94abb234b87f7510b22417c62d075c3c Mon Sep 17 00:00:00 2001 From: Ulf Knoblich Date: Wed, 18 Mar 2015 19:43:02 +0100 Subject: [PATCH 134/146] CC2538: added support for SSI1 --- cc.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cc.h b/cc.h index 90ef3e710..6bd87c288 100644 --- a/cc.h +++ b/cc.h @@ -129,12 +129,18 @@ #define CC_CONCAT2(s1, s2) s1##s2 /** - * A C preprocessing macro for concatenating to - * strings. + * A C preprocessing macro for concatenating two preprocessor tokens. * * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow * concatenation of two \#defined macros. */ #define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) +#define CC_CONCAT_EXT_2(s1, s2) CC_CONCAT2(s1, s2) + +/** + * A C preprocessing macro for concatenating three preprocessor tokens. + */ +#define CC_CONCAT3(s1, s2, s3) s1##s2##s3 +#define CC_CONCAT_EXT_3(s1, s2, s3) CC_CONCAT3(s1, s2, s3) #endif /* CC_H_ */ From 91ea73f6b4fc337660244c6b61e23dd7941e71f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Fri, 2 Nov 2012 16:56:11 +0100 Subject: [PATCH 135/146] Add function etimer_reset_set. This new function is similar to reset, but allows to also set a new timeout. Thus long-term accuracy with changing timeouts is now possible. --- etimer.c | 8 ++++++++ etimer.h | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/etimer.c b/etimer.c index 719401115..17ac74285 100644 --- a/etimer.c +++ b/etimer.c @@ -181,6 +181,14 @@ etimer_set(struct etimer *et, clock_time_t interval) } /*---------------------------------------------------------------------------*/ void +etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval) +{ + timer_reset(&et->timer); + et->timer.interval = interval; + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void etimer_reset(struct etimer *et) { timer_reset(&et->timer); diff --git a/etimer.h b/etimer.h index b1f57b01a..ebbcfc7fd 100644 --- a/etimer.h +++ b/etimer.h @@ -114,6 +114,19 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval); */ CCIF void etimer_reset(struct etimer *et); +/** + * \brief Reset an event timer with a new interval. + * \param et A pointer to the event timer. + * \param interval The interval before the timer expires. + * + * This function very similar to etimer_reset. Opposed to + * etimer_reset it is possible to change the timout. + * This allows accurate, non-periodic timers without drift. + * + * \sa etimer_reset() + */ +void etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval); + /** * \brief Restart an event timer from the current point in time * \param et A pointer to the event timer. From 1ed30b514a5f0e8d2e2e47793822f366a399d1db Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Mon, 10 Nov 2014 17:21:18 +0100 Subject: [PATCH 136/146] CTIMER API extension to explictly state the process a ctimer belongs to --- ctimer.c | 9 ++++++++- ctimer.h | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ctimer.c b/ctimer.c index c72f247f5..66698a8e6 100644 --- a/ctimer.c +++ b/ctimer.c @@ -98,9 +98,16 @@ ctimer_init(void) void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr) +{ + ctimer_set_with_process(c, t, f, ptr, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p) { PRINTF("ctimer_set %p %u\n", c, (unsigned)t); - c->p = PROCESS_CURRENT(); + c->p = p; c->f = f; c->ptr = ptr; if(initialized) { diff --git a/ctimer.h b/ctimer.h index bebe8a532..dabf43d8a 100644 --- a/ctimer.h +++ b/ctimer.h @@ -109,10 +109,28 @@ void ctimer_restart(struct ctimer *c); * sometime in the future. When the callback timer expires, * the callback function f will be called with ptr as argument. * + * This essentially does ctimer_set_process(c, t, f, ptr, PROCESS_CURRENT()); + * */ void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr); +/** + * \brief Set a callback timer. + * \param c A pointer to the callback timer. + * \param t The interval before the timer expires. + * \param f A function to be called when the timer expires. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. + * \param p A pointer to the process the timer belongs to + * + * This function is used to set a callback timer for a time + * sometime in the future. When the callback timer expires, + * the callback function f will be called with ptr as argument. + * + */ +void ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p); + /** * \brief Stop a pending callback timer. * \param c A pointer to the pending callback timer. From d41fb14c1404530c3134fe41f28b6505fac995a5 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 3 Sep 2015 15:53:10 +0200 Subject: [PATCH 137/146] Introduce ENERGEST_SWITCH macro. It allows to switch between energest modes without running into the risk of losing a tick in the process --- energest.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/energest.h b/energest.h index 6d43aaa11..a8f445b65 100644 --- a/energest.h +++ b/energest.h @@ -105,6 +105,21 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) + +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + if (energest_local_variable_now < energest_current_time[type_off]) { \ + energest_total_time[type_off].current += RTIMER_ARCH_SECOND; \ + } \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) + #else #define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ @@ -117,13 +132,24 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI energest_current_time[type]); \ energest_current_mode[type] = 0; \ } while(0) -#endif +#define ENERGEST_SWITCH(type_off, type_on) do { \ + rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \ + if(energest_current_mode[type_off] != 0) { \ + energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \ + energest_current_time[type_off]); \ + energest_current_mode[type_off] = 0; \ + } \ + energest_current_time[type_on] = energest_local_variable_now; \ + energest_current_mode[type_on] = 1; \ + } while(0) +#endif #else /* ENERGEST_CONF_ON */ #define ENERGEST_ON(type) do { } while(0) #define ENERGEST_OFF(type) do { } while(0) #define ENERGEST_OFF_LEVEL(type,level) do { } while(0) +#define ENERGEST_SWITCH(type_off, type_on) do { } while(0) #endif /* ENERGEST_CONF_ON */ #endif /* ENERGEST_H_ */ From d7acfd4188e62f24f7f1b512bdbaa888a3498b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Fri, 28 Nov 2014 12:22:24 +0100 Subject: [PATCH 138/146] Ensure that the data in ringbuff is accessed in the right order --- cc.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cc.h b/cc.h index 06b8889ec..f105a78c3 100644 --- a/cc.h +++ b/cc.h @@ -123,6 +123,17 @@ #define CC_NO_VA_ARGS CC_CONF_VA_ARGS #endif +/** \def CC_ACCESS_NOW(x) + * This macro ensures that the access to a non-volatile variable can + * not be reordered or optimized by the compiler. + * See also https://lwn.net/Articles/508991/ - In Linux the macro is + * called ACCESS_ONCE + * The type must be passed, because the typeof-operator is a gcc + * extension + */ + +#define CC_ACCESS_NOW(type, variable) (*(volatile type *)&(variable)) + #ifndef NULL #define NULL 0 #endif /* NULL */ From dd450d3781670811dbbbb96bd642ccb514f82043 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 22 Jun 2015 09:48:39 -0600 Subject: [PATCH 139/146] Defining gcc specific macros in seperate header --- cc-gcc.h | 43 +++++++++++++++++++++++++++++++++++++++++++ cc.h | 5 +++++ 2 files changed, 48 insertions(+) create mode 100644 cc-gcc.h diff --git a/cc-gcc.h b/cc-gcc.h new file mode 100644 index 000000000..e96716327 --- /dev/null +++ b/cc-gcc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Scanimetrics - http://www.scanimetrics.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef _CC_GCC_H_ +#define _CC_GCC_H_ +#ifdef __GNUC__ + +#ifndef CC_CONF_INLINE +/* use __inline__ in case "inline" is not available for any reason */ +#define CC_CONF_INLINE __inline__ +#endif + +#define CC_CONF_ALIGN(n) __attribute__((__aligned__(n))) + +#endif /* __GNUC__ */ +#endif /* _CC_GCC_H_ */ diff --git a/cc.h b/cc.h index 06b8889ec..18965acdd 100644 --- a/cc.h +++ b/cc.h @@ -46,6 +46,7 @@ #define CC_H_ #include "contiki-conf.h" +#include "sys/cc-gcc.h" /** * Configure if the C compiler supports the "register" keyword for @@ -110,6 +111,10 @@ #define CC_INLINE #endif /* CC_CONF_INLINE */ +#ifdef CC_CONF_ALIGN +#define CC_ALIGN(n) CC_CONF_ALIGN(n) +#endif /* CC_CONF_INLINE */ + /** * Configure if the C compiler supports the assignment of struct value. */ From 3a79e7e6abbe5640387283989018dd21a677be89 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Sun, 1 Nov 2015 18:10:17 +0100 Subject: [PATCH 140/146] Removed CC_FASTCALL. CC_FASTCALL was introduced many years ago for the cc65 tool chain. It was never used for another tool chain. With https://github.com/cc65/cc65/commit/a798b1d6487c38345cf136617543671e4c85adbf the cc65 tool chain doesn't need CC_FASTCALL anymore. --- cc.h | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/cc.h b/cc.h index f105a78c3..c77bc41d7 100644 --- a/cc.h +++ b/cc.h @@ -67,24 +67,14 @@ #define CC_FUNCTION_POINTER_ARGS 0 #endif /* CC_CONF_FUNCTION_POINTER_ARGS */ -/** - * Configure if the C compiler supports fastcall function - * declarations. - */ -#ifdef CC_CONF_FASTCALL -#define CC_FASTCALL CC_CONF_FASTCALL -#else /* CC_CONF_FASTCALL */ -#define CC_FASTCALL -#endif /* CC_CONF_FASTCALL */ - /** * Configure if the C compiler have problems with const function pointers */ #ifdef CC_CONF_CONST_FUNCTION_BUG #define CC_CONST_FUNCTION -#else /* CC_CONF_FASTCALL */ +#else /* CC_CONF_CONST_FUNCTION_BUG */ #define CC_CONST_FUNCTION const -#endif /* CC_CONF_FASTCALL */ +#endif /* CC_CONF_CONST_FUNCTION_BUG */ /** * Configure work-around for unsigned char bugs with sdcc. From 76b4ca43abbfb02e23d1fe2f2ba273974693611f Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Tue, 18 Aug 2015 15:30:20 +0200 Subject: [PATCH 141/146] ContikiMAC: use RTIMER_GUARD_TIME #define to avoid accidentally scheduling a rtimer in the past on platforms with fast rtimer ticks --- rtimer.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtimer.h b/rtimer.h index 11dde5fa1..91c23b932 100644 --- a/rtimer.h +++ b/rtimer.h @@ -151,6 +151,16 @@ void rtimer_arch_schedule(rtimer_clock_t t); #define RTIMER_SECOND RTIMER_ARCH_SECOND +/* RTIMER_GUARD_TIME is the minimum amount of rtimer ticks between + the current time and the future time when a rtimer is scheduled. + Necessary to avoid accidentally scheduling a rtimer in the past + on platforms with fast rtimer ticks. Should be >= 2. */ +#ifdef RTIMER_CONF_GUARD_TIME +#define RTIMER_GUARD_TIME RTIMER_CONF_GUARD_TIME +#else /* RTIMER_CONF_GUARD_TIME */ +#define RTIMER_GUARD_TIME (RTIMER_ARCH_SECOND >> 14) +#endif /* RTIMER_CONF_GUARD_TIME */ + #endif /* RTIMER_H_ */ /** @} */ From 660a9beda0eec630a508230fb15191d702be06a6 Mon Sep 17 00:00:00 2001 From: Hardy Date: Wed, 13 Apr 2016 18:12:47 +0200 Subject: [PATCH 142/146] Removed some unnecessary statics in do_event() and process_post(). This allows the optimizer to put the corresponding variables into registers. See also discussion about other static variables: https://sourceforge.net/p/contiki/mailman/message/35010460/ --- process.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/process.c b/process.c index b2ed5701c..f98057cd3 100644 --- a/process.c +++ b/process.c @@ -245,10 +245,10 @@ do_poll(void) static void do_event(void) { - static process_event_t ev; - static process_data_t data; - static struct process *receiver; - static struct process *p; + process_event_t ev; + process_data_t data; + struct process *receiver; + struct process *p; /* * If there are any events in the queue, take the first one and walk @@ -321,7 +321,7 @@ process_nevents(void) int process_post(struct process *p, process_event_t ev, process_data_t data) { - static process_num_events_t snum; + process_num_events_t snum; if(PROCESS_CURRENT() == NULL) { PRINTF("process_post: NULL process posts event %d to process '%s', nevents %d\n", From 51f7e04451b6eb34b6f2d1a7c98764531ca74533 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 23 Apr 2016 00:19:21 +0200 Subject: [PATCH 143/146] TSCH: use RTIMER_CLOCK_DIFF to compute estimated drift, fixing a bug that would occur on 16-bit rtimer platforms --- rtimer.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rtimer.h b/rtimer.h index 91c23b932..a89ed8299 100644 --- a/rtimer.h +++ b/rtimer.h @@ -55,10 +55,12 @@ #include "contiki-conf.h" -#ifndef RTIMER_CLOCK_LT +#ifndef RTIMER_CLOCK_DIFF typedef unsigned short rtimer_clock_t; -#define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) -#endif /* RTIMER_CLOCK_LT */ +#define RTIMER_CLOCK_DIFF(a,b) ((signed short)((a)-(b))) +#endif /* RTIMER_CLOCK_DIFF */ + +#define RTIMER_CLOCK_LT(a, b) (RTIMER_CLOCK_DIFF((a),(b)) < 0) #include "rtimer-arch.h" From f98b218d9fe592874596d125d7ff0ef3a41d81b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 10 Aug 2016 03:53:58 +0200 Subject: [PATCH 144/146] mt: Remove unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- mt.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/mt.h b/mt.h index f6296e24a..6db215084 100644 --- a/mt.h +++ b/mt.h @@ -183,18 +183,9 @@ void mtarch_pstop(void); struct mt_thread { int state; - process_event_t *evptr; - process_data_t *dataptr; struct mtarch_thread thread; }; -/** - * No error. - * - * \hideinitializer - */ -#define MT_OK 1 - /** * Initializes the multithreading library. * From be0a815f42bc2fcdb7c59a1cf634540ec0f7dad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 10 Aug 2016 03:58:00 +0200 Subject: [PATCH 145/146] mt: Fix missing call to mtarch_pstop() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If mt_yield() needs it, then mt_exit() too. A thread could indeed be preempted while calling mt_exit(). Signed-off-by: Benoît Thébaudeau --- mt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mt.c b/mt.c index 430440fe8..b59d9463d 100644 --- a/mt.c +++ b/mt.c @@ -100,6 +100,7 @@ mt_yield(void) void mt_exit(void) { + mtarch_pstop(); current->state = MT_STATE_EXITED; current = NULL; mtarch_yield(); From c6111ceb9c821fb3da8b19e67e00cbd03115dc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 10 Aug 2016 04:01:11 +0200 Subject: [PATCH 146/146] mt: Fix preemption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preemption was supposed to be supported, but it had no means of safely updating the state of a thread, so mt_exec() could fail to resume a preempted thread. mt_exec() is allowed to be called only from the main Contiki thread, so the mt threads passed to it may be only ready or exited, not running. Consequently, there is no need for a distinction between the ready and running states, so merge them as a started state, which avoids having to update the state of a thread upon preemption. Signed-off-by: Benoît Thébaudeau --- mt.c | 9 ++------- mt.h | 5 ++--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/mt.c b/mt.c index b59d9463d..d5bc10398 100644 --- a/mt.c +++ b/mt.c @@ -68,14 +68,13 @@ mt_start(struct mt_thread *thread, void (* function)(void *), void *data) stack with the correct parameters. */ mtarch_start(&thread->thread, function, data); - thread->state = MT_STATE_READY; + thread->state = MT_STATE_STARTED; } /*--------------------------------------------------------------------------*/ void mt_exec(struct mt_thread *thread) { - if(thread->state == MT_STATE_READY) { - thread->state = MT_STATE_RUNNING; + if(thread->state == MT_STATE_STARTED) { current = thread; /* Switch context to the thread. The function call will not return until the the thread has yielded, or is preempted. */ @@ -87,14 +86,11 @@ void mt_yield(void) { mtarch_pstop(); - current->state = MT_STATE_READY; - current = NULL; /* This function is called from the running thread, and we call the switch function in order to switch the thread to the main Contiki program instead. For us, the switch function will not return until the next time we are scheduled to run. */ mtarch_yield(); - } /*--------------------------------------------------------------------------*/ void @@ -102,7 +98,6 @@ mt_exit(void) { mtarch_pstop(); current->state = MT_STATE_EXITED; - current = NULL; mtarch_yield(); } /*--------------------------------------------------------------------------*/ diff --git a/mt.h b/mt.h index 6db215084..b472b3197 100644 --- a/mt.h +++ b/mt.h @@ -84,9 +84,8 @@ #include "contiki.h" -#define MT_STATE_READY 1 -#define MT_STATE_RUNNING 2 -#define MT_STATE_EXITED 5 +#define MT_STATE_STARTED 1 +#define MT_STATE_EXITED 2 /** * An opaque structure that is used for holding the state of a thread.