IMA4 2017/2018 P10 : Différence entre versions
m (→Semaine 9) |
m (→Semaine 9) |
||
Ligne 263 : | Ligne 263 : | ||
[[Fichier:Rpl dodag.png | center |500px | thumb | DODAG RPL]] | [[Fichier:Rpl dodag.png | center |500px | thumb | DODAG RPL]] | ||
+ | |||
+ | L'objectif du protocole RPL est d'optimiser la transmission d'information dans des réseaux sans fils. Chaque noeud essaye de transmettre ses données au noeud racine (sur l'image rank 0) en utilisant le chemin le plus court et le plus sur possible, d'où la création de l'arbre DODAG. La création de l'arbre est effectuée grâce a des messages ICMPv6 (message de type DIO, DIS, DAO). | ||
=Documents Rendus= | =Documents Rendus= |
Version du 12 mai 2018 à 11:02
Sommaire
Présentation générale
Description
Le but de ce projet est d’effectuer le portage du système d’exploitation RIOT-OS pour le microcontrôleur CC430 dans l’optique IoT. L’IoT, ou en français « Internet des Objets », est en quelque sorte l’extension d’Internet aux objets du quotidien et aux personne. Avec l’IoT, il ne s’agit plus de connecté via Internet seulement des serveurs et des ordinateurs, mais aussi des montres, des caméra, des feux de signalisation ou des capteurs en tout genre. RIOT-OS est un système d’exploitation destiné aux objets connectés, avec comme préoccupation principale une consommation minimale en mémoire et en puissance. C’est un OS OpenSource communautaire dont le site est le suivant : https://riot-os.org/. RIOT-OS a une organisation en module, avec des modules indépendants du hardware utilisé se reposant sur des modules dépendant du hardware utilisé, c’est-à-dire qu’il n’est pas nécessaire de réécrire tout l’OS pour l’adapter au microcontrôleur voulu, seulement les modules dépendant du hardware. Il est possible d’émuler le fonctionnement d’une application utilisant RIOT-OS sur un ordinateur, permettant de tester l’application développer sans les inconvénients du hardware. Le principal intérêt de cette fonctionnalité est de vérifier la viabilité d’une application avant de commencer le portage sur la cible voulue.
Le CC430 est une famille de microcontrôleur de la marque Texas Instrument, intégrant un microprocesseur MSP430 et un module radio CC1101. La famille MSP430 est une famille de microcontrôleur très utilisé dans le domaine professionnel. Le module radio CC1101 est un module radio conçu pour des applications embarquées à basse consommation, aussi de la marque Texas Instrument.
Objectifs
Les objectifs de ce projets sont :
- Rendre compatible RIOT-OS avec le CC430
- Permettre la communication par radio entre deux CC430 ayant RIOT-OS d'installé
Analyse du projet
Positionnement par rapport à l'existant
Il existe de nombreux OS pour l’embarqué et les systèmes connectés (Contiki, FreeRTOS, Linux, Windows For IOT…). Chaque Système d’Exploitation possède ses intérêts et ses défauts. Notre objectif est l’IoT, donc les objets connectés et les réseaux de capteurs. De plus, RIOT-OS est open source, nous allons donc comparer notre projet face à d’autres OS open source visant les objets connectés qui supportent les MSP430, donc proche du CC430.
Analyse du premier concurrent : FreeRTOS
FreeRTOS est l’un des OS les plus populaire du monde de l’embarqué. Très simple à prendre en main avec très peu de fichiers .C, il est disponible pour de très nombreuses plateforme. Les sources de cet OS sont disponible sur leur site https://www.freertos.org/. La plus grande force de FreeRTOS est sa simplicité d’utilisation, en effet, il n’y a qu’un seul fichier source à modifier pour rendre l’OS compatible avec n’importe quelle plateforme supportée. En revanche, FreeRTOS occupe « beaucoup » d’espace en mémoire, avec en moyenne 4kB d’utilisation de RAM et 9kB d’utilisation de ROM, comparé à respectivement 1.5kB de Ram et 5kB de ROM pour RIOT. De plus, dans une optique IoT, FreeRTOS ne supporte que les protocoles TCP, UDP et Ethernet pour la communication par Internet, tandis que RIOT, bien que ne supportant pas Ethernet, supporte TCP, UDP et surtout CoAP, un protocole de transmission d’information via Web optimisé pour les réseaux contraints sans fil. Enfin, il n’est possible que de développer en C sur FreeRTOS, alors que RIOT laisse le choix entre C et C++, permettant l’utilisation de plus bibliothèques.
Analyse du second concurrent : Contiki
Contiki est un OS ayant pour cible des petits microcontrôleurs à faibles cout et faible consommation pour l’IoT. Le site de Contiki est le suivant : http://www.contiki-os.org/. Contiki a été pensé pour les réseaux de capteurs et implémente plusieurs standards et protocoles de communications sans fils et Internet, tel que IPv4 et IPv6, 6loWPAN, RPL ou encore CoAP. Les principales forces de Contiki sont l’importance de la gestion de l’énergie des microcontrôleurs sur lequel il est porté et son émulateur Cooja permettant de simuler des réseaux Contiki et vérifier le bon fonctionnement de l’application développée. En revanche, tout comme FreeRTOS, Contiki est gourmand en mémoire RAM et ROM, nécessitant environ 2kB de RAM et 30kB de ROM. De plus, contrairement à RIOT-OS, les capacités temps réel de Contiki sont limitées, son scheduler est basé sur un algorithme coopératif et non préemptif comme c’est le cas pour RIOT-OS.
Scénario d'usage du produit ou du concept envisagé
Carrie F. est développeuse de systèmes embarqués et doit mettre en place réseau de capteurs afin de mesurer la pollution d’une zone sensible, une usine, une ville, une zone contaminée tel que Tchernobyl, dont les données doivent être transmises à un serveur de manière sécurisé. Elle n'a pas beaucoup de temps et doit choisir un produit lui permettant de réaliser son projet dans le temps qui lui est attribué. Elle fait le choix du CC430 qui est un microcontrôleur possédant nativement des capacités de communications sans fil. Afin de mettre en place rapidement son réseau de capteur, elle a besoin d'un OS pret à l'emploi. La combinaison RIOT-OS-CC430 permettrait de répondre à toutes les problématiques. En effet, à la fois le MSP430 intégré dans le CC430 et RIOT-OS offrent des solutions afin de sécuriser à la fois les transmissions ET le capteur, permettent une communication sans fils via Internet, et RIOT-OS étant axé sur l’économie d’énergie, permet de faire fonctionner plus longtemps les capteurs sur batterie, permettant de soit palier à un défaut d’alimentation, voir de ne dépendre que du soleil afin de s’alimenter.
Réponse à la question difficile
La question difficile était : "Sur quel microcontrôleur de la famille des MSP430 le port doit-il être fait?". Après discussion, il s'est avéré que le sujet réel était "Portage de RIOT-OS sur CC430 pour IOT" et non "Portage de RIOT-OS sur MSP430 pour IOT" , et donc le sujet du projet répondait à cette question : le port doit être effectué sur le CC430, un microcontrôleur de la famille des MSP430 ayant un CC1101. La réponse à la question difficile est donc triviale : le microcontrôleur doit être le CC430.
Préparation du projet
Cahier des charges
Choix techniques : matériel et logiciel
La référence exacte du CC430 utilisé est : CC430F5137IRGZT (datasheet http://www.ti.com/lit/ds/symlink/cc430f5137.pdf , http://www.ti.com/lit/ug/slau259e/slau259e.pdf)
Les programmes seront écrit en C et compilés avec le compilateur GCC pour msp430 (http://www.ti.com/tool/msp430-gcc-opensource).
Le CC430 sera flashé grâce à un launchpad de la marque TI : le MSP-EXP430G2 (http://www.ti.com/tool/MSP-EXP430G2).
Afin de vérifier que les CC430 émettent correctement les messages radios, un autre microcontrôleur sera utilisé comme agent de contrôle : le MSP430-CCRF (https://www.olimex.com/Products/MSP430/Starter/MSP430-CCRF/)
Liste des tâches à effectuer
Afin de réaliser le projet, il faut :
- Mettre en place la chaîne de compilation (ggc pour msp430, comprendre comment utiliser le flasheur..)
- Analyser le fonctionnement de RIOT-OS
- Charger la version de RIOT-OS pour MSP430 sur le CC430 et déterminer quelles parties doivent être faites/refaites
Calendrier prévisionnel
Réalisation du Projet
Feuille d'heures
Tâche | Prélude | Heures S1 | Heures S2 | Heures S3 | Heures S4 | Heures S5 | Heures S6 | Heures S7 | Heures S8 | Heures S9 | Heures S10 | Total |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Analyse du projet | 0 | |||||||||||
Mise en place de la chaine de compilation | 8 | 1 | ||||||||||
Analyse du fonctionnement de RIOT-OS | 6 | 2 | ||||||||||
Portage du module radio | 5 | 7 | 7 | 6 + 4 | 4 |
Prologue
Semaine 1
La première semaine du projet a été consacrée à la mise en placede la chaine de compilation nécessaire pour complier le code pour le CC430 et et le falsher sur la carte.
Le compilateur msp430-gcc a été installé et l'outil mspdebug a été installé pour pouvoir flasher les cartes.
Les connexions physiques entre la carte habritant le cc430 et le launchpad msp-exp430g2 ont été repérées.
Des câbles avec une extremité femelle ont été soudés à une carte afin de permettre une communication (et donc une programmation) facile entre cette carte et le launchpad.
Semaine 2
Beaucoup de lecture et de recherche sur le fonctionnement de RIOT-OS ont été effectuées
Semaine 3
J'ai récupéré des sources d'un ancien projet IMA5 (https://projets-ima.plil.fr/mediawiki/index.php/P11_Spectateur_augment%C3%A9) dans lequel existait des codes fonctionnels et des bibliothèques fonctionnelles pour utiliser le module radio du CC430. Je compte utiliser ces sources comme bases à intégrer a RIOTOS Afin de porter intégralement RIOTOS sur le CC430, il faut ajouter aux source de RIOTOS les sources permettant d'utiliser les différents modules disponibles sur le CC430. Parmi les modules disponibles sur le cc430, il ne faut porter que les modules suivants : le module CRC16, le module radio (le cc1101) et le module de cryptage AES. Après discussion avec les encadrants de projets, il n'est nécessaire pour l'instant que de porter le module radio
RIOT-OS fonctionne grâce à une série de makefile en cascade et à une arborescence précise, chaque fichier et makefile devant se trouver au bon endroit et modifiés de manière cohérente par rapport a l'architecture de compilation de RIOTOS.
Les différents microcontrôleurs supportés par RIOTOS sont rangés dans le dossier */RIOT/cpu et les différentes board sont rangés dans le dossier */RIOT/boards. Afin de porter RIOT OS pour le cc430, il faut donc ajouter les sources du module radio au dossier des sources du CC430, soit dans le dossier */RIOT/cpu/cc430. Il faut aussi créer un répertoire propre à la carte électronique fourni par les encadrants, j'ai donc crée dans l'architecture de RIOT un répertoire */RIOT/boards/CC430BV. En me basant sur l'architecture de la board msb430, une board utilisant un msp430 donc très proche de celle dont je dispose, j'ai recréé l'architecture de répertoire et de makefile pour cette board.
J'ai ensuite ajouté dans les sources du cc430 les bibliothèques pour le module radio en suivant l'architecture des différents répertoires, c'est à dire :
- j'ai ajouté dans le dossier /RIOT/cpu/cc430/include/ le fichier RF1A.h, correspondant au fichier header pour faire fonctionner le module radio
- j'ai ajouté dans le dossier /RIOT/cpu/cc430/ le fichier RF1A.c, correspondant au fichier source pour faire fonctionner le module radio
J'ai de plus ajouté des fichiers utiles pour un projet que je compte réutilisé dans les sources du CC430BV, principalement des sources pour la PMM et la commande des LED de la board.
J'ai ensuite crée un dossier pour mes projets de test au sein de l'arborescence de RIOT afin que les makefile retrouvent facilement les chemins des sources de l'OS.
J'ai rencontré beaucoup de problème liés à la compilation, la plupart de mes nouvelles sources n'étant pas reconnues. Afin de résoudre le problème, j'ai commencé par tenter de compiler un des mini projet d'exemples, en l’occurrence un simple projet "hello world", trouvable dans le répertoire */RIOT/examples/hello-world, et je me suis rendu compte que ce projet, compilant pour d'autres board, ne compilait pas pour ma nouvelle board cc430BV. EN suivant les messages d'erreurs j'ai pu résoudre ce problème et l'exemple compile sans erreur. En revanche, je n'arrive toujours pas a compiler mon projet de test avec mes nouvelles sources.
Semaine 4
Cette semaine a été consacrée à résoudre les problème de compilation liés au portage du module radio. Le principale problème rencontré est que à la compilation, certains fichiers sources nouvellement ajoutés ne sont pas reconnus, et donc certaines fonctions et certaines variables n’existent pas. Ce problème peut être facilement résolu en faisant un #include "monfichier.h" et en l'ajoutant au répertoire courant du projet, mais cela ne présente pas un grand intérêt dans le cadre de l'utilisation de RIOTOS et va a l'encontre de l’intérêt du portage.
Le problème est que pour que le port soit bien fait, n'importe quel projet puisse utiliser les sources pour la communication radio, et ce pour n'importe board existante utilisant le cc430, le module radio étant inclut dans ce microcontrôleur. Les sources doivent donc être ajouté au dossier même du cc430, et je n'ai pas trouvé de solution afin que ces fichiers soient bien inclus lors de la compilation.
J'ai modifié les makefiles que j'avais crée car il se trouvait qu'il y avait des erreurs, résolvant certains problèmes, mais le plus gros persiste, mes nouvelles sources ne sont pas prises en compte.
Après une remarque de M. Vantroys, j'ai décidé de prendre exemple sur l'architecture des répertoires et des makefiles de la board chronos, board utilisant aussi un cc430. Malgré cela, j'ai toujours les meme problèmes de compilation. En observant le cheminement du makefile grace à l'option -n, je remarque bien pourtant que mes fichiers, principalement mes fichiers sources RF1A.h et RF1A.c sont bien pris en compte et normalement bien ajoutés à la compilation grâce à l'option -I de gcc, mais certains #define sont inaccessible.
Semaine 5
En fouillant dans les exemples fournis par RIOTOS et dans la documentation de l'OS, j'ai trouvé la bonne méthode à utiliser pour porter l'OS sur le cc30.
Contrairement à ce que je pensais, il faut bien utiliser les #include "header.h"
pour inclure les sources nécessaires, avec header.h dans RIOT/cpu/cc430/includes et sources.c dans RIOT/cpu/cc430. J'ai donc déplacer mes fichiers RF1A.c et RF1A.h dans les bons répertoires (RIOT/cpu/cc430 et RIOT/cpu/cc430/includes).
Dans le dossier correspondant à la board doit être inclut tous les fichiers sources relevant des drivers nécessaires au fonctionnements des périphériques n'étant pas nativement sur le cpu. Les sources de la gestion de led doivent donc y être placés.
L'architecture doit donc être la suivante (sans tenir compte des dossiers et des fichiers déjà existant et ne devant pas être déplacés) :
RIOT/ cpu/ cc430/ RF1A.c includes/ RF1A.h board/ cc430BV/ drivers/ Makefile led_commands.c include/ led_command.h
Une fois les fichiers au bon endroit et en utilisant les bon #include
, il suffit de compiler de se placer dans le répertoire du projet et d'utiliser le makefile avec la commande suivante :
make BOARD=cc430BV
et le projet compile sans erreur.
Afin de tester l'intégration de l'OS, j'ai décidé de reprendre les sources d'un code simple provenant du même projet que les sources déjà utilisés précédemment permettant l'envoi d'un message par une board et allumant une LED à chaque envoi, et permettant à une autre board de recevoir un message et allumant une LED à chaque réception. J'ai testé ces sources en les uploadant simplement sans modification sur les board que j'ai et elles fonctionnent comme escomptées.
J'ai ensuite intégrés ces quelques lignes de codes dans un programme créant un thread sur RIOTOS afin de tester les capacités d'émission et de réception.
Lors de ces tests, il s'est avéré que les LED ne clignotent pas comme dans les sources de base. En effet, afin de contrôler les LED, il faut utiliser un timer, et il s'avère que le timer utiliser pour la gestion des LED est le même que celui utilisé par RIOT pour son ordonnanceur. Les LED ne reste allumé que très peu de temps comparer à la version sans RIOT, mais à première vue, cela ne dérange pas le bon fonctionnement de RIOT. Ce problème n'est pas très important pour le moment, car il suffit de changer la gestion des LED, et cela ne rentre de tout façon pas en compte dans le port de RIOT pour le cc430, ce problème ne concernant que notre board.
En revanche, sachant que les codes sources fonctionnaient, j'ai testé la reception et l'émission de la manière suivante :
- : émission sans RIOT et réception avec RIOT
- : émission avec RIOT et réception sans RIOT
- : émission et réception avec RIOT
Les résultats de ces tests sont :
Pour le test 1, il y a bien un allumage de LED à chaque réception d'un message, et si on coupe la source d'émission, il n'y a plus d'allumage à la réception, la réception à l'air de fonctionner
Pour le test 2, des problèmes sont apparus. Le récepteur ne captait qu'un seul message, et l'émetteur allumait sa LED mais ne l'éteignait jamais. Il s’avère que dans le code utilisé pour faire fonctionner le module radio, la fin de chaque transmission déclenchait une interruption. Je n'ai pas encore regardé comment RIOT gérait les interruptions, mais il est possible que le problème vienne de là, car le code que j'ai récupéré ne traitait pas l'interruption et laissait donc le code de base. Les prochaines séances vont être consacrées à la résolution de ce problème. Une fois ce problème surpassé, il faudra refactorer toutes les sources afin qu'elles correspondent aux normes de RIOT et d'écrire une API afin de gérer proprement les interruptions généré par la liaison radio.
Pour le moment, j'ai désactivé l'interruption et, au moins sur des messages très court, les board communiquent par radio avec des threads de RIOT.
Semaine 6
L'objectif de cette semaine était de faire fonctionner RIOT en parallèle des interruptions générés par le module radio.
Les vecteurs d'interruptions sont accessible et modifiable par la directive "pragma". Je n'ai pas encore très bien compris le fonctionnement des pragma, car spécifique à chaque compilateur, mais le code suivant permet de réveiller un thread suite à la réception d'un message par le module radio si ce dernier à été paramétré correctement (c'est à dire en mode réception RX avec la bonne interruption d'autorisée) :
#pragma vector=CC1101_VECTOR __attribute__((interrupt(CC1101_VECTOR))) void CC1101_ISR(void) { if(RF1AIV==RF1AIV_RFIFG4){ thread_wakeup(pid) } }
Pour le moment j'ai décidé de ne pas repérer la fin d'une transmission par un interruption, le code que j'ai actuellement fonctionne et je ferais des améliorations une fois que tout le reste fonctionnera.
J'ai ensuite refactoré tout le code afin de respecter les conventions de RIOT, c'est-à-dire respecter en particulier les consignes suivantes :
while(REGISTRE == VALUE); n'est pas correct while(REGISTRE == VALUE) {} est correct.
void maFonction() {...} n'est pas correct void rf1a_ma_fonction(void) {...} est correct
Indentation de 4 espaces, et non une tabulation ou 2 espaces
Les consignes complètes se trouvent à ce lien : https://github.com/RIOT-OS/RIOT/wiki/Coding-conventions
Durant la semaine de repos, j'ai commencé à tester mon codes afin de vérifier que tout fonctionnait bien, et je me suis rendu compte d'un problème très génant : je peux transmettre autant de paquets de deux octets que je le souhaites, mais je ne peux transmettre que 2 à 3 paquets de plus de 2 octets. Je ne sais pas pourquoi ce comportement est présent, je n'ai pas encore trouvé le problème.
Semaine 7
J'ai continué de cherché la raison du bug empéchant de transmettre des paquets de plus de 2 octets, et en me documentant sur le fonctionnement exact du cc430, j'ai découvert que le code que j'ai récupéré d'un ancien projet IMA provenait en fait de codes d'exemple fourni par TI sous le couvert d'une license TI assez restrictive. Je ne sais donc pas si le code que j'utilise peux être intégré à RIOT OS. Le code de TI peut être trouvé à cette adresse www.ti.com/lit/sw/slac525b/slac525b.zip .
De plus , en comparant ma version du code et la verison de TI, je n'ai pas trouvé de différences sur les parties qui me concernait , et ce code est sencé fonctionner pour transmettre des paquet de n'importe quelle taille.
Semaine 8
J'ai trouvé la source du problème des transmissions longues impossibles, et il s'agit en fait d'un problème dans mon code de test. En effet, j'utilisais le mode "taille de paquet fixe" du cc430, c'est à dire que la taille du paquet transmit devait être le premier octet transmit, et dans mes tests de paquets de tailles plus longue que 2 octets, j'oubliais de mettre à jour ce champ. En corrigeant ce problème dans mon programme de test, les réceptions se produisent correctement, dans la limite du buffer de 64 octets autorisés par le cc430.
Une fois ce bug résolu, j'ai entamé l'étape de nettoyage du code pour le rendre parfaitement compatible avec RIOT OS, et respectant les conventions imposées par RIOT. J'ai donc utilisé un "code beautifier" nommé uncrustify afin de rectifier la majorité des "erreurs". J'ai de plus du retirer la plupart des caractères "blanc" (ou whitespace) en fin de ligne, afin d'éviter les erreurs de compilation Murdok. Malgré quelques recherches, je n'ai pas trouvé à quoi correspondait cette erreur.
Après consultations de mes encadrants de projets, il a été décidé que le code a ajouter à RIOT est suffisamment simple, et suffisamment différent du code source de Ti pour ne pas se soucier des droits d'auteur.
Afin de montrer que le portage de la radio fonctionne bien, je vais utiliser le protocole RPL entre 3 noeuds, en utilisant la bibliothèque créée pour RIOT. Je vais me baser sur les projets IMA https://projets-ima.plil.fr/mediawiki/index.php/P15_R%C3%A9seau_de_capteurs_temps_r%C3%A9el et https://projets-ima.plil.fr/mediawiki/index.php/P7_R%C3%A9gulation_temps_r%C3%A9el_sur_r%C3%A9seau_sans_fil pour comprendre le fonctionnement de RPL et comment RIOT l'a implémenté.
Semaine 9
Le Pull Request a été effectué, et après plusieurs corrections, le code a passé les tests automatiques de CI. Il ne reste plus qu'à attendre les retours des responsables de RIOT OS.
En parallèle, j'a commencé à me renseigner sur le protocole RPL. Le protocole RPL est un protocole de routage et a été conçu principalement pour les objets connectés afin de s'adapter au LLN (Low-power and Lossy Networks). La description en détail de ce protocole peut être trouvé à la rfc6550 (https://tools.ietf.org/html/rfc6550). Le principe du RPL est la construction d'un arbre DODAG (Destination-Oriented Directed Acyclic Graph) avec au moins un nœud racine.
L'objectif du protocole RPL est d'optimiser la transmission d'information dans des réseaux sans fils. Chaque noeud essaye de transmettre ses données au noeud racine (sur l'image rank 0) en utilisant le chemin le plus court et le plus sur possible, d'où la création de l'arbre DODAG. La création de l'arbre est effectuée grâce a des messages ICMPv6 (message de type DIO, DIS, DAO).