TinyOS (II)

Post date: Jul 4, 2013 5:15:53 PM

Inmediatamente despues de empezar a programar cualquier aplicación en TinyOS viene la necesidad de depurar.

Para ello en tinyOS podemos usar el simulador TOSSIM.

La primera tarea es generar las librerías que usaremos en el simulador. Para ello, con el propio Makefile que usamos compilar nuestro programa, generamos las librerías python que constituyen la simulación de nuestro programa.

tinyos-client$ ls

debug.py Makefile meyer-heavy.txt mqttApp.nc mqttC.nc mqtt.h mqtt.nc readme.txt salida sys

$ make iris sim

mkdir -p simbuild/iris

placing object files in simbuild/iris

writing XML schema to app.xml

compiling mqttApp to object file sim.o

ncc -c -shared -fPIC -o simbuild/iris/sim.o -g -O0 -tossim -fnesc-nido-tosnodes=1000 -fnesc-simulate -fnesc-nido-motenumber=sim_node\(\) -fnesc-gcc=gcc -Wall -Wshadow -Wnesc-all -target=iris -fnesc-cfile=simbuild/iris/app.c -board=micasb -DDEFINED_TOS_AM_GROUP=0x22 --param max-inline-insns-single=100000 -DIDENT_APPNAME=\"mqttApp\" -DIDENT_USERNAME=\"felix\" -DIDENT_HOSTNAME=\"homer\" -DIDENT_USERHASH=0x4fc24a01L -DIDENT_TIMESTAMP=0x51d5a51aL -DIDENT_UIDHASH=0x686b91f9L -Wno-nesc-data-race mqttApp.nc -fnesc-dump=components -fnesc-dump=variables -fnesc-dump=constants -fnesc-dump=typedefs -fnesc-dump=interfacedefs -fnesc-dump=tags -fnesc-dumpfile=app.xml

compiling Python support and C libraries into pytossim.o, tossim.o, and c-support.o

g++ -c -shared -fPIC -o simbuild/iris/pytossim.o -g -O0 -DIDENT_APPNAME=\"mqttApp\" -DIDENT_USERNAME=\"felix\" -DIDENT_HOSTNAME=\"homer\" -DIDENT_USERHASH=0x4fc24a01L -DIDENT_TIMESTAMP=0x51d5a51aL -DIDENT_UIDHASH=0x686b91f9L /opt/tinyos-2.1.1/tos/lib/tossim/tossim_wrap.cxx -I/usr/include/python2.5 -I/opt/tinyos-2.1.1/tos/lib/tossim -DHAVE_CONFIG_H

g++ -c -shared -fPIC -o simbuild/iris/tossim.o -g -O0 -DIDENT_APPNAME=\"mqttApp\" -DIDENT_USERNAME=\"felix\" -DIDENT_HOSTNAME=\"homer\" -DIDENT_USERHASH=0x4fc24a01L -DIDENT_TIMESTAMP=0x51d5a51aL -DIDENT_UIDHASH=0x686b91f9L /opt/tinyos-2.1.1/tos/lib/tossim/tossim.c -I/usr/include/python2.5 -I/opt/tinyos-2.1.1/tos/lib/tossim

g++ -c -shared -fPIC -o simbuild/iris/c-support.o -g -O0 -DIDENT_APPNAME=\"mqttApp\" -DIDENT_USERNAME=\"felix\" -DIDENT_HOSTNAME=\"homer\" -DIDENT_USERHASH=0x4fc24a01L -DIDENT_TIMESTAMP=0x51d5a51aL -DIDENT_UIDHASH=0x686b91f9L /opt/tinyos-2.1.1/tos/lib/tossim/hashtable.c -I/usr/include/python2.5 -I/opt/tinyos-2.1.1/tos/lib/tossim

linking into shared object ./_TOSSIMmodule.so

g++ -shared -fPIC simbuild/iris/pytossim.o simbuild/iris/sim.o simbuild/iris/tossim.o simbuild/iris/c-support.o -lstdc++ -o _TOSSIMmodule.so

copying Python script interface TOSSIM.py from lib/tossim to local directory

*** Successfully built iris TOSSIM library.

tinyos-client$ ls

app.xml debug.py Makefile meyer-heavy.txt mqttApp.nc mqttC.nc mqtt.h mqtt.nc readme.txt salida simbuild sys _TOSSIMmodule.so TOSSIM.py

A partir de aquí tenemos que crearnos un pequeño escenario de simulación que nos permita validar

nuestro software, en mi caso, que es un cliente MQTT para publicar eventos desde la propia mota:

from TOSSIM import *

import sys

t = Tossim([])

iris0 = t.getNode(0)

iris1 = t.getNode(1)

t.addChannel("Radio",sys.stdout)

r = t.radio()

iris0.bootAtTime(100001)

iris1.bootAtTime(800008)

r.add(0,1,-10)

noise = open("meyer-heavy.txt", "r")

lines = noise.readlines()

for line in lines:

str1 = line.strip()

if str1:

val = int(str1)

for i in range(2):

t.getNode(i).addNoiseTraceReading(val)

for i in range(2):

print "Creating noise model for ",i;

t.getNode(i).createNoiseModel()

print r.connected(0,1)

for i in range(100):

t.runNextEvent()

Que básicamente crea dos motas (iris0 e iris1), añade una traza de ruido (sin traza de ruido no funciona, esto no lo he investigado mucho), y a partir

de ese punto se crean 100 eventos.

De esta forma, con ejecutar:

$ python debug.py

Creating noise model for 0

Creating noise model for 1

True

DEBUG (0): Init..

DEBUG (0): Init..done

DEBUG (1): Init..

DEBUG (1): Init..done

DEBUG (0): periodic...

DEBUG (0): Sending connect.

DEBUG (0): buffer connect.(a)21.

DEBUG (0): Sending connect.28.

DEBUG (0): sending connect...ok!21.

DEBUG (1): periodic...

DEBUG (1): Sending connect.

DEBUG (1): buffer connect.(a)21.

DEBUG (1): Sending connect.28.

DEBUG (1): sending connect...ok!21.

DEBUG (1): SEND Done ....

DEBUG (1): send Done ..ok

DEBUG (0): SEND Done ....

DEBUG (0): send Done ..ok

DEBUG (0): periodic...

DEBUG (0): Sending connect.

DEBUG (0): buffer connect.(a)21.

DEBUG (0): Sending connect.28.

DEBUG (0): sending connect...ok!21.

DEBUG (1): periodic...

DEBUG (1): Sending connect.

DEBUG (1): buffer connect.(a)21.

DEBUG (1): Sending connect.28.

DEBUG (1): sending connect...ok!21.

DEBUG (1): Message RECEIVED.21.

DEBUG (0): SEND Done ....

DEBUG (0): send Done ..ok

DEBUG (1): SEND Done ....

DEBUG (1): send Done ..ok

DEBUG (0): periodic...

DEBUG (0): Sending connect.

DEBUG (0): buffer connect.(a)21.

DEBUG (0): Sending connect.28.

DEBUG (0): sending connect...ok!21.

DEBUG (1): periodic...

DEBUG (1): Sending connect.

DEBUG (1): buffer connect.(a)21.

DEBUG (1): Sending connect.28.

DEBUG (1): sending connect...ok!21.

DEBUG (1): SEND Done ....

DEBUG (1): send Done ..ok

DEBUG (1): Message RECEIVED.21.

DEBUG (0): SEND Done ....

DEBUG (0): send Done ..ok

DEBUG (0): periodic...

DEBUG (0): Sending connect.

DEBUG (0): buffer connect.(a)21.

DEBUG (0): Sending connect.28.

DEBUG (0): sending connect...ok!21.

DEBUG (1): periodic...

DEBUG (1): Sending connect.

DEBUG (1): buffer connect.(a)21.

DEBUG (1): Sending connect.28.

DEBUG (1): sending connect...ok!21.

DEBUG (1): SEND Done ....

DEBUG (1): send Done ..ok

podemos ver los mensajes de depuración que el código nesC ejecuta ante los diferentes eventos.

Por ejemplo, el cliente MQTT tiene en la parte de recepción una simple impresión de la longitud del mensaje recibido:

event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {

dbg("Radio", "Message RECEIVED.%hhu.\n",len);

return bufPtr;

}