Creación de módulos e interfaces en nesC para TinyOS 2
Después de pelearme con tinyOS he conseguido comprender mas o menos como va el tema de los módulos y wiring (conexionado lógico entre módulos). Aquí dejo un ejemplo muy básico y la explicación que ilustra lo suficiente para poder comenzar a hacer cosillas.
Introducción
tinyOS se basa en el uso de módulos que se "cablean" (wiring) entre sí para dar lugar a la aplicación en sí. Este cableado se lleva a cabo en lo que se conoce como configuraciones y podemos tener montones de configuraciones distintas para una misma aplicación. De este modo, podemos conseguir que una misma aplicación pueda correr en distintas arquitecturas hardware sin apenas tocar código, solo modificando las configuraciones, lo que hará que se utilicen unos módulos u otros que se encargan del control a mas bajo nivel. Básicamente, aquí hablaré de:- Módulos
- Interfaces
- Configuraciones
javieralso@richie:~$ svn co https://arco.inf-cr.uclm.es/svn/public/prj/tinyOS
Interfaces
Las interfaces se pueden definir como la parte "visible" de los módulos. No se puede acceder a ninguna función de un módulo si antes no ha sido definida en una interfaz. Una interfaz puede ser provista por varios módulos distintos. Por ejemplo, podemos tener una interfaz de comunicaciones que abstraiga los procedimientos de envío y recepción de mensajes y varios módulos que hagan uso de esa interfaz, uno para cada tipo de hardware subyacente (por ejemplo no se maneja igual el hardware de comunicaciones de una mica2 que el de una telos). Los métodos serán los mismos y se llamarán igual (la interfaz es la misma), pero la implementación interna puede ser totalmente distinta. Nosotros lo veremos como una caja negra. En nuestro ejemplo se utilizan dos interfaces: interfaz2, en el archivo interfaz2.nc e interfazPRB en el archivo interfazPRB.nc. Las implementaciones son las que siguen:interface interfaz2 {
command void i2c1();
command uint16_t i2c2(int c);
command uint16_t i2c3(char d);
}
interface interfazPRB {
command void comando1();
command int comando2(int c);
}
Módulos
Los módulos implementan bloques funcionales generalmente de un nivel de abstracción más bajo que el bloque que los referencia. Un mismo módulo puede proveer varias interfaces y por lo tanto puede implementar distintas funcionalidades (Por ejemplo el módulo AMSender provee las interfaces Packet, AMPacket, AMSend, etc...). Lo lógico es que todos los conjuntos de funciones (interfaces) que implementa un módulo guarden algún tipo de relación. En nuestro caso, utilizamos dos módulos: modulo2C, implementado en modulo2C.nc y moduloC implementado en moduloC.nc. Éste es el contenido de los archivos:module modulo2C {
provides {
interface interfaz2;
/*
Única interfaz proporcionada por el módulo
*/
}
}
implementation
{
command void interfaz2.i2c1() {
int v1 = 5;
int v2;
v2 = v1;
}
command uint16_t interfaz2.i2c2(int c) {
return (uint16_t)2*c;
}
command uint16_t interfaz2.i2c3(char d) {
return (uint16_t)d*d*d;
}
}
module moduloC {
provides interface interfazPRB;
uses {
interface interfaz2;
interface Leds;
}
}
implementation {
command void interfazPRB.comando1() {
call Leds.led0Toggle();
call Leds.led1Toggle();
call Leds.led2Toggle();
}
command int interfazPRB.comando2(int c) {
call Leds.set((uint8_t)c);
return 0;
}
}
Configuraciones
Como se ha dicho anteriormente, una aplicación escrita para tinyOS se compone de implementación de módulos y de configuraciones. En algunos casos, pueden hacerse aplicaciones solo con archivos de configuraciones. Un archivo de configuración consiste básicamente en un archivo formado por los módulos (o componentes) a utilizar en la aplicación y la relación que hay entre dichos módulos y las interfaces utilizadas por otros módulos. En un principio esto puede parecer bastante lioso, así que nada mejor que verlo con algún ejemplo. Veamos primero el archivo de configuración moduloEjm.nc:configuration moduloEjmC {
provides interface interfazPRB;
}
implementation {
components LedsC;
components modulo2C;
components moduloC;
moduloC.Leds -> LedsC;
moduloC.interfaz2 -> modulo2C;
interfazPRB = moduloC;
}
- moduloC.Leds -> LedsC;
- moduloC.interfaz2 -> modulo2C;
configuration ejmAppC{}
implementation
{
components MainC, ejmC;
components moduloEjmC;
ejmC -> MainC.Boot;
ejmC.interfazPRB -> moduloEjmC;
}
module ejmC {
uses interface Boot;
uses interface interfazPRB;
}
implementation {
event void Boot.booted() {
call interfazPrb.comando1();
}
}
Referencias
- Página principal de tinyOS: www.tinyos.net
- Documentación y tutoriales on-line acerca de tinyOS 2: www.tinyos.net/tinyos-2.x/doc/
[ show comments ]
blog comments powered by Disqus