#include “BaudRate.java”

July 02, 2012 | 3 Minute Read

Ebbene sì: il titolo che vedete non è per nulla inventato. Ma andiamo con ordine.

Esiste un sistema operativo: TinyOS. E’ pensato per reti di sensori, le quali sono costituite da devices che si interfacciano con i computer tramite porta seriale (travestita da USB, ma poco importa in questo contesto). Di conseguenza, tale OS viene distribuito con un set di librerie in alcuni linguaggi per leggere e deserializzare il più comodamente possibile i messaggi trattati all’interno del sistema stesso, così da poter ricevere i dati ed elaborarli in qualche modo. La struttura standard di una WSN, infatti, prevede che uno dei devices funga da sink e riceva le comunicazioni dell’intera rete, per poi trasferire queste informazioni in un computer (che le salverà in qualche formato). I linguaggi di questo piccolo SDK sono C, C++, Java e Python.

Per poter interfacciare un device di una WSN con un computer a bassa potenza come una Carambola, è necessario utilizzare le versioni C o C++, dato che sia Python che Java non sono tendenzialmente supportati su quel tipo di schede. Ora, mentre sfogliate i sorgenti che leggono le porte seriali, potreste imbattervi nella seguente riga:

#include “../../java/net/tinyos/packet/BaudRate.java”

Tah-da! Un file sorgente C include un file Java al suo interno! Vi lascio qualche momento per rabbrividire adeguatamente della cosa…

Ok, l’idea di fondo è la seguente: esiste una lista riempita in un file Java strutturata come segue:

package net.tinyos.packet;

class BaudRate {
static void init() throws Exception {
Platform.add(Platform.x, “mica”, 19200);
Platform.add(Platform.x, “mica2″, 57600);

}
}

Il problema è che tale lista è necessaria anche nella versione C (che deduco essere arrivata dopo quella Java), e anzichè replicare le informazioni, gli sviluppatori hanno deciso di includere il file Java dentro quello C.

La sintassi è adeguatamente simile, e per far funzionare il giochino (come spiegano alcuni commenti del file C) è necessario:

  1. definire alcune define (perdonate il gioco di parole), affinchè la dichiarazione di package, di classe e di metodo non interferiscano in alcun modo con il codice C; tali definizioni si trovano in fondo al file C, dato che (mi è stato fatto notare) probabilmente scrivere qualcosa come “#define void” e ridefinire parole chiave che esistono in C creerebbe troppi problemi in altri punti del codice (ma non sono certo di questo)
  2. definire alcune struct con puntatori a tipi e funzioni, così che le chiamate del tipo “Platform.add” vengano interpretate correttamente e, come conseguenza, la variabile “args” alla fine contenga esattamente il secondo e terzo parametro della linea corretta tra le varie “add” (il secondo parametro è riempito dai sorgenti, tutto questo sistema serve per fare una sorta di lookup tra le linee “add” e ricavare il numero che indica il baudrate da utilizzare nella comunicazione con la seriale).

Chiaro, no? Non sono sicuro di riuscire a scendere ulteriormente nel dettaglio delle struct stesse, dato che sono un tantino convolute ed io non scrivo codice C da un po’, ma sono certo che un’occhiata ai sorgenti permetterà ai nerdoni tra voi di capire al volo come funziona il meccanismo!