TinyOS est un système d’exploitation open-source conçu pour des réseaux de capteurs sans fil.
Il respecte une architecture basée sur une association de composants, réduisant la taille du code nécessaire à sa mise en place. Cela s’inscrit dans le respect des contraintes de mémoires qu’observent les réseaux de capteurs.
Pour autant, la bibliothèque de composant de TinyOS est particulièrement complète puisqu’on y retrouve des protocoles réseaux, des pilotes de capteurs et des outils d’acquisition de données. L’ensemble de ces composants peut être utilisé tel quel, il peut aussi être adapté à une application précise.
En s’appuyant sur un fonctionnement événementiel, TinyOS propose à l’utilisateur une gestion très précise de la consommation du capteur et permet de mieux s’adapter à la nature aléatoire de la communication sans fil entre interfaces physiques.
Propriétés principales
TinyOS est un système principalement développé et soutenu par l’université américaine de Berkeley, qui le propose en téléchargement sous la licence BSD et en assure le suivi. Ainsi, l’ensemble des sources sont disponibles pour de nombreuses cibles matérielles. Il a été programmé en langage NesC.
Le fonctionnement d’un système basé sur TinyOS s’appuie sur la gestion des évènements se produisant. Ainsi, l’activation de tâches, leur interruption ou encore la mise en veille du capteur s’effectue à l’apparition d’évènements, ceux-ci ayant la plus forte priorité. Ce fonctionnement évènementiel (event-driven) s’oppose au fonctionnement dit temporel (time-driven) où les actions du système sont gérées par une horloge donnée. TinyOS a été conçu pour minimiser la consommation en énergie du capteur. Ainsi, lorsqu’aucune tâche n’est active, il se met automatiquement en veille.
Cependant, TinyOS ne gère pas le mécanisme de préemption entre les tâches mais donne la priorité aux interruptions matérielles. Ainsi, les tâches entre elles ne s’interrompent pas mais une interruption peut stopper l’exécution d’une tâche. Il n'est également pas prévu pour avoir un fonctionnement en temps réel.
Allocation de la mémoire
TinyOS a une empreinte mémoire très faible puisqu’il ne prend que 300 à 400 octets dans le cadre d’une distribution minimale. En plus de cela, il est nécessaire d’avoir 4 Ko de mémoire libre qui se répartissent entre 3 composants :
- La pile : sert de mémoire temporaire au fonctionnement du système notamment pour l’empilement et le dépilement des variables locales.
- Les variables globales : réservent un espace mémoire pour le stockage de valeurs pouvant être accessible depuis des applications différentes.
- La mémoire libre : pour le reste du stockage temporaire.
La gestion de la mémoire possède de plus quelques propriétés. Ainsi, il n’y a pas d’allocation dynamique de mémoire et pas de pointeur de fonctions. Bien sûr cela simplifie grandement l’implémentation.
Par ailleurs, il n’existe pas de mécanisme de protection de la mémoire sous TinyOS ce qui rend le système particulièrement vulnérable aux crashs et corruptions de la mémoire.
Structure logicielle
Le système d’exploitation TinyOS s’appuie sur le langage NesC. Celui-ci propose une architecture basée sur des composants, permettant de réduire considérablement la taille mémoire du système et de ses applications. Chaque composant correspond à un élément matériel (LEDs, timer, ADC…) et peut être réutilisé dans différentes applications. Ces applications sont des ensembles de composants associés dans un but précis.
Les composants peuvent être des concepts abstraits ou bien des interfaces logicielles aux entrées-sorties matérielles de la cible étudiée (carte ou dispositif électronique).
L’implémentation de composants s’effectue en déclarant des tâches, des commandes ou des évènements.
- Une tâche est un travail de « longue durée ».
- Une commande est l'exécution d’une fonctionnalité précise dans un autre composant.
- Un événement est l'équivalent logiciel à une interruption matérielle.
Les tâches sont utilisées pour effectuer la plupart des blocs d’instruction d’une application. À l’appel d’une tâche, celle-ci va prendre place dans une file d’attente de type FIFO (First In First Out) pour y être exécutée. Comme nous l’avons vu, il n’y a pas de mécanisme de préemption entre les tâches, et une tâche activée s’exécute en entier. Ce mode de fonctionnement permet de bannir les opérations pouvant bloquer le système (inter-blocage, famine, …). Par ailleurs, lorsque la file d’attente des tâches est vide, le système d’exploitation met en veille le dispositif jusqu’au lancement de la prochaine interruption (on retrouve le fonctionnement event-driven).
Les évènements sont prioritaires par rapport aux tâches et peuvent interrompre la tâche en cours d’exécution. Ils permettent de faire le lien entre les interruptions matérielles (pression d’un bouton, changement d’état d’une entrée, …) et les couches logicielles que constituent les tâches.
Dans la pratique, NesC permet de déclarer 2 types de composants : les modules et les configurations. Voici un second tableau récapitulatif :
Composant
|
Utilisation
|
Module
|
Contient le code d’un composant élémentaire.
|
Configuration
|
Permet de faire les liens entre différents modules.
|
Interface
|
Définit les entrées-sorties et le comportement d’un composant.
|
Les modules constituent les briques élémentaires de code et implémentent une ou plusieurs interfaces.
Une application peut faire appel à des fichiers de configuration pour regrouper les fonctionnalités des modules. Un fichier top-level configuration permet de faire le lien entre tous les composants.
Les interfaces sont des fichiers décrivant les commandes et évènements proposés par le composant qui les implémente. L’utilisation des mots clefs « Use » et « Provide » au début d’un composant permet de savoir respectivement si celui-ci fait appel à une fonction de l’interface ou redéfinit son code.
L’ordonnanceur TinyOS
Nous allons détailler le fonctionnement précis de l’ordonnanceur TinyOS qui est au cœur de la gestion des tâches et des évènements du système. Le choix d’un ordonnanceur déterminera le fonctionnement global du système et le dotera de propriétés précises telles que la capacité à fonctionner en temps réel.
L’ordonnanceur TinyOS c’est :
- 2 niveaux de priorité (bas pour les tâches, haut pour les évènements)
- 1 file d’attente FIFO (disposant d’une capacité de 7)
Par ailleurs, entre les tâches, un niveau de priorité est défini permettant de classer les tâches, tout en respectant la priorité des interruptions (ou évènements).
Lors de l’arrivée d’une nouvelle tâche, celle-ci sera placée dans la file d’attente en fonction de sa priorité (plus elle est grande, plus le placement est proche de la sortie).
Dans le cas où la file d’attente est pleine, la tâche dont la priorité est la plus faible est enlevée de la FIFO.
Package TinyOS
TinyOS est prévu pour fonctionner sur une multitude de plateformes, disponibles dès l’installation. En effet, TinyOS peut être installé à partir d’un environnement Windows (2000 et XP) ou bien GNU/Linux (Red Hat essentiellement, mais d’autres distributions sont également possibles).
Deux principales versions de TinyOS sont disponibles : la version stable (v. 1.1.0) et la version actuellement en tests (v. 1.1.15); la première présente moins de risques mais est nettement moins récente. En outre, afin d’installer la dernière version de test, il est nécessaire de procéder d’abord à l’installation de la version 1.1.0.
Procédure d’installation :
- Windows : un guide propose l’installation de tous les principaux outils nécessaires au bon fonctionnement du système, notamment Cygwin (couche d'émulation de l'API Linux) qui permet d’avoir une interface Unix sous Windows. Le JDK Java 1.4 de Sun est nécessaire afin d’effectuer la procédure d’installation.
- GNU/Linux : des packages RPM sont proposés au téléchargement, un guide explique la marche à suivre. Les distributions Linux ayant un autre gestionnaire de paquet peuvent utiliser un programme (comme « Alien ») pour installer les packages, ou compiler directement à partir des sources. Le JDK de IBM est nécessaire.
Par la suite, des packages supplémentaires peuvent être ajoutés en passant par le site SourceForge, qui met à disposition le code open source de TinyOS et d'un ensemble de programmes spécialisés.
Cibles possibles pour TinyOS
Il existe de nombreuses cibles possibles pour ce système d’exploitation embarqué. Malgré leurs différences, elles respectent toutes globalement la même architecture basée sur un noyau central autour duquel s’articule les différentes interfaces d’entrée-sortie, de communication et d’alimentation. Voici un schéma représentant cette architecture :
Mote, processeur, RAM et Flash : On appelle généralement Mote la carte physique utilisant TinyOS pour fonctionner. Celle-ci a pour cœur le bloc constitué du processeur et des mémoires RAM et Flash. Cet ensemble est à la base du calcul binaire et du stockage, à la fois temporaire pour les données et définitif pour le système TinyOS.
Radio et antenne : TinyOS est prévu pour mettre en place des réseaux sans fils, les équipements étudiés sont donc généralement équipés d’une radio ainsi que d’une antenne afin de se connecter à la couche physique que constitue les émissions hertziennes.
LED, interface, capteur : TinyOS est prévu pour mettre en place des réseaux de capteurs, on retrouve donc des équipements bardés de différents types de détecteurs et autres entrées.
Batterie : Comme tout dispositif embarqué, ceux utilisant TinyOS sont pourvus d’une alimentation autonome telle qu’une batterie.
Voici une liste rapide des équipements supportés initialement par TinyOS dans sa version « tinyos-1.1.11-3is ».
ATMega8
|
AVRMote
|
Mica
|
Mica2
|
Micadot
|
Mica128
|
Micaz
|
MSP430
|
Rene2
|
Telos
|
Telos2
|
PC
|
Au-delà de cette liste, il est possible d’implémenter tout type de plateforme embarquée physique en redéveloppant les bibliothèques nécessaires à la prise en compte des entrées sorties nécessaires.
Ainsi, le lien suivant propose le résultat d’une thèse mettant en œuvre TinyOS sur un dispositif Freescale MC13192-EVB sur un réseau ZigBee :
Sources et liens