IMA5 2018/2019 P13
Sommaire
Présentation générale
Description
La recherche de places de parking est une tâche fastidieuse, consommatrice de temps et polluante.
Objectifs
Pour remédier à ce problème, nous proposons de réaliser un ensemble composé :
- D'un capteur de détection de voiture :
- D'un système de transmission basé sur une carte "maison" (µC : CC430) déjà existante ;
- D'un système de stockage et de visualisation des places libres.
Préparation du projet
Cahier des charges
Choix techniques : matériel et logiciel
Liste des tâches à effectuer
Calendrier prévisionnel
Réalisation du Projet
Semaine du 17/09
En attendant un entretien avec les encadrants de projet pour mettre au point un cahier des charges précis, plusieurs recherches bibliographiques ont été effectuées.
Plusieurs solutions existent déjà pour effectuer la détection de voitures dans un parking, axées autours de trois méthodes :
- Détection avec un capteur par place
- Détection avec des capteurs en entrée et en sortie de parking
- Détection par caméra
Chaque solution présente des avantages et des inconvénients, qu'il faudra analyser afin de choisir la solution adaptée.
Le solution avec un capteur par place est précise et indique facilement et précisément l'occupation des places. Elle est de plus peu coûteuse en énergie par capteur, la détection ne devant pas être effectuée en permanence. En revanche cette méthode est coûteuse car nécessite un capteur par place, et implique une remontée d'informations complexe à mettre en place (sans fil ou filaire).
La solution avec des capteurs en entrée et en sortie est peu coûteuse et permet une remontée d'informations assez simple (peu de données à transmettre). En revanche elle n'est pas précise et indique seulement le nombre de voitures/places restantes dans le parking et non les places précises restantes. Elle est de plus coûteuse en énergie pour les capteurs, devant être actifs très souvent afin de ne pas manquer une voiture.
La solution par caméra est économe en matériel, une caméra pouvant être suffisante pour un parking entier, et permet de détecter précisément les places restantes. Elle n'est cependant pas pratique pour un parking souterrain, consomme beaucoup d'énergie par capteur et nécessite des capacités de traitement d'images hors de la portée d'un cc430. Elle peut cependant utiliser un serveur pour effectuer les calculs.
Des liens vers les études sont disponibles dans la partie Documentation
L'entretien avec les encadrant à de plus été préparer afin de pouvoir déterminer u cahier des charges précis. Les questions suivantes doivent être abordées :
- Objectifs précis du projet
- Localisation du parking, type de parking
- Durée de vie minimale des capteurs
- Type de détection voulu
- Budget
- Design du boiter du capteur
- Utilisation de RIOT imposée
- Quel type d'affichage
- Alimentation des capteurs
- Utilisation d'un serveur
- Utilisation du protocole RPL
Semaine du 24/09
Suite au rendez-vous du 21/09, les questions suivantes ont été écartées :
- Durée de vie minimale des capteurs
- Type de détection voulu
- Budget
- Design du boitier du capteur
- Quel type d'affichage
- Alimentation des capteurs
- Utilisation d'un serveur
En effets ces questions ne sont pas prioritaires et n'entreront dans l'équations que si le projet avance très vite.
- Objectifs précis du projet
L'objectif principal du projet est de déployer un réseau d'objets sans fils possédant des capacités de routage dynamique.
- Localisation du parking, type de parking
Le parking d'étude sera le parking de l'IRCICA, mais des essais en condition réel seront intéressant mais ne sont pas une priorité
- Utilisation du protocole RPL
Le routage dynamique devra préférentiellement être mis en place en respectant le protocole RPL
- Utilisation de RIOT imposée
RIOT OS n'est en aucun cas imposé, et l'utilisation d'un autre OS (Contiki a été évoqué) est parfaitement envisageable, voir même tenter une appproche sans OS.
Ayant déjà travaillé avec RIOTOS et le CC430, je sais qu'il peut y avoir des problème concernant la taille et l'occupation en RAM des OS. Ma première mission est donc de déterminer si le CC430 et ses 32ko de ROM et 4ko de RAM permettent l'utilisation des implémentations du protocoles RPL des différents OS de l'embarqués, ou si d'autres options plus simple (routage statique voir simple broadcast) sont à privilégier.
Semaine du 01/10
Durant cette semaine j'ai étudié l'impact en mémoire (ROM et RAM) des deux OS les plus adaptés aux premiers abord pour le projet : Contiki et RIOT. Les deux OS vantent une utilisation en ROM et RAM faible (environ 10ko de ROM et 2 ko de RAM), ce qui conviendrait parfaitement au besoin du projet. Malheureusement, ces tailles annoncées ne sont vrai que pour l'OS seul dans la plus grande majorité des cas, que ce soit pour RIOT ou Contiki. Le cc430 n'est pas supporté par Contiki, mais le Tmote Sky l'est, et est basé sur un msp430 de chez TI, comme le cc430. Utiliser le Tmote Sky afin d'établir la taille en ROM et RAM prise par les sources semble une option valide. Lors de la compilation des sources d'exemples RPL pour Contiki avec le Tmote Sky, sans modification au préalable de l'exemple, on option (grâce à la commande size sur linux) :
text | data | bss |
---|---|---|
43380 | 310 | 6958 |
soit 43380 octets de ROM utilisé et 310+6958=7268 octets de RAM utilisés, ce qui est bien supérieur à ce qui est disponible.
Du coté de RIOT, je savais que le programme d'exemple ne tenait pas dans le cc430, en effet il y a une surcharge de RAM de 2426 octets et de ROM de 32956 octets.
Dans les deux cas il est possible de réduire la taille de ce programme en retirant ce qui ne nous concerne pas.
De plus, afin d'être sur que le compilateur optimise la taille de l'exécutable, j'ai regardé la commande final des makefile de RIOT et Contiki en ajoutant
SHELL="sh -x"
à la fin de la commande make.
L'une des option de gcc pour optimisé en taille est l'option -0s, et cette option est bien présente pour les deux OS. Les gains en places ne peuvent donc pas être effectués grâce aux options du compilateur, mais doivent être effectués auprès du code source.
Les optimisations possibles chez Contiki se font en ajoutant un fichier project-conf.h dans le répertoire de l'exemple et d'y ajouter des #define pour restreindre certaines fonctionnalités.
Du coté de RIOT, il faut modifier le makefile et le code d'exemple.
Semaine du 08/10
Cette semaine a été consacrée à l'exploration des possibilités de réductions de taille des sources.
Contiki
Le programme d'exemple étant assez simple, il n'y à pas beaucoup de chose à modifier pour en réduire la taille. Il faut donc jouer sur les paramètres du fichier project-conf.h. Les paramètrs impactant la taille que nous pouvons modifier sont les suivants :
#define QUEUEBUF_CONF_NUM 4 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8 #define NETSTACK_MAX_ROUTE_ENTRIES 0 #define UIP_CONF_BUFFER_SIZE 100 #define SICSLOWPAN_CONF_FRAG 0 #define PROCESS_CONF_NO_PROCESS_NAMES 1 #define UIP_CONF_TCP 0
avec QUEUEBUF_CONF_NUM le nombre de message que doit pouvoir contenir le buffer de message. Plus cette varaible est faible, moins le programme prend de place en RAM mais plus il y a un risque d'engorgement. NBR_TABLE_CONF_MAX_NEIGHBORS correspond aux nombres de voisins que le nodes peut gérer. Plus cette valeur est importante, plus le réseau est flexible, mais plus cela prend de la place en RAM. NETSTACK_MAX_ROUTE_ENTRIES correspond au nombre de route sauvegarder dans la table rde routage. Plus cette valeur est importante, plus le réseau est réactif, mais comme nous sommes en mode "non storing mode", cette valeur doit être mise à zéro. UIP_CONF_BUFFER_SIZE correspond à la taille en octet du buffer de message IPv6. La taille minimal pour l'intéropérabilité est de 1280 octets, mais si le réseau n'a pas vocation à être mis en relation avec d'autre réseau IPv6, comme dans notre cas, la taille de ce buffer peut être réduit. Comme un paquet RPL à une taille maximale d'environ 32 octets et l'entête IPv6 d'envoron 40 octets, une taille de buffer de 100 est suffisante. SICSLOWPAN_CONF_FRAG correspond à l'utiliksation ou non du méchanisme de fragmentation des messages. Comme nos message seront normalement très court (moins de 10 octets), ce mechanisme ne devrait pas être utile et donc peut être retirer. Cela gagne de la place en RAM et en ROM. PROCESS_CONF_NO_PROCESS_NAMES correspond au mechanisme de nommage des processus créés dans Contiki. Comme il n'y aura pas beaucoup de processus et qu'ils ne seront pas lu par un humain lors du fonctionnement, désactiver ce mechanisme permet de gagner de l'espace en ROM principalement. UIP_CONF_TCP correspond à l'utilisation du mechanisme TCP. Comme le protocole UDP correspond à nos besoin, il n'est pas nécessaire d'intégrer les mechanismes de TCP.
De plus, dans le programme d'exemple, il y a de plus un mechanisme qu'il est possible de désactiver : les logs. En effet, Contiki propose un système avancé de log avec plusieurs niveaux permettant d'observer finement ce qu'il se passe durant le fonctionnement de l'OS. Passer de
#define LOG_LEVEL LOG_LEVEL_INFO
à
#define LOG_LEVEL LOG_LEVEL_NONE
permet aussi d'économiser un peu d'espace.
Avec ces modification, on arrive à
text | data | bss |
---|---|---|
41174 | 296 | 3492 |
On arrive donc en dessous des 4ko de RAM utilisée, mais il reste encore environ 10ko de ROM en trop.
RIOT
Comme je savais depuis mon projet IMA4 que RIOT occupait trop de place sur le cc430, j'ai pu rapidement tester des modifications afin de déterminer la taille prise en nmémoire. J'ai donc compilé le projet d'exemple gnrc_networking avec une carte proche du cc430 mais ayant plus de ROM et de RAM, le Tmote sky, ou telosB. Le resultat, sans modification préalable n'est pas encourageant : la compilation échoue car il y a un overflow de ROM de 14ko, sur les 48k disponible. La compilation n'indique pas d'overflow en RAM utilisé, mais le Tmote Sky ayant 10ko de RAM, ce n'est pas une chose à retenir car le cc430 n'en a que 4ko.
En modifiant le programme principale pour qu'il ne fasse rien, et en retirant dans le makefile l'inclusion de sources non nécessaire à notre projet (comme un shell), on arrive à un overflow de 7ko de ROM.
Avec ces même modifications, une compilation avec comme cible le cc430 indique un overflow en RAM de 1.6Ko de RAM.
Semaine du 15/10
J'ai décidé d'orienter principalement mes efforts vers l'OS Contiki, car je trouve que leurs sources sont plus facilement lisible que celles de RIOT, et leur programme d'exemple pour former un réseau RPL est plus facilement réutilisable, n'utilisant pas une couche shell contrairement à RIOT.
En étudiant les sources du Tmote Sky que j'utilise comme références, j'ai trouvé que le port était assez fourni, permettant de gérer beaucoup d'aspect du microcontroleur, avec entre autre des modules pour les GPIO, l'UART, le SPI, l'I2C et les capteurs de la carte. Le Tmote Sky possède aussi un module d'indentification unique, le ds2411. Ce module permet d'obtenir de manière matériel un identifiant unique pour chaque node. Pour le début du projet, il n'y a pas besoin de ces modules, donc il est possible de les retirer du makefile et des différentes sources les utilisant.
Ce faisant, on arrive à :
text | data | bss |
---|---|---|
35762 | 210 | 3296 |
On arrive proche des 32ko de ROM du cc430. Afin d'avoir de la marge, j'estime à 2ko de ROM nécessaire pour utiliser les sources du cc430 disponible, donc je pense qu'il faut réduire l'utilisation en ROM a 30ko.
En retirant la gestion propre à Contiki des LED et le calcul du chiffrement AES de manière logiciel, on descend à 35370 octets de ROM.
Les paramètres du fichiers projet-conf.h que l'on peut encore modifier sont :
QUEUEBUF_CONF_NUM NBR_TABLE_CONF_MAX_NEIGHBORS
Malheureusement, ces variables n'ont qu'un impact fort sur la RAM, et leur impact est très faible sur la ROM.
A partir de ce point je n'ai pas d'autre pistes pour réduire de manière significative l'utilisation en ROM. En accord avec mes encadrants, il a été décidé que si l'on veut utiliser les cc430 disponibles, il va falloir se passer d'OS et extraire les parties de la couches réseau de Contiki ou de RIOT dont nous avons besoin (principalement MAC, UDP et RPL).
Contiki met en place des méchanismes très pratique afin d'analyser la mémoire utilisé par les sources graces aux commandes (expliquée ici https://github.com/contiki-ng/contiki-ng/wiki/Tutorial:-RAM-and-ROM-usage) :
make <nom-du-projet>.ramprof
pour observer la taille de chaque variable en RAM. Cette commande effectue en fait la commande
msp430-nm -S -td --size-sort <nom-du-projet>.<cible> | grep -i " [abdrw] " | cut -d' ' -f2,4
(ici
msp430-nm -S -td --size-sort udp-client.sky | grep -i " [abdrw] " | cut -d' ' -f2,4
)
et
make <nom-du-projet>.flashprof
pour observer la taille de chaque fonction en ROM. Cette commande exécute en fait la commande :
msp430-nm -S -td --size-sort <nom-du-projet>.<cible> | grep -i " [t] " | cut -d' ' -f2,4
(ici
msp430-nm -S -td --size-sort udp-client.sky | grep -i " [t] " | cut -d' ' -f2,4
)
Un extrait du resultat de la seconde commande donne
{...} 00000384 nbr_table_add_lladdr 00000384 uip_icmp6_error_output 00000396 frame802154_parse 00000432 rpl_process_dio 00000476 transmit_from_queue 00000558 rpl_icmp6_dio_output 00000612 ns_input 00000680 dio_input 00000808 rpl_ext_header_update 00001196 uip_process 00001540 input 00001810 output
On remarque que les deux plus grosses fonctions sont "input" et "output".
On peut déterminer leur origine avec les commandes suivantes :
$ nm -oStd obj_sky/*.o | grep " output$" obj_sky/sicslowpan.o:00000000 00001810 t output $ nm -oStd obj_sky/*.o | grep " input$" obj_sky/sicslowpan.o:00000000 00001540 t input
On remarque que ces fonctions proviennent du module "sicslowpan" (6LoWPAN). 6LoWPAN (IPv6 over Low-Power Wireless Personal Area Networks) définit des méchanismes d'encapsulation et de compression des headers IPv6 pour objets contraints, et donc on ne peut se séparer de ce module. 6LoWPAN sert de plus de base pour le protocole de routage RPL, et est donc indispensable.
Afin d'être sur que les sources de Contiki en rapport avec la couche MAC, avec 6LoWPAN et RPL (entre autres) pouvaient effectivement tenir dans les 32ko du cc430, j'ai décidé d'estimer la taille totale de ces sources.
Pour ce faire, j'ai d'abord conçu des scripts se basant sur les commandes précedemment citées. J'ai enregistré le résultat de la commande
make udp-client.flashprof
dans un fichier, puis ajouté à chaque ligne correspondant à une fonction la localisation de cete fonction grâce au script suivant :
#!/bin/bash obj=~/Documents/PFE/baseSource/Contiki-NG/contiki-ng/examples/rpl-udp/obj_sky/*.o file=~/Documents/PFE/Redaction/outputFlash.txt file2=~/Documents/PFE/Redaction/funcLocations.txt rm $file2 touch $file2 cptline=0 while IFS= read -r cmd; do if [ $cptline -ge 2 ]; then nom=$(echo $cmd |cut -d' ' -f2) line= taille=$(echo $cmd |cut -d' ' -f1) location=$(nm -oStd $obj | grep " $nom$") location=$(echo $location |cut -d' ' -f1) line=$taille' '$nom$'\t'$'\t'$location echo ' '$taille' '$nom$'\t'$'\t'$location >> $file2 else cptline=$(($cptline + 1)) fi done < "$file"
Cela donne une résultat du genre :
00000002 drop_route /home/nenth/Documents/PFE/baseSource/Contiki-NG/contiki-ng/examples/rpl-udp/obj_sky/rpl.o:00000000 00000002 energest_flush /home/nenth/Documents/PFE/baseSource/Contiki-NG/contiki-ng/examples/rpl-udp/obj_sky/clock.o: {...}
J'ai ensuite ajouté à chaque ligne un champs au debut de celle ci contenant 1 ou 0 en fonction de la localisation de la fonction, 1 si la fonction semble être dans un module réseau, 0 sinon.
Ensuite j'ai exécuté le script suivant qui en, fonction du premier champs à 1 ou 0 calcul la taille totale de toutes les fonctions :
#!/bin/bash file=~/Documents/PFE/Redaction/funcLocationsAppend.txt total=0 while IFS= read -r cmd; do isAddable=$(echo $cmd |cut -d' ' -f1) if [ $isAddable -eq 1 ]; then total=$(($total + $(echo $cmd |cut -d' ' -f2 | sed -e 's/^0*//'))) fi echo $total done < "$file"
Ici le sed permet de transformer le champs de type
00000384
en
384
car pour le shell un nombre commençant par 0 est considéré comme en base 8, et donc les chiffres 8 et 9 font planter l'addition.
Le résultat de ce script donne une taille totale de 28564 octets. A première vue, il reste environ 3k pour le reste du projet, ce qui est relativement peu, mais cela doit être possible.