La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

TinyOS Programación Orientada a componentes SISEM 2009.

Presentaciones similares


Presentación del tema: "TinyOS Programación Orientada a componentes SISEM 2009."— Transcripción de la presentación:

1 TinyOS Programación Orientada a componentes SISEM 2009

2 Objetivos Exponer los lineamientos generales de un lenguaje usado para SisEm -> RTOS Diferencias con otros lenguajes o sistemas. Razones que motivan la elección del mismo Algunos ejemplos de uso

3 División en temas: 1. Características Generales Robustez (confiablilidad) Jerarquía – Modularidad 2. Caraterísticas de tiempo real Sincrónico - asíncrono Tareas Eventos

4 Conocimientos necesarios Esencialmente contenidos dentro de SisEm y DesaSoft C, y algo de C++, o Java Punteros “Algo” de sistemas operativos Conocer sobre concurrencia, interrupciones y preemption.

5 Programación orientada al componente Programación en nesC / TinyOS es similar a programar en un lenguaje de descripción de hardware.

6 TinyOS se basa en nesC

7 nesC (network embedded system C) Es un dialecto de C basado en componentes. Programación simple: –Todo lo que se requiere es implementar algunos módulos e interconectarlos entre sí. –La dificultad se presenta al interconectar aplicaciones complicadas (incorporar nuevos códigos a los ya existentes).

8 Modelo de enlazado (Linking) La diferencia esencial con C radica en el modelo de enlazado de los módulos –Como funciona el enlazado en C, C++ (desde el punto del programador) y cómo esto afecta la estructura de un código. –Al analizar esto mismo en nesC, se entenderán las diferencias

9 C Un solo namespace global para funciones y variables Tres formas de nombrar una variable: Declaración (establece que existe una variable) Definición (crea efectivamente la variable) (*) Referencia (usa la variable) (*) implementa la función o aloja la variable

10 C Alcance Global Variables globales y funciones no- estáticas poseen un alcance global (cualquier código puede hacer referencia a las mismas)

11 Interdependencia Si dos archivos fuente hacen referencia al mismo nombre de función, están haciendo referencia a la misma función Esto puede dar lugar a dependencias no deseadas entre dos códigos Si quiero cambiar mi implementación le cambio también la implementación a los demás

12 Punteros a funciones Una forma de resolver en C esta interdependencia es con punteros a funciones En lugar de hacer referencia a una función específica, un código puede hacer referencia a una varible que almacena un puntero a una posible función Esto permite resolver vínculos en tiempo de ejecución al elegir qué puntero almacenar en dicha variable

13 Indirección Esto le permite al código C hacer referencia o llamar a nuevas extensiones que no existían en el momento en que fué compilado Elemento crítico en cualquier sistema que use este procedimiento.

14 Callback Un callback es un código ejecutable que se pasa como argumento a otro código. Permite que una capa de nivel bajo llame una subrutina (o función) definida en una capa de mayor nivel.

15 Función Callback Def. 2 Una función callback, es una función que es llamada a través de un puntero a función. Si se pasa el puntero (dirección) de una función como argumento de otra, cuando tal puntero es usado para llamar la función apunta a lo que se denomina un call back.

16 Ejemplo: GUI en C Una herramienta GUI debe poder llamar funciones en respuesta a eventos generados por el usuario La función - con determinado comportamiento - es parte del código de la aplicación (ej. Botón llama función) La herramienta GUI precompilada debe poder llamar a esta función (cuyo nombre no conoce)

17 Ejemplo button Cuando una aplicación crea un botón le da un puntero a una función para que la llame cuando es “clickeado” La estructura botón almacena este puntero en RAM Este puntero debe ser asignado en tiempo de ejecución

18 C++ C++ complica aún más las cosas agregando jerarquías de namespaces Una clase define un namespace Existen diferencias entre private de C++ y static de C, java también tiene lo suyo pero no entraremos en los detalles

19 Conclusiones del namespace: El espacio global de nombres de C, C++ o Java se traduce en composición dinámica Hacer referencia a una función significa refererirse a un nombre único en el espacio global Por eso se hace necesario usar punteros a funciones para desacoplar las implementaciones entre si.

20 Visión nesC nesC toma otro camino: 1)El código se parte en componentes (unidades discretas de funcionalidad) 2)Un componente sólo puede hacer referencia a las variables de su propio espacio de nombres (local) 3)Un componente no puede nombrar una variable de otro componente 4)En cambio, si puede declarar que usa una función definida por otro componente 5)También puede declarar que provee una función que otro componente podrá usar

21 Tipos de Componentes Existen dos tipos de componentes: – Modulos: Implementan comportamiento – Configuraciones: Interconectan componentes entre si.(Estructura) A un componente no le importa si otro componente es un módulo o una configuración Un componente puede estar compuesto de otros componentes

22 Módulos proveen código que implementa una o mas interfaces y el comportamiento interno del componente

23 Interface y módulo Interface A Funcion X Funcion Y Modulo M Provee interface A Implementa funciones X e Y

24 Configuraciones Unen entre sí a los componentes para dar lugar a un nuevo componente

25 nesC vs C Los módulos TinyOS son análogos al código C En cambio las configuraciones – que pegan los componentes entre si- no lo son.

26 Componentes vs Objetos En cierta forma, los componentes nesC son similares a los objectos. encapsulan estados y los dotan con funcionalidad. La principal diferencia recae en el alcance de los nombres (naming scope)

27 Diferencia con objetos Los objetos en C++ y Java se refieren a funciones y variables en un espacio de nombres (namespace) global Las componentes nesC usan un namespace local Además de declarar las funciones que implementa, un componente debe también declarar las funciones que usa (o llama).

28 Interconexión Para que un componente pueda usar una función que otro provee, es necesario que previamente se interconecten explícitamente usuario con proveedor USUARIO PROVEEDOR Al ser una interconexión a un punto específico, el compilador puede optimizar el llamado de las mismas a través de las fronteras (interfaces)

29 Composición en tiempo de compilación Dado que esta composicion ocurre en tiempo de compilación, no require alojar memoria o almacenar punteros a funciones en RAM en tiempo de ejecución. Al no usar estos niveles de indirección, el compilador nesC conoce el grafo completo de la llamada.

30 Interfaz Es raro que un componente declare funciones individuales en su especificación. Los componentes se unen mediante interfaces, las cuales constituyen un conjunto de comandos y eventos lógicamente relacionados entre sí

31 Contratos de Interface Se han reportado casos de errores provenientes de restricciones en el uso de las interfaces. Muy comunmente es necesario leer el código de los componentes para poder usarlos con éxito, lo cual contradice el principio de jerarquia. Existen trabajos que pretenden resolver estos problemas mediante la especificación y el cumplimiento de contratos de interfaz.

32 ¿Por qué esta forma extraña de hacer las cosas?

33 Características de nodos Sensores Tamaño pequeño, bajo consumo Operación altamente concurrente -Flujo múltiple, no se espera - respuesta - al comando  Modularidad  Interfaces simples sensoresactuadores red almacen Operación Robusta numerosos, no atendidos, critical Timers

34 Computador Embebido A diferencia de los computadoras personales que necesitan cargar programas dinámicamente en respuesta al requerimiento de los usuarios, las redes de sensores se componen de computardores embebidos, que tienen usos específicos bien definidos.

35 Visión Estatica Esto puede evolucionar y cambiar con el tiempo, pero esta evolución es lenta en comparación con la forma en que una PC carga programas. Adicionalmente los sistemas embebidos no requieren de una interacción permanente con el usuario como lo hacen las PC.

36 sistemas sin atención Si el servidor se pone loco lo reiniciamos. Si el procesador de texto enlentece lo cerramos y volvemos a abrir. Esto no pasa en sistemas embebidos que operan sin atención de usuario la mayor parte del tiempo.

37 Hardware CPU ADC convertir pronto

38 Split Phase El Hardware por lo general no bloquea, es casi siempre split-phase. Es split-phase en el sentido que al completar un pedido genera un callback (interrupción al sistema).

39 Software Comunicaciones entre procesos El pasaje de mensajes puede ser: Sincrónico (blocking): El transmisor espera hasta que el receptor haya recibido el mensaje. Asíncrono (non-blocking): el transmisor no espera

40 Si un conversor ADC interrumpe demasiado rápido el driver del mismo debería poder solucionarlo con un simple loop de espera a que se dispare. En cambio si la interrupción es lenta, esto gastaría mucha CPU y ciclos de energía. La solución tradicional para este último caso consiste en el uso de multiple threads

41 Caso RTOS (Sincrónico) Cuando un thread pide una muestra al ADC, el OS hace el pedido y coloca a dicho thread en cola de espera (WAIT), inicia la operación y luego pone a correr otro thread que estaba READY. Cuando el ADC interrumpe, el driver retoma el thread que estaba en WAIT (OS lo pasa a la cola READY).

42 threads en sistemas embebidos El problema es que requieren bastante uso de RAM. cada thread tiene un stack privado que debe ser guardado cuando el thread pasa a “waiting” o “idle”. P.ej. cuando thread muestrea un ADC y es colocado en cola de espera, toda la memoria de su stack de llamada debe permanecer intacta para poder continuar cuando retome la ejecución.

43 Solución TinyOS en lugar de hacer todo sincrónico a través de threads se opta por: –Las operaciones que son split-phase en hardware se hacen split-phase en software. –Esto significa que muchas operaciones comunes como muestrear sensores y enviar paquetes a la radio, son split-phase.

44 Interfaz bidireccional USER – PROVIDER USER PROVIDER Down Call Command Up Call Event Interface Bidireccional

45 comandos y eventos Una característica importante de la interfaz split- phase es que es bidireccional: Hay una “downcall” para iniciar la operación, Y un “upcall” que significa que la operación se ha completado. En nesC, downcalls son generalmente commands, mientras que upcalls son events

46 event Un event es una función mediante la cual la interfaz de la aplicación señala que ha tenido lugar cierto suceso. Una interfaz no solo provee commands que puedan ser llamados por sus usuarios (users), sino que también señala events, estos a su vez llaman “handlers” que deben ser implementados por el usuario.

47 Debemos pensar al evento como una función callback que la interfaz de la aplicación invoca. Un módulo que usa (uses) una interfaz debe implementar los eventos (events) que dicha interfaz usa. IMPLEMENTACIÓN DE LOS EVENTOS

48 Los Componentes implementan los eventos que usan y los comandos que proveen

49 Composición Componente Lector StdControl Timer Read provides uses provides interface StdControl; interface Timer ; uses interface Read

50 Messaging Component init Power(mode) TX_packet(buf) TX_packet_done (success) RX_packet_done (buffer) Internal State init power(mode) send_msg(addr, type, data) msg_rec(type, data) msg_send_done) internal thread Commands Events

51 Resumen Caracteríticas Scheduler + Grafo de Componentes –Modelo scheduling restringido a dos niveles: comandos + eventos Componente: –Comandos, –Event Handlers –Frame (almacenamiento) –Tasks (concurrency) Modelo de almacenamiento restringido

52 Resumen

53 Data Memory Model STATIC memory allocation! – No heap (malloc) – No function pointers Variables - frame por componente Variables locales – Saved on the stack stack compartido – Declared within a method

54 Modelo de Programación Separación entre construcción y composición Programas hechos mediante componentes Cada componente se especifica mediante una interfaz – Provee “hooks” para conectar componentes entre si. Los componentes se hallan conectados entre sí en forma estática basada en sus interfaces –Aumenta la eficiencia en tiempo de ejecución

55 Modelo de Concurrencia TinyOS ejecuta un solo programa formado por los componentes del sistema que hayamos elegido y por los componentes a medida hechos por nosotros para la aplicación específica. Existen dos threads de ejecución: “tasks” y “hardware event handlers”.

56 Cada componente tiene una especificación, un bloque de código que declara las funciones que provee (implementa) y las funciones que usa (llama).

57 Que un componente provea o use la interfaz Send interface es lo que define de qué lado de la operación split-phase se encuentre. Un proveedor de Send define las funciones send y cancel y puede señalizar el evento sendDone. Por el contrario un usuario de Send necesita definir el evento sendDone y llamar a los comandos send y cancel.

58 Ejemplos

59 interfaz StdControl Para controlar el consumo es necesario prender y apagar partes del circuito, tales como encender un sensor para tomar una lectura o la radio para escuchar si se reciben paquetes. La interfaz StdControl es la encargada de realizar estas operaciones.

60

61 Un componente que representa un servicio que puede ser apagado debe proveer la interfaz StdControl Mientras que un componente que necesita encender o apagar a otros usa dicha interfaz.

62 ejemplo Una capa de ruteo necesita arrancar una capa de enlace de paquetes La cual a su vez necesita arrancar y parar la detección de canal libre:

63

64 Wiring El código RoutingLayerC llama a las funciones: SubControl.start() y SubControl.stop(). A menos que SubControl se cablee a un proveedor, estas funciones son símbolos indefinidos, no están vinculados a ningún código existente. En cambio si SubControl se cablea al StdControl de PacketLayerC, entonces cuando RoutingLayerC llama a SubControl.start() está invocando a StdControl.start() de Packet- LayerC. Esto significa que la referencia RoutingLayerC.SubControl.start apunta a la definición: PacketLayerC.StdControl.start.

65 Encapsulado Las dos componentes RoutingLayerC y PacketLayerC se hallan completamente desacopladas y solamente se vinculan cuando se cablean entre sí.

66 Timer.nc interface Timer { command result_t start(char type, uint32_t interval); command result_t stop(); event result_t fired(); } Here we see that Timer interface defines the start() and stop() commands, and the fired() event.

67 El comando start() se usa para especificar el tipo de timer y el intervalo en el cual el timer expirará. La unidad del argumento intervalo es milisegundo. Los tipoa válidos son: TIMER_REPEAT y TIMER_ONE_SHOT. Un timer one-shot termina al cumplirse su tiempo Un timer repeat solo se detiene con un comando stop().

68 ¿Cómo sabe una aplicación cuando ha expirado su timer? Respuesta: Cuando recibe un evento que provee la interfaz Timer: event result_t fired();

69 Configuration configuration Blink { } implementation { components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> SingleTimer.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC; }

70 module /** * Implementation for Blink application. Toggle the red LED when a * Timer fires. **/ module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; } // continua

71 StdControl.init() implementation { /** * Initialize the component. * * @return Always returns SUCCESS **/ command result_t StdControl.init() { call Leds.init(); return SUCCESS; }

72 StdControl.start() /** * Start things up. This just sets the rate for the clock component. * * @return Always returns SUCCESS **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); }

73 StdControl.stop() /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns SUCCESS **/ command result_t StdControl.stop() { return call Timer.stop(); }

74 Timer.fired() /** * Toggle the red LED in response to the Timer.fired event. * * @return Always returns SUCCESS **/ event result_t Timer.fired() { call Leds.redToggle(); return SUCCESS; }

75 Makefile COMPONENT=Blink include../Makerules

76 Tutorial TinyOS Tutorial http://docs.tinyos.net/index.php/TinyOS_Tutorials

77 TinyOS Enhancement Proposals (TEPs) TinyOS 2.0 Core Working Group http://www.tinyos.net/scoop/special/working_ group_tinyos_2-0


Descargar ppt "TinyOS Programación Orientada a componentes SISEM 2009."

Presentaciones similares


Anuncios Google