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. Nous allons détailler ceux-ci dans le tableau suivant :
Les tâches sont utilisées pour effectuer la plupart des blocs d’instruction d’une application. A l’appel d’une tache, 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 tache 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 taches 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 tache 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 taches.
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.