Sistemas Embebidos para tiempo real

Documentos relacionados
Fondo y pantalla inactiva. Guía del administrador

Pantalla principal NOTA

VCC-HD2300/HD2300P VCC-HD2100/HD2100P

- 1 - Servicios de otros fabricantes

Personalización de pantalla

HDD TWAIN driver Manual del Operador

El scheduler O(1) de Linux

MagicInfo Express Creador de contenido

Adobe Illustrator Client Manual del Usuario

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata

TWAIN driver Manual del Operador

- Quiénes NUNCA han Utilizado Software Libre? - Cuál es la diff entre software gratis y libre?

TÉRMINOS Y CONDICIONES DE USO DE LA APLICACIÓN WEB GEOXARC

1 Salud y seguridad. Introducción. 2 Acerca del juego. 3 Cómo jugar. 4 Antes de jugar. 5 Inicio. 6 Guardar la partida.

Contadores y timers. Contadores y timers. Contadores y timers

Cap.2. Kernel Sistemas Operativos - Viña del Mar.

Informe técnico FINAL

Universidad Nacional de Rosario Facultad de Ciencias Exactas, Ingeniería y Agrimensura Escuela de Ingeniería Electrónica INFORMÁTICA ELECTRÓNICA

Laboratorio 6 Capa de Aplicación

GUÍA DE USUARIO (No oficial) OpenBSD 5.1

SISTEMAS OPERATIVOS Arquitectura de computadores

Arquitectura de computadoras

Microchip Tips & Tricks...

Figura 1. Diagrama de bloques del Timer_A

Universidad de la República Facultad de Ingeniería Instituto de Ingeniería Eléctrica Sistemas Embebidos para Tiempo Real Curso Informe Final-

Interniche TCP-IP - V3.1 copyright (c) rsa data security, inc

Cátedra de Sistemas Distribuidos Escuela de Ingeniería Electrónica Departamento de Sistemas e Informática

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata

CASIO ClassPad App. (para Android, para ios) Guía del usuario. Para la serie ClassPad II.

Redes de sensores inalámbricos (RSI)

Estructura de los sistemas de cómputo

Ejemplo de la configuración HSRP del IPv6

XV ENCUENTRO INGENIERO&JOVEN 2017 Salidas profesionales en Auge Movilidad: Sostenibilidad e Innovación

Temporización mediante el temporizador del sistema SysTick en microcontroladores ARM Cortex-M

Estructura de Microprocesadores. Profesor Ing. Johan Carvajal Godínez

Registros SFR vistos hasta ahora: Microcontroladores PIC

Plataformas de Tiempo Real

Serie CM: Módulo de escaneo 2D

Studio Essentials Guía del Usuario

Youjie YJ HF600. Guía de inicio rápido. Lector de Area Imagen. YJ-HF600-ESES-QS Rev A 5/16

Youjie YJ HF600. Guía de inicio rápido. Escáner generador de imagen por área. YJ-HF600-ESLA-QS Rev A 5/16

INTERRUPCIONES Y ENTRADA/SALIDA DE PULSOS EN EL CPM2A/CPM2C

Funciones en C++: Nota: Este material es de estudio personal, en clases sólo revisaremos las láminas con. Usted revise todo.

VASO DE ALUMINIO 400cc PISTOLA DE GRAVEDAD CON SP352 SP352. GRAVITY SPRAY GUN WITH ALUMINIUM SWIVEL CUP 400cc

Light Account Siguientes pasos FAQ

SAP SuccessFactors: Extensiones HCP Learning Service Report: FUNDAE (Fundación Tripartita)

Implementación de un reloj de tiempo real en el MSP430F149

Laboratorio 2: Mediciones Digitales

Guia para examen de Sistemas Embebidos I Para primer parcial Febrero 2013 Revisión 2 Ing. Julio Cesar Gonzalez Cervantes

Organización de la Computadora

Segundo Parcial de Programación 2 7 de junio de 2017

HDD TWAIN driver Manual del Operador

Microcontroladores. Sistemas embebidos para tiempo real

INSTITUTO TECNOLÓGICO METROPOLITANO ITM GUÍA DE LABORATORIO INSTRUMENTACIÓN ELECTRÓNICA INTERFAZ ARDUINO - LABVIEW

Arquitectura de Computadores II

Laboratorio 2: Mediciones Digitales

Prácticas de Sistemas operativos

Escritorio Movistar Latam para Mac OS X

Vuquest 3310g. Guía de inicio rápido. Escáner lector ES-QS Rev C 1/13

Part No: KTI (Page 1-13) (Pagina 14-26) K-Tool International Wixom, MI 48393

CAPITULO 3 MANEJO DE LOS TEMPORIZADORES Y CONTADORES

Esko Data Exchange for Adobe Illustrator Guía del Usuario

Granit 1980i. Guía de inicio rápido. Lector industrial de imagen de largo alcance. GRNT1980-ES-QS Rev A 1/15

Microcontrolador PIC16F84: Arquitectura

Guía para Sincronización Ver. 2.2, Marzo 2016

Sophos Endpoint Security and Control Guía de inicio de usuario independiente

INGENIERÍA DE COMPUTADORES 3. Solución al Trabajo Práctico - Junio de 2016

CONALEP TEHUACÁN 150. INSTALACIÓN DE SISTEMAS MICROPROCESADOS. GRUPO 309 SOMA UNIDAD 2. INTRODUCCIÓN A LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR

GUIA DE PROGRAMACIÓN DE CONTROLADORES SOLARES EPSOLAR SERIES LANDSTAR Y VIEWSTAR

Xenon Guía de inicio rápido. Escáner lector. NG2D-ES-QS Rev B 5/11

Rational Developer for System z Unit Test. Sergio González Consultor Calidad Ingeniería del Software

FAQ's sobre Sincronización Ver. 2.2 Marzo 2016

Terminal Portátil Dolphin TM Guía de inicio rápido

Modelo de Arquitectura para Aplicaciones con HMI para CompactRIO

MANUAL DE ADMINISTRACIÓN BÁSICA v. 1.0

1. Para qué sirve un Descriptor de Dispositivo? Qué funciones del sistema operativo acceden a ellos y para qué?

Tabla de contenidos. 1 de 26. TANGO CENTRO DE CLIENTES Cerrito CP C1010AAZ Buenos Aires Argentina +54 (011) (011)

Granit 1280i. Guía de inicio rápido. Lector Láser Industrial de Amplio Rango LS-QS Rev A 1/14

Microcontroladores. Sistemas embebidos para tiempo real

Introducción Ejercicios PIC: Intel 8259 Más ejercicios Preguntas. Entrada/Salida. Polling e Interrupciones. Francisco García Eijó

Esquema de partida. Maximum Operating Supply Voltage 5.5V USB 1 USART 1

Laboratorio 2: Mediciones Digitales

GSM/GPRS/GPS Tracker GV300

UNIVERSIDAD NACIONAL DE COLOMBIA SEDE BOGOTÁ FACULTAD DE INGENIERÍA INGENIERÍA MECATRÓNICA

Arquitectura de Sistemas

CÓMO FUNCIONA UN PLC Control Combinacional Programación del PLC

Terminal portátil Dolphin TM Guía de inicio rápido

Periféricos: Timer. Cesáreo Fernández Martínez Álvaro Sánchez Miralles

Contenidos Configuración Uso Resolución de problemas LED de estado Apéndice WIRELESS SUBWOOFER. Manual del usuario. HEOS Subwoofer

Procesamiento de nóminas en ADP Time & Attendance

Guía rápida para gestionar el puerto paralelo del PC

====================================================================== Archivo "LÉAME" (Readme) del Programa ScanSnap Organizer V5.

Datos compartidos: alternativas a deshabilitar interrupciones. Sistemas embebidos para tiempo real

Entrada / Salida. Relojes y terminales. Dr. Alonso Ramírez Manzanares 4-Nov-2010

LABORATORIO DE ELECTRÓNICA DE POTENCIA PRÁCTICA N 3

Introducción a las Computadoras. Capítulo 3 Buses del Sistema

Las Interrupciones en el S7-200

Solaris 7980g. Guía de inicio rápido. Escáner de presentación por imagen ESES-QS Rev A 11/15

Transcripción:

MEMORIA DEL PROYECTO DE FIN DE CURSO Sistemas Embebidos para tiempo real Integrantes: PABLO BALLIVA COSTA GUSTAVO BROWN RODRÍGUEZ CARLOS FERNÁNDEZ PALERMO Tutores: LEONARDO STEINFELD JAVIER SCHANDY IIE FIng UdelaR 1. er semestre 2014

Resumen Los RTOS Real Time Operating Systems ( sistemas operativos de tiempo real ) utilizan timers provistos por el hardware para realizar diversas acciones como ser: medir tiempo, planificar tareas o agendar eventos tanto del sistema como del usuario. La implementación actual de Contiki OS utiliza timers con período fijo para realizar estas tareas. Esto conduce a que el procesador se mantenga en un estado de alto consumo por un tiempo mayor al necesario, puesto que una gran proporción de las interrupciones del temporizador son solamente para actualizar el estado del timer. En este proyecto se modificaron algunas de las bibliotecas de timer de Contiki, incluyendo el módulo reloj específico de la plataforma Sky, de manera de que hardware solo interrumpa cuando haya sido agendado. La implementación es completamente transparente para las aplicaciones existentes y funcionó correctamente en varios casos de prueba. En algunas aplicaciones podría obtenerse una baja en el consumo considerable. Todo tipo de aplicaciones de bajo consumo podrían verse beneficiadas por la extensión de esta estrategia a otras plataformas. Palabras clave. RTOS, Contiki, timer, tick. Índice 1 Introducción...................................... 1 1.1 Descripción del problema........................... 1 1.2 Antecedentes................................... 1 2 Objetivos........................................ 1 3 Alcance......................................... 2 4 Diseño......................................... 2 4.1 Estructura de timers del RTOS Contiki.................... 2 4.1.1 Módulo Clock.............................. 2 4.1.2 Módulo Etimer.............................. 3 4.1.3 Módulos Ctimer y Rtimer........................ 3 4.2 Diseño de timers sin tick: SinTicki....................... 4 5 Implementación.................................... 4 5.1 Activación de timer sin tick.......................... 4 5.2 Módulo Clock.................................. 4 5.3 Módulo Etimer.................................. 8 5.4 Módulos Timer, Ctimer y Rtimer........................ 8 5.5 Módulo UART.................................. 9 5.6 Implementación de timer sin tick en otras plataformas........... 9 6 Pruebas......................................... 9 6.1 Simulaciones................................... 9 6.2 Pruebas en mote real.............................. 11 I

6.2.1 Consumo................................. 12 6.2.2 Resultados................................ 13 6.3 Cálculos..................................... 16 6.3.1 Consumo base declarado por el fabricante.............. 16 6.3.2 Consumo base medido......................... 18 6.3.3 Curvas paramétricas.......................... 18 7 Conclusiones..................................... 18 7.1 Futuros desarrollos............................... 20 8 Anexo.......................................... 21 8.1 Fuentes SinTicki................................. 21 8.2 Fuentes pruebas................................. 41 II

1. Introducción 1.1. Descripción del problema Los RTOS utilizan timers provistos por el hardware para realizar varias acciones como ser medir tiempo, planificar tareas o agendar eventos tanto del sistema como del usuario. Contiki 1 es un RTOS desarrollado principalmente por Adam Dunkels, de código abierto y licenciado bajo BSD, con un énfasis en redes de sensores inalámbricos y sistemas de bajo consumo con restricciones de memoria. La implementación actual de Contiki utiliza timers con período fijo para realizar estas tareas, en un esquema en el cual en cada interrupción del mismo se actualiza el estado del sistema en lo referente al manejo del tiempo y se disparan los eventos agendados que correspondan. Esto conduce a que el procesador se mantenga en un estado de alto consumo por un tiempo mayor al necesario, puesto que una gran proporción de las interrupciones del temporizador son solamente para actualizar el estado del timer. El procesador debe en cada tick pasar a estado activo (si estuviese en algún modo de bajo consumo) para actualizar el contador de ticks, verificar si algún evento debe ocurrir en ese instante y, en caso contrario, volver al estado anterior. Por otra parte, si el procesador estuviese ocupado ejecutando una tarea de usuario (o código del propio sistema operativo), la interrupción tiene como penalización el retardo de conmutar el contexto, ser procesada y conmutar el contexto nuevamente para que prosiga la ejecución anterior. El uso de un timer sin tick consiste en la programación del temporizador dinámicamente, para que interrumpa solo cuando sea momento de disparar un evento. 1.2. Antecedentes En el año 2013, un proyecto del curso trabajó sobre el problema de la utilización de timers sin tick para minimizar el ciclo de trabajo correspondiente al disparo de eventos asociados al tiempo 2. Si bien Contiki actualmente no implementa la funcionalidad de timer sin tick, otros sistemas operativos de tiempo real 3 sí lo hacen. En el proyecto de fin de carrera Plagavisión 4, que utilizó una plataforma TelosB corriendo Contiki, se midió un consumo base de 40 µa (radio apagada, flash apagada, MCU en modo LPM) que promediando los ticks periódicos ascendía a más del doble, 96 µa. Bajar este consumo podría ser de gran interés para las aplicaciones de bajo consumo en redes de sensores inalámbricos. 2. Objetivos El objetivo del proyecto es implementar la funcionalidad de timer sin tick para el RTOS Contiki, y tomar métricas de consumo de un sistema de prueba para ser compa- 1 A. Dunkels, et al., Contiki OS, http://www.contiki-os.org/ 2 M. Valdés, F. Vanzini, F. Viera, Timer sin tick, proyecto de fin de curso de Sistemas embebidos para tiempo real, https://eva.fing.edu.uy/pluginfile.php/66263/mod_page/content/4/informefinal.pdf 3 H. Cha, S. Choi, I. Jung, et al., RETOS: Resilient, Expandable, and Threaded Operating System for Wireless Sensor Networks. 4 N. Wainstein, J. Schandy, M. González, Plagavisión, proyecto de fin de Carrera IIE. 1

rado con la implementación actual del manejo de temporizadores de Contiki. 3. Alcance Los alcances se resumen en los siguientes puntos: 1. Se modificará el código fuente de Contiki de manera de que se cumpla con el objetivo. 2. Se verificará, sobre una plataforma de simulación, el correcto funcionamiento del manejo del agendado de tareas, con las modificaciones previstas en el proyecto y también del manejo de tiempo real. 3. Se utilizará una plataforma de desarrollo TelosB compatible (TMoteSky, CM3000, CM3300, CM5000, etc.), con un microcontrolador de la familia MSP430 para realizar las pruebas. 4. Se evaluará si la implementación consigue bajar el consumo en una aplicación típica de la plataforma. 5. Para este proyecto no se realizarán desarrollos de hardware. 4. Diseño 4.1. Estructura de timers del RTOS Contiki Se estudió la estructura interna de Contiki, en particular, la organización del conjunto de bibliotecas de timers que utilizan tanto el sistema como las aplicaciones que corren en él. Las bibliotecas contienen la funcionalidad necesaria para comprobar períodos de tiempo expirados y para alternar entre la ejecución de tareas y modos de bajo consumo, mientras se espera por el tiempo seteado para una tarea. El sistema utiliza uno de los timers del microcontrolador, en el caso particular de estudio es un MSP430F1611. El timer se setea en modo continuo y con comparación, o sea que el registro TAR de 16 bits se incrementa a la frecuencia de un oscilador auxiliar (32768 Hz en nuestro caso) y genera una interrupción cuando TAR es igual al valor seteado en el registro TACCR1. 4.1.1. Módulo Clock Este módulo de Contiki provee funcionalidades para manejar la hora del sistema y para bloquear la CPU por períodos cortos de tiempo. El módulo depende de la plataforma y se implementa en clock.c. Maneja el reloj del sistema y también las notificaciones de la biblioteca Etimer cuando hay que chequear si hay timers de eventos expirados. Las funciones que incluye el módulo Clock son: clock_time_t clock_time(): obtiene la hora del sistema en ticks; unsigned long clock_seconds(): obtiene la hora del sistema en segundos; 2

void clock_delay(unsigned int delay): retardo de la CPU; void clock_wait(int delay): retardo de la CPU por un número de ticks; void clock_init(void): inicializa el módulo; CLOCK_SECOND: número de ticks por segundo. En este módulo se encuentra la ISR del timera del MCU, en ella incrementa una variable estática llamada count del tipo clock_time_t que es un long sin signo. Esta variable almacena el número de ticks que ocurren desde que inicia el sistema. Además en la ISR setea al registro TACCR1 sumándole la constante INTERVAL para de esta forma obtener interrupciones periódicas que llamamos ticks. Si existen eventos pendientes de expirar los actualiza llamando a la función etimer_request_poll() que detallamos dentro de la biblioteca Etimer. 4.1.2. Módulo Etimer La biblioteca Etimer de Contiki provee un mecanismo de timer que genera eventos temporizados. Se utiliza al módulo Clock, en particular, la función clock_time(). Los etimers se declaran como estructuras y se acceden por punteros. Las funciones que incluye el módulo Etimer son: void etimer_set(struct etimer *t, clock_time_t interval): inicia el timer; void etimer_reset(struct etimer *t): reinicia el timer desde que expiró en previo; void etimer_restart(struct etimer *t): reinicia el timer desde la hora actual; void etimer_stop(struct etimer *t): detiene el timer; int etimer_expired(struct etimer *t): chequea si expiró un timer; int etimer_pending(): chequea si algún timer aún no expiró; clock_time_t etimer_next_expiration_time(): obtiene el próximo tiempo de expiración; void etimer_request_poll(): informa a la biblioteca Etimer que el reloj del sistema ha cambiado. Además de estas funciones la biblioteca Etimer tiene la función estática static void update_time(void) que es utilizada por varias de las funciones públicas. En esta función mantiene una lista de todos los eventos pendientes y calcula cuál es el próximo evento a dispararse. 4.1.3. Módulos Ctimer y Rtimer Los timers del tipo ctimer proveen un mecanismo que llama a una función específica al expirar. Un ctimer es declarado como una estructura y es accedido mediante punteros al timer de callback declarado. La biblioteca Rtimer corresponde a timers de tiempo real y es utilizada cuando se requiere cierta precisión en la ejecución de una tarea. Al igual que Etimer, utiliza el registro TAR en comparación, pero con otro registro CCR. Estos timers tienen su propio módulo Clock donde se encuentra la ISR específica. 3

4.2. Diseño de timers sin tick: SinTicki Basados en el estudio de la estructura de timers de Contiki en lo que sigue presentamos el diseño de la solución para implementar timers sin ticks. En la sección anterior se presentó el módulo Clock que depende de la plataforma y se encuentra la ISR del timera del microcontrolador. En este módulo se encuentra la variable count que lleva la cuenta de los ticks. Esta variable se actualiza hoy con un timer con tick. La función clock_time() retorna dicho valor y los distintos módulos que interactúan con eventos utilizan directa o indirectamente dicho valor. Nuestra propuesta es realizar una «simulación de ticks» manteniendo esa variable y modificándola de acuerdo al timer sin tick (programado para dispararse cuando toque ejecutar el siguiente evento agendado). Es decir, que cuando se dispara la ISR del temporizador se actualiza la variable count con el nuevo valor, como si se hubiesen disparado los ticks que correspondan. La función clock_time() no solamente se dispara cuando expira un timer: la misma puede ser llamada asincrónicamente y por lo tanto debe ser modificada para que tenga en cuenta el valor del registro TAR actual y mantener el valor del mismo registro cuando se produjo la última interrupción del temporizador. De esa forma conociendo la cantidad de incrementos del registro TAR entre dos interrupciones se puede determinar a cuantos ticks corresponde. En la siguiente sección se desarrolla el detalle de la implementación de esta solución. 5. Implementación Luego de analizar los módulos de Contiki relativos al manejo de tiempo se procedió a realizar las modificaciones al mismo para la arquitectura MSP430, específicamente, para el microcontrolador de la familia MSP40F1xxx. Las modificaciones fueron realizadas sobre la versión 2.7 de Contiki. A continuación se describen los cambios realizados a cada módulo 5.1. Activación de timer sin tick En el archivo de cabecera clock.h se definió la constante del preprocesador _TST. Esta constante determina si al compilar un proyecto con Contiki se utilizará timer sin tick (cuando la constante está definida) o si Contiki se mantendrá sin modificaciones. Esto facilita las pruebas funcionales de las modificaciones al sistema operativo ya que es posible comparar el comportamiento de un programa utilizando timer sin tick y el sistema operativo sin modificaciones simplemente modificando la existencia de dicha constante. 5.2. Módulo Clock Este módulo comprende el archivo de código clock.c y su correspondiente archivo de cabecera clock.h. En el archivo de cabecera además de la constante _TST se agregó el prototipo de una nueva función void clock_setup(clock_time_t next_t) que es la encargada de reprogramar los registros del temporizador interno del microcontrolador para que interrumpa cuando sea requerida una acción. 4

El archivo clock.c contiene entre otras funciones la implementación de la rutina de atención a la interrupción del temporizador que fue modificada para soportar timer sin tick. A continuación se presenta el código de dicha función simplificado (considerando que está definida la constante _TST): TimerISR 1 ISR ( TIMERA1, timera1 ) 2 { 3 uint16_ t diff_ tar = 0; 4 clock_ time_ t temp_ count ; 5 ENERGEST_ON ( ENERGEST_TYPE_IRQ ); 6 watchdog_ start () ; 7 if ( TAIV == 2) { 8 timer_ triggered = TRUE ; 9 diff_ tar = TAR - last_ tar ; 10 /* Arregla caso en que TAR se ' pasa ' algun tick causa diff_ tar chico */ 11 if ( diff_tar < min_dif_for_next_t ) diff_tar = min_dif_for_next_t ; 12 temp_ count = count ; 13 /* Actualiza variables ' count ' y ' seconds ' */ 14 count += ( diff_tar / INTERVAL ); 15 if ( diff_ tar & HALF_ INTERVAL_ MASK ) 16 count ++; /* Aplica redondeo en INTERVAL */ 17 temp_ count = count + r emainder_ for_ second - temp_ count ; 18 seconds += temp_ count / CLOCK_ CONF_ SECOND ; 19 remainder_ for_ se cond = temp_ count % CLOCK_ CONF_ SECOND ; 20 last_ tar = TAR ; 21 TACCR1 = last_ tar - 1; 22 min_ dif_ for_ next_ t = ~0; 23 if ( etimer_pending () ){ 24 etimer_ request_ poll () ; 25 LPM4_ EXIT ; 26 } 27 } 28 watchdog_ stop () ; 29 ENERGEST_OFF ( ENERGEST_TYPE_IRQ ) ; 30 } Las líneas 1 a 6 contienen el prólogo de la rutina de atención a la interrupción, habilitan ENERGEST de tipo IRQ, activan el watchdog y determinan si la interrupción fue generada por el temporizador. La línea 8 contiene una variable booleana del módulo que indica lleva cuenta si el temporizador se ha disparado desde la última vez que fue configurado por la rutina clock_setup. Las líneas 9 a 11 computan la cantidad de ticks del TAR que han ocurrido desde la última vez que se generó una interrupción del temporizador y le aplica un ajuste a dicho valor cuando esta diferencia es más chica que el tiempo estimado. Esto puede ocurrir dado que la variable que lleva cuenta de la diferencia de ticks es de 16 bits al igual que el propio TAR, por lo tanto cuando se agenda que la próxima interrupción se produzca en el intervalo máximo puede ocurrir que la rutina efectivamente se dispare algunos ticks después. En ese caso la resta puede desbordar y quedar con un valor cercano a 0. Para solventar este problema, una variable del módulo llamada 5

min_dif_for_next_t mantiene la diferencia mínima que debe contabilizarse cuando se produzca la interrupción del temporizador. Esta variable se actualiza en esta misma rutina y en la rutina que reprograma el temporizador. Las líneas 12 a 16 actualizan la variable del módulo count que lleva cuenta de los ticks vistos por Contiki. Con el sistema sin modificar, estos ticks se actualizan a razón de un tick cada INTERVAL ticks del temporizador de hardware. Teniendo la diferencia de ticks entre interrupciones y dividiendo este valor por IN- TERVAL se obtiene la cantidad de ticks de Contiki que deben ser contabilizados. Nuevamente, en este caso se aplica una corrección a dicho valor para tener en cuenta semi intervalos de un tick. En este caso se toma como aproximación el semi período de un tick aplicando redondeo sobre el intervalo. Las líneas 17 a 19 actualizan la variable del módulo seconds que mantiene la cantidad de segundos que el sistema está en funcionamiento desde que fue reseteado. En este caso además de actualizar los dicha variable se mantiene una variable auxiliar remainder_for_second que contiene la cantidad de ticks en exceso del último segundo contabilizado. Esta variable debe tenerse en cuenta para mantener correctamente la variable asociada a los segundos del sistema. Las líneas 20 a 25 se encargan de reagendar el temporizador al período máximo, actualizar la variable que mantiene una copia del valor actual del TAR y requerir la atención del despachador de eventos del módulo Etimer. La rutina finaliza desactivando el watchdog y apagando ENERGEST. La rutina que reprograma el registro trigger del temporizador también se encuentra en este módulo: clock_setup 1 void clock_setup ( clock_time_t ticks_for_next_t ){ 2 clock_ time_ t temp = ticks_ for_ next_ t ; 3 uint16_ t next_ ccr ; 4 dint () ; 5 /* Agenda proximo disparo del temporizador */ 6 if ( ticks_ for_ next_ t == DUMMY_ TIMER_ TRIGGER 7 ticks_ for_ next_ t >= DUMMY_ TIMER_ TICKS ) 8 { 9 if (! timer_ triggered ) 10 { 11 eint () ; 12 return ; 13 } 14 next_ ccr = TAR-1; /* Agenda 2 segundos */ 15 } else 16 { /* Agenda para disparar temporizador asociado a proximo evento */ 17 next_ ccr = TAR + ticks_ for_ next_ t * INTERVAL ; 18 } 19 timer_ triggered = FALSE ; 20 21 TACCR1 = next_ ccr ; 22 23 eint () ; 24 } Esta recibe como parámetro la cantidad de ticks del evento a ser disparado más 6

cercano en el tiempo, o una constante predefinida DUMMY_TIMER_TRIGGER cuando no hay eventos a disparar. Para reprogramar el temporizador basta con modificar el registro TACCR con un valor adecuado, teniendo en cuenta el valor actual del TAR. Las líneas 5 a 15 se encargan de agendar el temporizador para que interrumpa en el período más largo (para la arquitectura MSP es de 2 segundos). Esto debe realizarse en dos casos: cuando no hay ningún evento a disparar y cuando el próximo evento esta fuera de la ventana de tiempo agendable). La rutina tiene en cuenta el caso en que ya se ha reprogramado el temporizador para el período máximo y se intenta volver a reprogramar el temporizador sin que se haya disparado la ISR. En este escenario igualmente se quiere que el temporizador se dispare cada 2 segundos dado que ello desencadena la actualización de las variables asociadas a los ticks y a los segundos de Contiki. La línea 17 calcula el valor adecuado para el TACCR1 para el caso en que el próximo evento entre dentro de la ventana actual del temporizador. La rutina finaliza actualizando la variable timer_triggered indicando que se ha programado el temporizador pero aún no se ha disparado el evento asociado. Dado que Contiki provee funciones para saber cuántos ticks/segundos han pasado desde que se reinició el sistema, y que estas funciones dependen del contador de ticks general, se deben aplicar modificaciones a dichas funciones para que tengan en cuenta los ticks que hubiesen pasado si el temporizador hubiese interrumpido en cada tick. clock_time 1 clock_time_t clock_time ( void ){ 2 clock_time_t t1, t2 ; 3 uint16_ t current_ tar = 0; 4 do { 5 t1 = count ; 6 current_ tar = last_ tar ; 7 t2 = count ; 8 } while ( t1!= t2 ); 9 10 /* clock_ time es el valor actual de ' count ' sumado a la cantidad de ticks 11 * desde la ultima interrupcion del temporizador */ 12 return t1 + ( TAR- current_ tar )/ INTERVAL ; 13 } A esta rutina se le realizaron cambios mínimos para contabilizar la cantidad de ticks Contiki desde la última vez que se disparó el temporizador. Para ello en la línea 6 (parte del bucle que determina la cantidad actual de ticks) se copia el valor del TAR cuando se ejecutó la ultima rutina de atención a la interrupción del temporizador. Se utiliza un bucle allí para resolver el problema de las variables globales (tanto count como last_tar con variables globales que se actualizan en la rutina de atención a la interrupción del temporizador). Una vez que se tienen estos datos, se puede calcular el valor de ticks Contiki como la suma de los ticks contabilizados hasta este momento más la cantidad de ticks determinados a partir de la diferencia del TAR con el último TAR contabilizado y el ratio entre ticks de la arquitectura y los ticks Contiki (INTERVAL). 7

clock_seconds 1 unsigned long clock_ seconds ( void ){ 2 unsigned long t1, t2 ; 3 uint16_ t current_ tar = 0; 4 do { 5 t1 = seconds ; 6 current_ tar = last_ tar ; 7 t2 = seconds ; 8 } while ( t1!= t2 ); 9 return t1 + ( remainder_ for_ second + ( TAR- current_ tar )/ INTERVAL ) / CLOCK_ CONF_ SECOND ; 10 } Al igual con la rutina que retorna la cantidad de ticks Contiki, a la rutina clock_seconds se le deben realizar pequeños ajustes. Nuevamente en la línea 6 se obtiene el valor del TAR de cuando se ejecutó la ISR. Ahora, para calcular la cantidad de segundos a retornar se debe contabilizar el valor de la variable seconds más la cantidad de segundos, teniendo en cuenta las variables remainder_for_second y el tiempo transcurrido desde la última atención a la interrupción del temporizador. 5.3. Módulo Etimer Este módulo es el encargado de administrar y despachar los eventos registrados por los protothreads de Contiki y su funcionamiento depende del módulo de Clock ya comentado. Cada vez que se agenda un evento se llama a la función update_time de este módulo, que mantiene una lista de todos los eventos pendientes y calcula cuál es el próximo evento a dispararse. Para funcionar con timer sin tick fue necesario realizar pequeñas modificaciones a dicha función para que llame a la función clock_setup del módulo Clock, pasándole como argumento la cantidad de ticks del próximo evento agendado (o un valor dummy indicando que no hay eventos pendientes). Asimismo, fue necesario realizar modificaciones al protothread etimer_process asociado a este módulo. Este protothread se encarga de verificar si hay algun evento que deba ser disparado, actuando en consecuencia. Cada vez que dispara un evento vuelve a llamar a la función update_time para recalcular el próximo evento agendado. El cambio consiste en llamar a la función update_time antes que el protothread se vuelve a bloquear, si no se ejecutó ningún evento agendado. 5.4. Módulos Timer, Ctimer y Rtimer Luego del análisis de estos módulos se concluyó que no era necesario realizar modificaciones sobre los mismos para que el funcionamiento fuese correcto utilizando timer sin tick. La razón es que estos módulos utilizan directamente la API expuesta en el módulo de reloj o utilizan timers internos para su implementación. La implementación de los rtimers utiliza internamente el mismo temporizador que el utilizado para llevar el timer sin tick pero con otro registro de comparación 8

(TACCR0). Es por ello que en la implementación del timer sin tick se tuvo cuidado de no modificar el registro TAR ni los prescalers compartidos con los rtimers. 5.5. Módulo UART La implementación para la familia MSP de la UART en Contiki permite que la recepción de datos sea realizada a través de DMA o por interrupciones. En el caso en que la misma sea realizada por DMA se mantiene un pequeño buffer donde se van recibiendo los datos y cada cierto tiempo se llama al handler que procesa los mismos (a través de un ctimer). Para la realización de este proyecto el manejo de recepción de datos de la UART debe hacerse por interrupciones en vez de utilizando DMA, porque en este último caso Contiki utiliza un temporizador cada dos ticks para procesar los datos recibidos por DMA, lo cual no permite aprovechar el esquema de timer sin tick. Por esta razón, si se está utilizando timer sin tick, por defecto se utilizará la UART de recepción vía interrupciones, en vez de DMA. La configuración de la UART toma su valor por defecto de acuerdo a la constante del preprocesador UART1_CONF_RX_WITH_DMA, por lo que cuando está definido timer sin tick en el módulo uart1.c por defecto se indica que se realice a través de interrupciones. 5.6. Implementación de timer sin tick en otras plataformas Para implementar timer sin tick en otras plataformas se deben realizar cambios análogos a los realizados para MSP430 en lo que respecta al manejo del módulo de reloj (módulo clock.c) y eventualmente aplicar las modificaciones al módulo de la UART para que la recepción se realice a través de interrupciones sin el uso de DMA. No es necesario modificar los fuentes etimer.c ni clock.h. Las modificaciones sobre clock.c implican el cambio de la rutina de atención a la interrupción del temporizador para realizar los cambios descriptos en la sección 5.2, y la implementación de la función clock_setup. Las rutinas clock_time y clock_seconds deben modificarse tal como se ha explicado en el documento, para tener en cuenta el tiempo transcurrido desde la última interrupción del temporizador. 6. Pruebas Las pruebas del nuevo sistema implementado se sucedieron en dos etapas: primero se realizaron simulaciones verificando el funcionamiento esperado y luego se ejecutaron aplicaciones en un nodo de red de sensores inalámbricos. 6.1. Simulaciones Las primeras pruebas de la implementación de SinTicki se realizaron corriendo aplicaciones en un simulador. Se utilizó Cooja, que es un simulador de redes de sensores que ejecuta el RTOS Contiki y viene incluido en la máquina virtual Instant Contiki. 5 Cooja permite simulaciones simultáneas a nivel de red (o aplicación), a nivel de sistema operativo y a nivel de instrucción de código de máquina. En este caso, era 5 http://www.contiki-os.org/start.html 9

de interés el nivel de sistema operativo y, como se ejecuta todo Contiki, incluidos los procesos de usuario, es posible simular las modificaciones de la funcionalidad del núcleo del SO. Esto permitió evaluar los cambios en módulos y bibliotecas incluidas en Contiki. Para estas simulaciones se desarrolló una aplicación que agenda tres eventos periódicos con diferentes períodos cada uno, y en la ejecución imprime en consola un mensaje indicando de que evento se trata y la hora del sistema en segundos. Los eventos se agendan utilizando las distintas bibliotecas de timers: Etimer, Ctimer y Rtimer. A continuación se muestran los procesos de la aplicación de prueba. En primer lugar se encuentran las definiciones con los tiempos a setear para los diferentes timers. definiciones 1 # define PROCESS1_ TIME (5 * CLOCK_ SECOND ) 2 # define PROCESS2_ TIME (7 * CLOCK_ SECOND ) 3 # define CTIMER1_ TIME (25 * CLOCK_ SECOND ) 4 # define TIMER_ TIME ( CLOCK_ SECOND + ( CLOCK_ SECOND > >1) ) 5 # define RTIMER1_ TIME ( RTIMER_ SECOND ) 6 7 # include < stdio.h > /* For printf () */ 8 /*----------------------------------------------------------------------*/ 9 PROCESS ( etimer1_process, " ETimer test 1"); 10 PROCESS ( etimer2_ process, " ETimer test 2"); 11 PROCESS ( init_process, " Init Process "); 12 AUTOSTART_ PROCESSES (& etimer1_ process, & etimer2_ process, & init_ process ); Luego se presenta un proceso que setea y espera la ocurrencia de un evento del timer que, cuando ocurre, imprime la cantidad de ocurrencias acumuladas, la hora del sistema en segundos y la hora del sistema en ticks. Process etimer1 1 PROCESS_ THREAD ( etimer1_ process, ev, data ) 2 { 3 static struct etimer periodic_ timer ; 4 static int c = 1; 5 PROCESS_ BEGIN () ; 6 7 etimer_ set (& periodic_ timer, PROCESS1_ TIME ); 8 while (1) { 9 PROCESS_WAIT_EVENT_UNTIL ( etimer_expired (& periodic_timer )); 10 etimer_ reset (& periodic_ timer ); 11 printf (" ETimer 1 timed out %d: %lu - ticks : %lu \n", c ++, clock_seconds (), clock_time () ); 12 etimer_ set (& periodic_ timer, PROCESS1_ TIME ); 13 } 14 15 PROCESS_ END () ; Cuando ocurren los eventos de Ctimer y Rtimer estos imprimen la hora en segundos además de la identificación de quien generó el evento. 10

ctimer 1 static struct ctimer ctimer1 ; 2 static void ctimer1_ callback ( void * ptr ) 3 { 4 static struct timer timer ; 5 clock_ time_ t interval = TIMER_ TIME ; 6 ctimer_ set (& ctimer1, CTIMER1_ TIME, ctimer1_ callback, NULL ); 7 printf (" CTimer 1 timed out : %lu \n", clock_seconds () ); 8 timer_ set (& timer, interval ); 9 // Apago watchdog para que no se resetee en el loop de ahi abajo 10 watchdog_ stop () ; 11 while (! timer_expired (& timer )); 12 watchdog_ start () ; 13 printf (" Timer timed out : %lu \n", clock_seconds () ); 14 } rtimer 1 static struct rtimer rtimer1 ; 2 void rtimer1_ callback ( struct rtimer * t, void * ptr ) 3 { 4 rtimer_ clock_ t rt_ trigger = RTIMER1_ TIME ; 5 rt_ trigger << 6; 6 rt_ trigger += RTIMER_ NOW () ; 7 rtimer_ set (& rtimer1, rt_ trigger, 1, rtimer1_ callback, NULL ); 8 printf (" RTimer 1 timed out : %lu \n", clock_seconds () ); 9 } La figura 1 es una captura de pantalla de la simulación realizada. Se simuló un nodo de red con la aplicación de prueba cargada. En la tabla «Log Listener» de la simulación se corroboran las impresiones que envía el nodo con los tiempos indicados. La ocurrencia de los eventos es acorde a lo esperado. 6.2. Pruebas en mote real Se grabaron nodos de redes de sensores con diferentes aplicaciones para poder cumplir con dos objetivos: corroborar los resultados obtenidos en la simulación del funcionamiento correcto y transparente de SinTicki; realizar comparaciones analizando las ventajas respecto al ahorro de energía que SinTicki pueda ofrecer. La misma aplicación que setea varios timers, presentada anteriormente, fue compilada e instalada en un nodo de la familia TelosB: el CM5000. Se puso a correr la aplicación con el nodo conectado a través del puerto USB del PC, que le brinda alimentación y da una conexión serie para que los printf() ejecutados al dispararse cada evento sean impresos en una consola. Instant Contiki ofrece esa herramienta con la ejecución del comando make login. Se verificó de la lectura en consola y se cronometraron las impresiones en pantalla corroborando que los tiempos eran los previstos según la aplicación. 11

FIGURA 1: Captura de pantalla de simulación de aplicación de eventos temporizados realizada con Cooja. 6.2.1. Consumo Para medir el consumo pudiendo apreciar las variaciones en todo el rango dinámico el setup de prueba constó de una fuente de alimenación, una resistencia en serie con el mote y un osciloscopio digital. Midiendo entonces con el osciloscopio el voltaje en la resistencia obtenemos una señal en pantalla proporcional a la corriente que el mote consume. Los elementos utilizados fueron los siguientes: fuente de alimentación regulada Tektronix PS280; resistencias shunt de 10 Ω y 100 Ω al 5 %, utilizadas según la necesidad de medir altos o bajos consumos, respectivamente; osciloscopio Tektronix TDS220. El osciloscopio utilizado permite capturar la pantalla y almacenar todos los datos que forman la señal. Luego de recolectados, estos se procesaron con Matlab. Se utilizaron tres aplicaciones que permitieron evaluar de diferentes maneras el consumo del nodo, corriendo primero sobre el Contiki original y luego sobre SinTicki. 12

1. Aplicación proporcionada por los docentes del curso. Esta aplicación lo que hace es llevar el mote al modo de más bajo consumo asegurando de apagar la mayoría de elementos que lo integran. La utilidad de esta aplicación es comparar las dos versiones del planificador de Contiki en modo LPM así de esta forma se evalúa el ahorro de energía si la CPU del mote no está obligada a salir de LPM solamente para actualizar los timers. 2. Aplicación simple desarrollada en el contexto del proyecto que enciende la CPU cada 25 s y la mantiene por 62 ms. Esto permite evaluar cuando existe un ciclo de trabajo con un consumo solamente de CPU en estado activo. 3. La última es una aplicación típica que viene con Instant Contiki, llamada sky-collect. Esta aplicación enciende sensores, toma medidas y envía los datos por la red que integra el nodo. También permite evaluar el impacto de utilizar SinTicki en una aplicación con ciclo de trabajo mixto, que realiza diferentes actividades. Los códigos fuente de las aplicaciones 1 y 2 se incluyen en la sección 8 y el código de la aplicación 3 se puede obtener de la documentación de Contiki. 6.2.2. Resultados La figura 2 muestra el perfil de consumo del nodo cuando corre la aplicación 1 en Contiki original. Se aprecia en la imagen que tiene un consumo base en LPM, con despertadas periódicas reflejadas en los picos de la señal. Hay dos picos distintos: el de menos altura corresponde a los ticks que actualizan la agenda de eventos; los picos más altos, que ocurren cada dos ticks, (fig. 5) se deben a que además del agendado se chequea si hay datos en memoria que llegaron por la UART y se escribieron por DMA. Para el análisis comparativo no se ha tomado en cuenta el consumo de estos últimos, ya que el usuario puede configurar la UART para que utilice interrupciones y no DMA. En el caso de la aplicación 1 corriendo en SinTicki solamente el timer interrumpe cuando desborda cada dos segundos. Los dos picos que se ven en la figura 3 son esas interrupciones. Se debe tener en cuenta que la relación en la escala de tiempos entre las figuras 2 y 3 es de 1 a 100, por lo que en esta última no se logra apreciar la forma de onda de los pulsos de CPU activa. A partir de los datos obtenidos de las mismas capturas de pantalla se estableció la carga del pulso correspondiente a un tick, calculando el área bajo la curva corriente en función del tiempo: el resultado para la carga de un tick es de 0, 2 µc. La corriente promedio medida cuando el mote está en LPM es de 80 µa. Con estos datos se puede determinar la carga consumida por los dos sistemas en un período determinado. En este caso se fijó en 2 segundos, que es cuando SinTicki tiene 1 tick y Contiki 256. Entonces: carga consumida Contiki: 174 µc; carga consumida SinTicki: 147 µc. Lo que da una diferencia del 16 % aproximadamente, o sea que, para un mote que solo duerme, la batería duraría un 16 % más. En la segunda aplicación se estableció arbitrariamente un ciclo de trabajo con actividad de CPU cada 25 s. En las figuras 4 y 5 se ven los perfiles de consumo con esta 13

FIGURA 2: Perfil de consumo de Contiki original en modo de bajo consumo. Despertadas periódicas. FIGURA 3: Perfil de consumo de SinTicki en modo de bajo consumo. Despertadas cada 2 segundos. aplicación para Contiki y SinTicki, respectivamente. En ambas se aprecia una meseta de 2 ma con duración de 62 ms. También se ven en las dos figuras picos periódicos de mayor valor que representan otra actividad del nodo que no interesa en este análisis. Los pulsos correspondientes a los ticks no se pueden distinguir en la figura 4, porque la escala de voltajes los hace imperceptibles junto a la actividad del nodo. Los pequeños picos que se perciben son los ya mencionados que ocurren cada 2 ticks pa- 14

FIGURA 4: Perfil de consumo de Contiki original, con un evento agendado cada 25 s que mantiene encendida la CPU por 62 ms. FIGURA 5: Perfil de consumo de SinTicki, con un evento agendado cada 25 s que mantiene encendida la CPU por 62 ms. ra la lectura del buffer de memoria de la UART. En la figura 5 se ve que el consumo es plano cuando el microcontrolador está en LPM, sin ticks ni lectura del buffer de la UART. Se nota una diferencia entre los pisos de consumo vistos en las figuras correspondientes a la aplicación 1 y la aplicación 2. Esto se debe a que la aplicación 1 se asegura de desactivar elementos del mote que siguen actuando cuando el microcontrolador pasa a LPM. La aplicación 2 es la hello-world que trae como ejemplo Instant Contiki, a la que se le agregaron procesos y en la que no se tiene el mismo cuidado que en 1. La figura 6 muestra el perfil de consumo del nodo con actividad de radio. La meseta es de unos 12 ma durante unos 150 ms, lo que resulta un consumo de carga de aproximadamente 1800 µc. Este valor es mucho mayor que el consumo en LPM durante 2 segundos, tanto corriendo sobre Contiki como sobre SinTicki. 15

FIGURA 6: Perfil de consumo de aplicación sky-collect. La meseta corresponde a la radio encendida. 6.3. Cálculos En esta parte se determina el impacto que esta implementación tiene en el consumo total de una aplicación que utilice Contiki. Como se explicó en la sección 6.2.2, el consumo en carga de un solo tick es de alrededor de Q tick = 0, 2 µc. 6.3.1. Consumo base declarado por el fabricante Las hojas de datos del fabricante del MSP430 declaran un consumo base en LPM de I datasheet = 5 µa. El consumo promedio en LPM considerando los ticks es entonces: I LPM = I datasheet + Q tick T donde T es el período con el que ocurren los ticks. Contiki y SinTicki utilizan respectivamente: T Contiki = 7, 8 ms T SinTicki = 2 s lo que resulta en: I LPM Contiki = 30, 6 µa I LPM SinTicki = 5, 1 µa Sea I Act. el consumo activo de corriente, definido como I Act. = 1 Tiempo activo I(t) dt {tiempos activos} Entonces, el consumo total de corriente puede calcularse como I total = δi Act. + (1 δ)i LPM (1) siendo δ el ciclo de trabajo, es decir, la fracción de tiempo que el sistema se encuentra fuera del LPM. 6 En la figura 7 se presenta la relación entre los consumos I LPM e I total, en porcentaje, para el funcionamiento con tick. Puede verse como para ciclos de trabajo superiores al 10 % el consumo en LPM es menor que 5 % del total. 16

10 9 8 (1 δ) I LPM / I Total (%) 7 6 5 4 3 2 1 0 0 5 10 15 Ciclo de trabajo δ (%) [ ] (1 δ)ilpm FIGURA 7: Relación % en función del ciclo de trabajo. I total 10 9 8 7 Ahorro (%) 6 5 4 3 2 1 0 0 5 10 15 Ciclo de trabajo δ (%) [ FIGURA 8: Ahorro de ] corriente, calculado como el cociente Itotal Contiki I total SinTicki %, en función del ciclo de trabajo. I total Contiki 17

La figura 8 muestra el ahorro de corriente que representa usar SinTicki. Una aplicación con un ciclo de trabajo δ 5 % ahorra al menos 2 % de corriente, respecto a Contiki. Como referencia, un encendido por segundo, que consuma 20 ma durante 150 ms corresponde a un δ = 15 %. Para alcanzarse el ahorro del 2 % no podría encenderse mas de una vez cada tres segundos. 6.3.2. Consumo base medido Durante las pruebas en motes reales la corriente base en LPM difería considerablemente de la declarada por el fabricante. Esto pudo deberse a algún consumo parásito de los dispositivos del mote, por ejemplo, la memoria flash. Considerando este valor, se recalcula I LPM y los demás parámetros, lo que arroja los resultados mostrados en las figuras 9 y 10, que convenientemente utilizan las mismas escalas que 7 y 8. Ahora, la corriente consumida en LPM + ticks es una fracción más grande del total, como se ve en 9. Sin embargo, el ahorro porcentual, mostrado en 10, baja apenas, respecto a la figura 8. 6.3.3. Curvas paramétricas Por último, en la figura 11 se presentan las curvas de ahorro de corriente en función del ciclo de trabajo, para varios valores de I Act., suponiendo I LPM SinTicki = 5, 1 µa. 7. Conclusiones La primera conclusión es que se estudió y logró entender la arquitectura del RTOS Contiki en su versión 2.7; tanto la estructura de los procesos y eventos como la arquitectura de timers, central para este desarrollo, pues es lo que se quería modificar. El RTOS cuenta con una arquitectura flexible, que permitió modificarlo satisfactoriamente para que funcione con timers sin tick de forma transparente para el usuario; o sea, que las aplicaciones ya existentes funcionen sin tener que hacer modificación alguna al código fuente de las mismas. Se determinaron experimentalmente los consumos en las diferentes actividades del nodo. Se realizó un análisis comparativo del impacto que tiene la implementación de SinTicki sobre el consumo de energía de un nodo de red de sensores inalámbricos TelosB. Se estableció una expresión para analizar el consumo de acuerdo al ciclo de trabajo del nodo. Utilizando las hojas de datos del fabricante se determinó que el consumo de LPM + ticks en Contiki es del orden de 4 % para ciclos de trabajo menores que δ = 10 %. En cambio si se consideran las medidas reales, la fracción es de 1 % en el mismo rango. Así, el ahorro porcentual de corriente ronda, como mínimo, el 1 %, ya sea que se considere uno u otro caso, dependiendo de la corriente que consuma la aplicación en modo activo, pudiendo llegar hasta un 10 % en el caso de que solo se utilice el CPU. 6 A los efectos de los siguientes cálculos, se supondrá una I Act. = 20 ma, que es una aproximación razonable de lo que consume el mote cuando enciende la radio. 18

10 9 8 (1 δ) I LPM / I Total (%) 7 6 5 4 3 2 1 0 0 5 10 15 Ciclo de trabajo δ (%) [ ] (1 δ)ilpm FIGURA 9: Relación % en función del ciclo de trabajo. I total 10 9 8 7 Ahorro (%) 6 5 4 3 2 1 0 0 5 10 15 Ciclo de trabajo δ (%) [ FIGURA 10: Ahorro de ] corriente, calculado como el cociente Itotal Contiki I total SinTicki %, en función del ciclo de trabajo. I total Contiki 19

Ahorro (%) 10 9 8 7 6 5 4 3 2 1 2 ma 5 ma 10 ma 20 ma 30 ma 0 0 5 10 15 Ciclo de trabajo δ (%) FIGURA 11: Ahorro de corriente en función del ciclo de trabajo, paramétrico en I Act.. Considerando que el timer interrumpe al menos una vez cada 2 segundos (para el caso del registro TAR de 16 bits y f clock = 32 khz), se estimó cual sería el impacto de eliminar ese tick cambiando dinámicamente el prescaler del timer (o la fuente del reloj), para llevarlo a lo sumo hasta un tick cada 16 segundos. La cantidad de ticks ya fue reducida de 128 ticks/s a 0, 5 ticks/s (un factor de 256), mientras que esta solución lo reduciría solamente a 0, 0625 ticks/s, lo que no ameritaría la complejidad de la eventual implementación. 7.1. Futuros desarrollos Este trabajo podría complementarse tomando medidas más sofisticadas en escenarios más realistas, por ejemplo, redes que estuvieran ya desplegadas y funcionando en campo. De esta manera, el impacto del presente trabajo podría determinarse con mayor precisión. 20

8. Anexo Se presentan en este apartado los códigos fuente de los archivos de Contiki modificados y los códigos fuente de las pruebas realizadas. 8.1. Fuentes SinTicki./contiki/core/sys/clock.h 1 /* * \ addtogroup sys 2 * @{ 3 */ 4 5 /* * 6 * \ defgroup clock Clock library 7 * 8 * The clock library is the interface between Contiki and the platform 9 * specific clock functionality. The clock library defines a macro, 10 * CLOCK_ SECOND, to convert seconds into the tick resolution of the platform. 11 * Typically this is 1-10 milliseconds, e. g. 4* CLOCK_ SECOND could be 512. 12 * A 16 bit counter would thus overflow every 1-10 minutes. 13 * Platforms use the tick interrupt to maintain a long term count 14 * of seconds since startup. 15 * 16 * Platforms may also implement rtimers for greater time resolution 17 * and for real- time interrupts, These use a corresponding RTIMER_ SECOND. 18 * 19 * \ note These timers do not necessarily have a common divisor or are phase locked. 20 * One may be crystal controlled and the other may not. Low power operation 21 * or sleep will often use one for wake and disable the other, then give 22 * it a tick correction after wakeup. 23 * 24 * \ note The clock library need in many cases not be used 25 * directly. Rather, the \ ref timer " timer library ", \ ref etimer 26 * " event timers ", or \ ref trimer " rtimer library " should be used. 27 * 28 * \ sa \ ref timer " Timer library " 29 * \ sa \ ref etimer " Event timers " 30 * \ sa \ ref rtimer " Realtime library " 31 * 32 * @{ 33 */ 34 35 /* 36 * Copyright ( c) 2004, Swedish Institute of Computer Science. 37 * All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met : 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 21

44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and / or other materials provided with the distribution. 47 * 3. Neither the name of the Institute nor the names of its contributors 48 * may be used to endorse or promote products derived from this software 49 * without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `` AS IS '' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES ; LOSS OF USE, DATA, OR PROFITS ; OR BUSINESS INTERRUPTION ) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 * 63 * This file is part of the Contiki operating system. 64 * 65 * Author : Adam Dunkels < adam@ sics. se > 66 * 67 */ 68 # ifndef CLOCK_H 69 # define CLOCK_H 70 71 # include " contiki-conf.h" 72 73 /* * 74 * A second, measured in system clock time. 75 * 76 * \ hideinitializer 77 */ 78 # ifdef CLOCK_ CONF_ SECOND 79 # define CLOCK_ SECOND CLOCK_ CONF_ SECOND 80 # else 81 # define CLOCK_ SECOND ( clock_ time_ t ) 32 82 # endif 83 84 /* # define _ TST to enable ' Timer Without Tick ' functionality */ 85 # define _TST 86 87 # ifdef _TST 88 # define DUMMY_ TIMER_ TRIGGER 0 89 # endif 22

90 91 /* * 92 * Initialize the clock library. 93 * 94 * This function initializes the clock library and should be called 95 * from the main () function of the system. 96 * 97 */ 98 void clock_init ( void ); 99 100 /* * 101 * Get the current clock time. 102 * 103 * This function returns the current system clock time. 104 * 105 * \ return The current clock time, measured in system ticks. 106 */ 107 CCIF clock_ time_ t clock_ time ( void ); 108 109 /* * 110 * Get the current value of the platform seconds. 111 * 112 * This could be the number of seconds since startup, or 113 * since a standard epoch. 114 * 115 * \ return The value. 116 */ 117 CCIF unsigned long clock_ seconds ( void ); 118 119 /* * 120 * Set the value of the platform seconds. 121 * \ param sec The value to set. 122 * 123 */ 124 void clock_ set_ seconds ( unsigned long sec ); 125 126 /* * 127 * Wait for a given number of ticks. 128 * \ param t How many ticks. 129 * 130 */ 131 void clock_wait ( clock_time_t t); 132 133 /* * 134 * Delay a given number of microseconds. 135 * \ param dt How many microseconds to delay. 136 * 137 * \ note Interrupts could increase the delay by a variable amount. 138 */ 139 void clock_ delay_ usec ( uint16_ t dt ); 140 141 # ifdef _TST 142 /*---------------------------------------------------------------------------*/ 143 /* * 144 * Setup next timer interrupt 145 * \ param next_ t number of " ticks " for next scheduled trigger 146 */ 147 void 23

148 clock_setup ( clock_time_t next_t ); 149 # endif 150 151 /* * 152 * Deprecated platform- specific routines. 153 * 154 */ 155 int clock_fine_max ( void ); 156 unsigned short clock_ fine ( void ); 157 void clock_ delay ( unsigned int delay ); 158 159 # endif /* CLOCK_H */ 160 161 /* * @ } */ 162 /* * @ } */./contiki/core/sys/etimer.c 1 /* * 2 * \ addtogroup etimer 3 * @{ 4 */ 5 6 /* * 7 * \ file 8 * Event timer library implementation. 9 * \ author 10 * Adam Dunkels < adam@ sics. se > 11 */ 12 13 /* 14 * Copyright ( c) 2004, Swedish Institute of Computer Science. 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met : 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and / or other materials provided with the distribution. 25 * 3. Neither the name of the Institute nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `` AS IS '' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 24

33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES ; LOSS OF USE, DATA, OR PROFITS ; OR BUSINESS INTERRUPTION ) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * This file is part of the Contiki operating system. 42 * 43 * Author : Adam Dunkels < adam@ sics. se > 44 * 45 */ 46 47 # include " contiki-conf.h" 48 49 # include " sys / etimer.h" 50 # include " sys / process. h" 51 52 static struct etimer * timerlist ; 53 static clock_ time_ t next_ expiration ; 54 55 PROCESS ( etimer_process, " Event timer "); 56 /*---------------------------------------------------------------------------*/ 57 static void 58 update_time ( void ) 59 { 60 clock_ time_ t tdist ; 61 clock_ time_ t now ; 62 struct etimer * t; 63 64 if ( timerlist == NULL ) { 65 next_ expiration = 0; 66 # ifdef _TST 67 /* Setup dummy timer trigger */ 68 clock_setup ( DUMMY_TIMER_TRIGGER ); 69 # endif 70 } else { 71 now = clock_ time () ; 72 t = timerlist ; 73 /* Must calculate distance to next time into account due to wraps */ 74 tdist = t-> timer. start + t-> timer. interval - now ; 75 for (t = t-> next ; t!= NULL ; t = t-> next ) { 76 if ( t-> timer. start + t-> timer. interval - now < tdist ) { 77 tdist = t-> timer. start + t-> timer. interval - now ; 78 } 79 } 80 next_ expiration = now + tdist ; 81 # ifdef _TST 82 /* Setup timer trigger */ 83 clock_setup ( tdist ); 84 # endif 85 } 25