Projet capteurs : 2011 - Romain Bitschené et Philippe Virouleau

De Ensiwiki
Aller à : navigation, rechercher

Présentation du projet

Matériel

Le projet se déroule sur les kits de développement Texas Instruments eZ430-rf2500. Ces kits contiennent :

  • 2 capteurs équipés d'un microtrolleur basse consommation TI MSP430 et d'une radio CC2500 opérant dans la bande des 2.4Ghz
  • Une interface de développement USB
  • Un conteneur de piles pour alimenter un capteur de manière autonome

Logiciels

  • Linux (ou n'importe quel UNIX like)
  • Compilateur MSPGCC
  • Utilitaire MSPDEBUG
  • Bibliothèques MRFI (Minimal RF Interface) et BSP (Board Support Package) de TI.
  • Gestionnaire de versions GIT

But

Schéma en couches expliquant à quel niveau nous avons travaillé
Schéma en couches expliquant à quel niveau nous avons travaillé

Les capteurs fournis peuvent être considérés comme vierge dans le sens où il n'y a rien d'autre présent dessus que quelques informations de configuration. Il est demandé à partir des outils libres énoncés plus haut, de la documentation disponible chez TI et des bibliothèques MRFI et BSP de créer un protocole permettant à ces capteurs de communiquer entre eux.


Protocole imposé

Le schéma ci-dessous décrit le protocole imposé à suivre.

Protocol eZ430-RF2500.png

Afin d'économiser les piles au maximum, on organise le cycle de vie des capteurs en périodes d'activité et d'inactivité. Tous les capteurs s'endorment et se réveillent en même temps, doivent s'annoncer dans le slot qui leur est attribué et ne pas émettre en dehors de la période d'activité.

On voit donc que deux aspects se dégagent : d'un côté la synchronisation, de l'autre le routage.

Travail Réalisé

Aspect synchronisation

États

L'implémentation du cycle de vie d'un capteur a été réalisée grace à une machine à état :

Projet Capteurs Machine a etat.png

On retrouve les 4 états suggérés par la spécification :

SCAN_STATE qui est l'état où l'on est en attente d'un beacon, et l'état de démarrage du timer. BEACON_STATE, durant lequel on envoi et reçoit les beacons. ACTIVE_STATE, durant lequel on procède à l'envoi et la reception de données. SLEEPING_STATE, durant lequel on est en économie d'énergie.

Les transitions sont définies par les différentes durée de chaque état.

Utilisation des timers

Pour réaliser la machine à état, nous avons utilisés les timers A et B de chaque capteur. L'horloge sur laquelle sont branchés les timers à une clock à 8 MHz, la taille des registres (16 bits) ne permet donc pas de programmer les timer pour les faire déclencher une interruption tous les duty cycle. Nous avons alors décidé que chacun des timers génèrerai une interruption toutes les milliseconde, et qu'on utiliserai deux autres variables (delay_a et delay_b) pour enregistrer le nombre de millisecondes écoulées depuis le lancement du timer.

Le timer A gère deux transitions : celle entre le SCAN_STATE et le BEACON_STATE, ainsi que celle entre le SLEEPING_STATE et le BEACON_STATE suivant. En régime continu il gère donc le redémarage des Duty Cycle.

Le timer B intervient au sein d'un Duty Cycle pour gérer la transition entre le BEACON_STATE et l'ACTIVE_STATE, et celle entre l'ACTIVE_STATE et le SLEEPING_STATE.

Description des actions associées aux états

SCAN_STATE

Pendant cet état, deux actions peuvent être déclenchées : la syncronisation sur un réseau existant (si on reçoit un beacon durant cet état), ou la création d'un nouveau réseau, si l'on n'a pas reçu de beacon à la fin du SCAN_STATE. Dans ce cas là on emet alors notre beacon dans le slot 0 plutôt que dans notre slot.

BEACON_STATE

L'action principale du capteur consiste à envoyer le beacon dans son slot, mais il y a aussi des actions déclenchées à la reception d'un beacon durant cet état. Il peut y avoir ici deux cas de figure : soit le beacon que l'on reçoit n'est pas celui du capteur sur lequel on est syncronisé, et il n'y a qu'une mise à jour de la table de routage. Dans le cas ou le beacon reçu est celui du capteur sur lequel on est syncronisé, on va également réajuster les différentes valeurs de nos timers pour les syncroniser sur ceux de l'initiateur du réseau. Le cas basique est celui ou il faut ajuster la valeur de delay_a sur le slot courant, à savoir delay_a = ref * DUREE_SLOT, et corriger cette valeur en fonction de l'arrivée du beacon dans le slot : l'augmenter si le beacon est en début de slot, la diminuer s'il est en fin de slot, et enfin tenir compte du temps de transfert d'un beacon.

ACTIVE_STATE

C'est pendant cette période que l'on va transmettre les paquets en attente : ils sont gérés par une pile, et périodiquement pendant cet état, on envoi celui en haut de la pile. Il y a également une autre action qui est déclenchée tous les ROUTING_BCAST_DELAY ACTIVE_STATE : la mise en pile d'attente de la table de routage du capteur. À la fin de cet état, la radio est éteinte et on entre en low power mode.

Aspect routage

Table de routage

Afin de pouvoir faire du relayage de packets il faut entretenir des tables de routage sur chacun des capteurs. Chaque capteur possède donc un tableau de structures pour représenter cette table.

Table de routage
Next Hop Hops Timeout
0x01 0 2
... ... ...
x x 0

Le entrées de la table sont indexés par @dst - 1 (i.e l'entrée pour atteindre 0x01 se trouve à l'indice 0). Le champ timeout sert à indiquer qu'une route à expiré (timeout = 0). Next hop représente le noeud à qui s'addresser pour faire suivre le packet et hops le nombre de noeuds intermédiaires.

Cette table est propagée aux voisins périodiquement qui vérifient s'ils peuvent trouver une meilleure route que ce qu'ils possèdent actuellement. La table est envoyée dans un ou plusieurs packets avec le flag FROUTING.

Packet forwarding

Pour indiquer qu'un packet doit être relayé il faut l'indiquer dans ses flags avec le flag FFORWARD, lever ce flag implique d'ajouter l'addresse de destination finale dans le premier octet de data. Un noeud qui reçoit un paquet FFORWARD peut le traiter de 2 manières :

  • Si la destination finale se trouve à proximité directe (hops = 0) alors on retire le flag FFORWARD, on remplace le champs destination du packet et on enlève l'adresse finale du data.
  • Sinon on remplace simplement l'adresse de destination par celle du noeud suivant dans la table.

Bugs connus & Amélioration possibles

  • [TODO] Pouvoir fusionner 2 réseaux
  • [TODO] Limiter la durée de vie d'une trame (équivalent du TTL de IP)
  • [TODO] Étudier plus précisement l'influence de la durée d'un duty cycle sur le décalage de syncronisation.
  • [TODO] Baisser la durée d'un slot pour la syncronisation
  • [BUG] L'échange de table de routage peut mener à une fausse route entre 2 noeud chacun pointant vers l'autre. Ceci est dût au fait que les tables échangés ont été emputées du champ timeout. Afin de régler le problème il suffit de changer le format des tables échangées pour y réinclure la valeur courante du timeout.

Difficultés

  • Obtenir une synchronisation stable est compliqué, toute la programmation étant basée sur des interruptions il suffit de peu pour retarder le traitement d'un timer et donc perdre la synchronisation avec le réseau
  • Débugger un capteur n'est pas aussi évident qu'un programme dans un OS, bien que des outils tels que GDB existent il est impossible de les utiliser sur un réseau synchronisé au risque de perdre la synchronisation à nouveau.
  • MRFI propose une implémentation du driver radio ne possédant qu'un seul slot dans son buffer, autrement dit des appels successifs trop rapides à la MRFI_Transmit écrasent le packet précédent qui ne sera donc jamais transmit.
  • Le MSP430F2274 ne possède qu'un 1Ko de RAM, autrement dit on se retrouve extrêmement rapidement à exploser la pile et donc à perdre le contrôle du programme.

Liens

Sources