Outils pour utilisateurs

Outils du site


tppic

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
tppic [2019/02/14 09:01]
bvandepo
tppic [2019/04/06 14:08] (Version actuelle)
bvandepo [Exercice 3: Réception de commandes des LED]
Ligne 3: Ligne 3:
  
 Se logger sur le pc superviseur en tant que: ge2i pass:ge2i Se logger sur le pc superviseur en tant que: ge2i pass:ge2i
 +
 +Utiliser le genre masculin pour socket car c'est un anglicisme: https://​fr.wiktionary.org/​wiki/​socket
  
 Les binaires pour les pc superviseur sont stockés en local sur les machines dans /​usr/​local/​binaries/​lanceEN.py pour ER2EN   et lance.py ​ pour ER2AU Les binaires pour les pc superviseur sont stockés en local sur les machines dans /​usr/​local/​binaries/​lanceEN.py pour ER2EN   et lance.py ​ pour ER2AU
Ligne 18: Ligne 20:
   sudo ip neigh flush dev eth0   sudo ip neigh flush dev eth0
  
 +
 +pour filtrer les requetes et réponses ARP avec Wireshark à partir de l'​adresse MAC:
 +  ((eth.dst == 00:​04:​a3:​10:​dc:​84) || (eth.src == 00:​04:​a3:​10:​dc:​84) ) && arp
 </​ifauth>​ </​ifauth>​
  
Ligne 41: Ligne 46:
 copier coller dans une console: copier coller dans une console:
 </​color>​ </​color>​
-  rsync -av --delete ~/​TCPIP_Demo_App_etudiant /mnt/etu/s4+  rsync -av --delete ~/​TCPIP_Demo_App_etudiant /mnt/etu/
  
 <color red> <color red>
-et completer ​la ligne en appuyant 3 fois sur la touche Tabulation, puis entrée.+et compléter ​la ligne en appuyant 3 fois sur la touche Tabulation, puis entrée.
  
  
 </​color>​ </​color>​
 +
 +------------------------------------------------------------
 +
 ===== TP Bus de communication : Initiation au micro-contrôleur PIC32 et utilisation d'un réseau local pour l'​échange de données via  sockets UDP ===== ===== TP Bus de communication : Initiation au micro-contrôleur PIC32 et utilisation d'un réseau local pour l'​échange de données via  sockets UDP =====
    
Ligne 76: Ligne 84:
   passerelle par défaut : 172.16.0.1   passerelle par défaut : 172.16.0.1
   plage @IP statiques (pour les cartes PIC) : 172.16.0.2 - 33   plage @IP statiques (pour les cartes PIC) : 172.16.0.2 - 33
-  plage @IP DHCP avec baux statiques : 172.16.0.34 - 62+  plage @IP DHCP avec baux statiques ​(pour les PC) : 172.16.0.34 - 62
   IP du PC superviseur : 172.16.0.34   IP du PC superviseur : 172.16.0.34
 </​ifauth>​ </​ifauth>​
Ligne 87: Ligne 95:
   passerelle par défaut : 172.16.6.1   passerelle par défaut : 172.16.6.1
   plage @IP statiques (pour les cartes PIC) : 172.16.6.2 - 33   plage @IP statiques (pour les cartes PIC) : 172.16.6.2 - 33
-  plage @IP DHCP avec baux statiques : 172.16.6.34 - 62+  plage @IP DHCP avec baux statiques ​(pour les PC) : 172.16.6.34 - 62
   IP du PC superviseur : 172.16.6.34  ​   IP du PC superviseur : 172.16.6.34  ​
 </​ifauth>​ </​ifauth>​
  
-Dans la salle, un PC va faire office de superviseur,​ dans le sens où il va permettre de centraliser les communications ​issues des différentes cartes PIC.+Dans la salle, un PC va faire office de superviseur,​ dans le sens où il va permettre de centraliser les informations ​issues des différentes cartes PIC et de les piloter à distance.
  
  
Ligne 108: Ligne 116:
  
 Le schéma suivant récapitule l'​ensemble des matériels et logiciels que nous allons utiliser dans cette série de TP. Les différents éléments seront expliqués au fur et à mesure. <color red>A chaque étape, vous devez être capable d'​identifier les portions utilisées et leur rôle. Vous devrez remplir les cases jaunes sur la feuille distribuée lors du TP.</​color>​ Le schéma suivant récapitule l'​ensemble des matériels et logiciels que nous allons utiliser dans cette série de TP. Les différents éléments seront expliqués au fur et à mesure. <color red>A chaque étape, vous devez être capable d'​identifier les portions utilisées et leur rôle. Vous devrez remplir les cases jaunes sur la feuille distribuée lors du TP.</​color>​
-<ifauth @prof> 
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​schemareseauPIC-2018-au-en.png}} 
-</​ifauth>​ 
  
 {{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​schemareseauPIC-2018-au-en-horizontal.png}} {{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​schemareseauPIC-2018-au-en-horizontal.png}}
Ligne 138: Ligne 143:
  
 <ifauth @en> <ifauth @en>
-  - En émission ​depuis ​l'IP 172.16.0.34 port UDP 30002+10*x vers l'​IP ​de la carte PIC 172.16.0.x port 30002+10*x +  - En émission: Superviseur avec l'IP 172.16.0.34 ​ et le port UDP 30002+10*x vers carte PIC avec l'​IP ​  ​172.16.0.x ​ et le port 30002+10*x 
-  - En réception ​depuis ​l'​IP ​de la carte PIC PIC 172.16.0.x port UDP 30001+10*x vers l'IP 172.16.0.34 port  30001+10*x+  - En réception: Carte PIC avec l'IP 172.16.0.x ​ et le port UDP 30001+10*x vers Superviseur avec l'IP 172.16.0.34 ​et le port  30001+10*x
 Par exemple, l'​application 3 communiquant avec la carte PIC 3 émet ses informations vers l'IP PIC 172.16.0.3 port 30032 et les reçoit sur le port 30031. La figure suivante montre la fenêtre de cette application:​ Par exemple, l'​application 3 communiquant avec la carte PIC 3 émet ses informations vers l'IP PIC 172.16.0.3 port 30032 et les reçoit sur le port 30031. La figure suivante montre la fenêtre de cette application:​
  
Ligne 146: Ligne 151:
  
 <ifauth @au> <ifauth @au>
-  - En émission ​depuis ​l'IP 172.16.6.34 port UDP 30002+10*x vers l'​IP ​de la carte PIC 172.16.6.x port 30002+10*x +  - En émission: Superviseur avec l'IP 172.16.6.34 ​ et le port UDP 30002+10*x vers carte PIC avec l'​IP ​  ​172.16.6.x ​ et le port 30002+10*x 
-  - En réception ​depuis ​l'​IP ​de la carte PIC PIC 172.16.6.x port UDP 30001+10*x vers l'IP 172.16.6.34 port  30001+10*x+  - En réception: Carte PIC avec l'IP 172.16.6.x ​ et le port UDP 30001+10*x vers Superviseur avec l'IP 172.16.6.34 ​et le port  30001+10*x 
 + 
 Par exemple, l'​application 3 communiquant avec la carte PIC 3 émet ses informations vers l'IP PIC 172.16.6.3 port 30032 et les reçoit sur le port 30031. La figure suivante montre la fenêtre de cette application:​ Par exemple, l'​application 3 communiquant avec la carte PIC 3 émet ses informations vers l'IP PIC 172.16.6.3 port 30032 et les reçoit sur le port 30031. La figure suivante montre la fenêtre de cette application:​
  
Ligne 237: Ligne 243:
  
  
-Cliquer sur Index puis sur UDP pour accéder à la partie qui nous sera utile. Le schéma suivant montre les différentes fonctions correspondant à l'​utilisation d'un socket UDP:+Cliquer sur Index puis sur UDP pour accéder à la partie qui nous sera utile. Le schéma suivant montre les différentes fonctions correspondant à l'​utilisation d'une socket UDP:
  
  
Ligne 245: Ligne 251:
  
  
-Nous nous restreindrons à utiliser les sockets dans un seul sens de communication à la fois et nous utiliserons donc deux sockets ​définis comme variables globales pour établir et maintenir la communication bidirectionnelle: ​+Nous nous restreindrons à utiliser les sockets dans un seul sens de communication à la fois et nous utiliserons donc deux sockets ​manipulés via deux variables globales pour établir et maintenir la communication bidirectionnelle: ​
   UDP_SOCKET udpsock; ​ //utilisé pour l'​émission depuis le PIC   UDP_SOCKET udpsock; ​ //utilisé pour l'​émission depuis le PIC
   UDP_SOCKET udpsock2; //utilisé pour la réception depuis le PIC   UDP_SOCKET udpsock2; //utilisé pour la réception depuis le PIC
    
-Chaque socket doit ensuite être ouvert dans la fonction ​Init par un appel à la fonction: ​ +Chaque socket doit ensuite être ouvert dans la fonction ​etudiantSocketAppInit() ​par un appel à la fonction: ​
   UDP_SOCKET UDPOpen( UDP_PORT localPort, ​ NODE_INFO * ptr_remoteNode, ​ UDP_PORT remotePort);​   UDP_SOCKET UDPOpen( UDP_PORT localPort, ​ NODE_INFO * ptr_remoteNode, ​ UDP_PORT remotePort);​
-localPort et remotePort ​sont ici égaux et valent ​le numéro du port associé au socket.  ptr_remoteNode est un pointeur sur une structure qui permet d'indiquer ​l'adresse IP de la machine connectée ​avec le socket. Cette structure est constituée de deux tableaux d'​octets IPAddr.v[] et  MACAddr.v[] codant respectivement l'​adresse IP et l'​adresse MAC du destinataire. Pour une socket ​écoutant sur n'​importe ​quelle adresse IP, il faut passer la valeur NULL comme paramètre effectif ptr_remoteNode.+Dans notre projet, les paramètres **localPort** et **remotePort** auront des valeurs effectives identiques pour un même socket: ​le numéro du port.  ​**ptr_remoteNode** est un pointeur sur une structure qui permet d'identifier ​l'hôte distant connecté ​avec le socket. Cette structure est constituée de deux tableaux d'​octets IPAddr.v[] et  MACAddr.v[] codant respectivement l'​adresse IP et l'​adresse MAC de l'​hôte distant. Pour ouvrir un socket ​en réception depuis ​n'​importe ​quel hôte, il faut passer la valeur ​**NULL** comme paramètre effectif ptr_remoteNode.
  
 +La fonction **UDPClose()** ne sera pas utilisée dans notre application,​ car les 2 sockets sont ouverts à l'​initialisation et utilisés tout au long de l'​exécution du programme.
  
 ===Socket en émission=== ===Socket en émission===
  
-Le socket en émission ​ peut alors émettre ses données à condition ​qu'il y ait de la place dans les buffers ​d'​émission ​de l'​interface Ethernet. Pour déterminer la place disponible, nous utiliserons la fonction suivante qui retourne le nombre de caractères que l'on peut émettre sur un socket:+Pour émettre des données sur un socket en émission, il faut s'​assurer ​qu'il y ait de la place dans son buffer ​d'​émission ​(FIFO). Pour déterminer la place disponible, nous utiliserons la fonction suivante qui retourne le nombre de caractères que l'on peut émettre sur un socket:
   WORD UDPIsPutReady( UDP_SOCKET s);   WORD UDPIsPutReady( UDP_SOCKET s);
  
-Si il y a suffisamment de place pour émettre les données, une chaîne de caractères cData contenant wDataLen caractères peut être émise ​par un appel à la fonction:+S'il y a suffisamment de place pour émettre les données, une chaîne de caractères ​**cData** contenant ​**wDataLen** caractères peut être copiée dans le buffer d'​émission ​par un appel à la fonction:
   WORD UDPPutArray( BYTE * cData, WORD wDataLen); //retourne le nombre de caractères effectivement émis.   WORD UDPPutArray( BYTE * cData, WORD wDataLen); //retourne le nombre de caractères effectivement émis.
-Finalement, pour demander l'​émission effective des données sur l'​interface, ​on fait appel à la fonction :+Finalement, pour demander l'​émission effective des données ​du buffer d'​émission ​sur l'​interface, ​il faut faire appel à la fonction :
   void UDPFlush();   void UDPFlush();
   ​   ​
 ===Socket en réception=== ===Socket en réception===
-Le socket en réception utilise d'​autres fonctions. La fonction UDPIsGetReady retourne le nombre de caractères pouvant être lus sur un socket,:+Le socket en réception utilise d'​autres fonctions. La fonction ​**UDPIsGetReady()** retourne le nombre de caractères pouvant être lus sur un socket, ​car disponible dans le buffer de réception:
   WORD UDPIsGetReady( UDP_SOCKET s);    WORD UDPIsGetReady( UDP_SOCKET s); 
-Les caractères (au nombre de wDataLen) sont ensuite lus vers une chaîne cData par la fonction:+Les caractères (au nombre de **wDataLen**) sont ensuite lus vers une chaîne ​**cData** par la fonction:
   WORD UDPGetArray( BYTE * cData, ​ WORD wDataLen);   WORD UDPGetArray( BYTE * cData, ​ WORD wDataLen);
-La fonction UDPClose() ne sera pas utilisée dans notre application,​ car les 2 sockets sont ouverts à l'​initialisation et utilisés tout au long de l'​exécution du programme.+
  
  
 ===Gestion du temps=== ===Gestion du temps===
-La fonction etudiantSocketAppTask() n'est pas appelée à intervalle de temps constant. Pour définir le nombre de fois que la tâche doit être exécutée par seconde, on utilise un timer que l'on vient scruter (mécanisme de scrutation plutôt que d'​interruption) à chaque appel de la fonction etudiantSocketAppTask() pour savoir s'il est temps d'​exécuter la tâche.+La fonction ​**etudiantSocketAppTask()** n'est pas appelée à intervalle de temps constant. Pour définir ​la périodicité (le nombre de fois que la tâche doit être exécutée par seconde), on utilise un timer que l'on vient scruter (mécanisme de scrutation plutôt que d'​interruption) à chaque appel de la fonction ​**etudiantSocketAppTask()** pour savoir s'il est temps d'​exécuter la tâche.
  
  
Ligne 279: Ligne 286:
   #define ETUDIANTSOCKETAPP_OCCURENCE_PAR_SEC 5ul //pour 5 fois par secondes,   #define ETUDIANTSOCKETAPP_OCCURENCE_PAR_SEC 5ul //pour 5 fois par secondes,
   ​   ​
-la fonction ​Task possède cette structure: +la fonction ​**etudiantSocketAppTask()** ​possède cette structure:
  
  
Ligne 294: Ligne 300:
  
 ===Génération et décodage de chaînes de caractères ASCII=== ===Génération et décodage de chaînes de caractères ASCII===
-Nous allons utiliser des tableaux de caractères pour l'​émission et la réception des données via les sockets car ce sont les paramètres d'​entrées/​sorties utilisés par les fonctions disponibles pour l'​envoi et la réception de datagrammes. Pour rappel, les fonctions permettant d'​écrire et de lire dans une chaîne de caractères chainecarac la chaîne de caractères formatée format(par exemple ''​Bonjour %d''​) sont:+Nous allons utiliser des tableaux de caractères pour l'​émission et la réception des données via les sockets car ce sont les paramètres d'​entrées/​sorties utilisés par les fonctions disponibles pour l'​envoi et la réception de datagrammes. Pour rappel, les fonctions permettant d'​écrire et de lire dans une chaîne de caractères ​**chainecarac** la chaîne de caractères formatée ​**format** (par exemple ''​Bonjour %d''​) sont:
  
   int sprintf(char* chainecarac,​ const char * format, ... );   int sprintf(char* chainecarac,​ const char * format, ... );
   int sscanf(char* chainecarac,​ const char * format, ... );    int sscanf(char* chainecarac,​ const char * format, ... ); 
-La fonction strlen retourne le nombre de caractères d'une chaîne chainecarac:​+La fonction strlen retourne le nombre de caractères d'une chaîne ​**chainecarac** terminée par le caractère '​\0'​:
    int strlen(char* chainecarac);​    int strlen(char* chainecarac);​
 ===Lecture de l'​état des boutons=== ===Lecture de l'​état des boutons===
-L'​état des 3 boutons est lu dans des variables ​par +L'​état des 3 boutons est lu et affecté à des variables ​grâce à:
   b1state=(int)!PORTReadBits(IOPORT_D,​ BIT_6);   b1state=(int)!PORTReadBits(IOPORT_D,​ BIT_6);
   b2state=(int)!PORTReadBits(IOPORT_D,​ BIT_7);   b2state=(int)!PORTReadBits(IOPORT_D,​ BIT_7);
Ligne 310: Ligne 316:
   LED1_IO ^= 1;    LED1_IO ^= 1; 
   LED2_IO ^= 1;   LED2_IO ^= 1;
 +
 Il est bien sûr possible de commander les leds par valeur par exemple avec: Il est bien sûr possible de commander les leds par valeur par exemple avec:
-  LED1_IO = 0; ou LED1_IO = 1;  ​+  LED1_IO = 0;  
 +  ​LED1_IO = 1;  ​ 
 +  LED1_IO = b2state;
  
 ====Remarques importantes:​==== ====Remarques importantes:​====
-   - Ne brancher le câble réseau sur l'​interface du PIC que lorsque vous voulez tester votre programme sur la carte et que vous l'avez déjà testé en pas à pas.+   - Dans tout le TP, vous veillerez à ne pas commenter ou casser du code précédemment validé. Chaque exercice doit ajouter des fonctionnalités,​ en maintenant le bon fonctionnement des fonctionnalités précédentes! 
 +   - Ne brancher le câble réseau sur l'​interface du PIC que lorsque vous voulez tester votre programme sur la carte.
    - Les cartes PIC ainsi que les câbles réseaux sont numérotés,​ il est IMPERATIF de n'​utiliser que votre câble et votre carte et de régler correctement l'​adresse IP de votre carte via le fichier "​TCPIPConfig PIC32 Internal Ethernet.h"​.    - Les cartes PIC ainsi que les câbles réseaux sont numérotés,​ il est IMPERATIF de n'​utiliser que votre câble et votre carte et de régler correctement l'​adresse IP de votre carte via le fichier "​TCPIPConfig PIC32 Internal Ethernet.h"​.
-  - Votre application est contenue uniquement dans les fichiers etudiantSocketApp.c et etudiantSocketApp.h. Vous n'avez pas à modifier d'​autres fichiers hormis "​TCPIPConfig PIC32 Internal Ethernet.h"​.+  - Votre application est contenue uniquement dans les fichiers etudiantSocketApp.c et etudiantSocketApp.h. Vous n'avez pas à modifier d'​autres fichiers hormis "​TCPIPConfig PIC32 Internal Ethernet.h" ​pour les réglages d'​adresses IP.
   - Ne jamais brancher une carte PIC sur le réseau sans avoir préalablement chargé votre programme... Elle contient peut être un mauvais programme qui va polluer tout le réseau et empêcher vos collègues de travailler!   - Ne jamais brancher une carte PIC sur le réseau sans avoir préalablement chargé votre programme... Elle contient peut être un mauvais programme qui va polluer tout le réseau et empêcher vos collègues de travailler!
-  - La carte de développement PIC32 est alimentée par le USB, ne pas chercher à l'​alimenter par une alimentation externe.+  - La carte de développement PIC32 est alimentée par le port USB, ne pas chercher à l'​alimenter par une alimentation externe.
   - Ne pas changer la position des cavaliers sur les cartes.   - Ne pas changer la position des cavaliers sur les cartes.
  
Ligne 324: Ligne 334:
  
 =====Travail demandé===== =====Travail demandé=====
 +
 +====Avant de coder...====
  
 ==Identification des binômes== ==Identification des binômes==
   - Remplir la feuille de présence pour déterminer qui utilise quelle carte et quelle adresse IP.    - Remplir la feuille de présence pour déterminer qui utilise quelle carte et quelle adresse IP. 
-Identification des éléments utiles sur le schéma et analyse des couches réseau ​+==Identification des éléments utiles sur le schéma et analyse des couches réseau==
   - Repérer sur le schéma à remplir les éléments utilisés pour faire dialoguer la carte PIC avec le PC superviseur..   - Repérer sur le schéma à remplir les éléments utilisés pour faire dialoguer la carte PIC avec le PC superviseur..
-  - Etablir ​un schéma faisant apparaître les différentes couches réseau impliquées.+  - Établir ​un schéma faisant apparaître les différentes couches réseau impliquées.
  
 ==Récupération du projet== ==Récupération du projet==
Ligne 355: Ligne 367:
 ==Lancement de l'​outils de développement== ==Lancement de l'​outils de développement==
   - Brancher la carte de développement sur le port USB du PC.   - Brancher la carte de développement sur le port USB du PC.
-  - Lancer mplabX, ​saisir dans la console: ​  ​mplab_ide  ​+  - Lancer mplabX, ​Menu Applications->​Programmation->​Mplab IDE
   - Dans mplabX, cliquer sur  File->​Open project et choisir le projet Projet.X dans le dossier ~/​TCPIP_Demo_App_etudiant ​     - Dans mplabX, cliquer sur  File->​Open project et choisir le projet Projet.X dans le dossier ~/​TCPIP_Demo_App_etudiant ​  
   - Par la suite, en cas de message d'​erreur indiquant que la carte ne peut pas être réinitialisée,​ il faudra fermer MPLABX et le relancer.   - Par la suite, en cas de message d'​erreur indiquant que la carte ne peut pas être réinitialisée,​ il faudra fermer MPLABX et le relancer.
Ligne 366: Ligne 378:
   #define MY_DEFAULT_IP_ADDR_BYTE4 {100ul}   #define MY_DEFAULT_IP_ADDR_BYTE4 {100ul}
   ​   ​
-Le masque est réglé à l'aide des macros MY_DEFAULT_MASK_BYTE1 à 4, de la même manière.+Le masque est réglé à l'aide des macros ​**MY_DEFAULT_MASK_BYTE1** à **4**, de la même manière.
  
-Le suffixe ul apres la valeur 100 signifie que la valeur est une constante à interpréter en tant que Unsigned Long. +Le suffixe ul apres la valeur 100 signifie que la valeur est une constante à interpréter en tant que **Unsigned Long**
 ==Chargement de votre programme et utilisation du mode debug== ==Chargement de votre programme et utilisation du mode debug==
   - Cliquer sur Debug->​Debug project. NB: la première compilation est lente (qq minutes) mais les suivantes seront plus rapides car seuls les fichiers modifiés seront recompilés (sauf si vous modifiez « TCPIPConfig PIC32 Internal Ethernet.h ») .   - Cliquer sur Debug->​Debug project. NB: la première compilation est lente (qq minutes) mais les suivantes seront plus rapides car seuls les fichiers modifiés seront recompilés (sauf si vous modifiez « TCPIPConfig PIC32 Internal Ethernet.h ») .
   - Placer des points d'​arrêt dans votre programme, en cliquant sur le numéro de la ligne (petit carré rouge apparaît), pour le désactiver,​ cliquer à nouveau sur le carré.   - Placer des points d'​arrêt dans votre programme, en cliquant sur le numéro de la ligne (petit carré rouge apparaît), pour le désactiver,​ cliquer à nouveau sur le carré.
   - Presser Debug->​debug project pour charger le programme dans le micro contrôleur et lancer le mode debug (Debug->​Finish debugger session)   - Presser Debug->​debug project pour charger le programme dans le micro contrôleur et lancer le mode debug (Debug->​Finish debugger session)
-===Test de communication avec la carte === + 
-Il y a plusieurs ​applications ​fonctionnant sur le PIC, notamment un service de réponse au PING.  +====Exercice 1: Test de communication avec la carte ==== 
-  - Votre carte étant en fonctionnement (RUN) et raccordée au réseau, lancer une demande de ping depuis ​le PC superviseur avec l'​adresse de votre carte. Votre PC envoie alors des demandes de PING à l'​adresse de la carte PIC. Si celle-ci est connectée au réseau et en fonction, elle doit répondre et l'​outil ping doit afficher le temps mis par la carte pour répondre (généralement moins d'une milliseconde sur ce réseau local). Cette opération peut être réalisée ​soit depuis le PC superviseur soit depuis votre machine de développement ​en saisissant ​ par exemple dans une console:+Il y a plusieurs ​tâches ​fonctionnant ​en (pseudo)parallèle ​sur le PIC, notamment un service de réponse au PING.  
 +  - Votre carte étant en fonctionnement (programme en cours d’exécution) et raccordée au réseau, lancer une demande de PING depuis ​votre PC superviseur avec l'​adresse de votre carte. Si celle-ci est connectée au réseau et en fonction, elle doit répondre et l'​outil ping doit afficher le temps mis par la carte pour répondre (généralement moins d'une milliseconde sur ce réseau local). Cette opération peut être réalisée ​ en saisissant ​ par exemple dans une console:
 <ifauth @en> <ifauth @en>
   ping 172.16.0.2   ping 172.16.0.2
Ligne 382: Ligne 395:
   ping 172.16.6.2   ping 172.16.6.2
 </​ifauth>​ </​ifauth>​
 +
 +
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}}
  
  
Ligne 390: Ligne 406:
   gitk &   gitk &
   echo fini   echo fini
-  ​ 
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} 
  
-  ​ 
  
-===Prise en main des E/S ===+====Exercice 2: Prise en main des E/S ====
   - Débrancher le cable réseau pour cet exercice.   - Débrancher le cable réseau pour cet exercice.
-  - Dans la fonction ​Task, recopier l'​état des boutons sur les leds correspondantes à une cadence d'une fois par seconde+  - Dans la fonction ​**etudiantSocketAppTask()**, recopier l'​état des boutons sur les LEDs correspondantes ​**à une cadence d'une fois par seconde**
-  - Utiliser l'​outil de debug en pas à pas pour suivre l'​exécution de votre programme+  - Afficher sur l'​interface debug la chaîne ​qui devrait être envoyé au superviseur pour donner l'​état des boutons à l'aide de la fonction ​**DBPRINTF** présentée plus haut. La chaîne ​affichée devra être générée dans le tableau ​**chaine** que vous aurez déclaré préalablement avec une taille suffisante. Le remplissage du tableau se fera à l'aide de la fonction **sprintf**:
-  - Afficher sur l'​interface debug la chaine ​qui devrait être envoyé au superviseur pour donner l'​état des boutons à l'aide de la fonction DBPRINTF présentée plus haut. La chaine ​affichée devra être générée dans le tableau chaine à l'aide de:+
  
  
   sprintf(chaine,"​compteur= %6d b1:%d  b2:%d  b3:​%d\n",​compteuretudiant,​b1state,​b2state,​b3state);​   sprintf(chaine,"​compteur= %6d b1:%d  b2:%d  b3:​%d\n",​compteuretudiant,​b1state,​b2state,​b3state);​
 +
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}}
   ​   ​
 Mettre à jour le suivi de version en saisissant dans une console: Mettre à jour le suivi de version en saisissant dans une console:
Ligne 411: Ligne 425:
   echo fini   echo fini
   ​   ​
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} 
  
  
-===Réception de commandes des LED === +====Exercice 3: Réception de commandes des LED ==== 
-  - Remplir ​les fonctions ​Init et Task pour gérer la réception périodique des chaînes de caractères commandant les LED depuis le PC superviseur. Pour cela, vous devrez ouvrir ​une socket écoutant sur le bon numéro de port et depuis n'​importe quelle IP.  Veillez à définir un tableau de caractères en mémoire et à ne pas tenter de lire plus de caractères qu'il n'y a de place dans ce tableau. Vous penserez à commenter les lignes de votre programme qui pilotent les leds à partir de l'​état des boutons pour ne pas interférer avec la commande des leds depuis le réseau. +  - Compléter ​les fonctions ​**etudiantSocketAppInit()** ​et **etudiantSocketAppTask()** ​pour gérer la réception périodique des chaînes de caractères commandant les LED depuis le PC superviseur. Pour cela, vous devrez ouvrir ​un socket écoutant sur le bon numéro de port et depuis n'​importe quelle IP.  Veillez à définir un tableau de caractères en mémoire et à ne pas tenter de lire plus de caractères qu'il n'y a de place dans ce tableau. ​Vous pourrez au choix traiter un ordre de commutation des LEDS par appel de la fonction **etudiantSocketAppTask()** ou bien traiter autant d'​ordres que possible (en fonction de la taille de votre tableau) 
-  - Tester votre programme en demandant sur le PC superviseur,​ via l'​application BroadcastReceiver qui communique avec votre carte PIC, de commuter chacune des LED.+  - Vous penserez à commenter ​**UNIQUEMENT** ​les lignes de votre programme qui pilotent les leds à partir de l'​état des boutons pour ne pas interférer avec la commande des LEDs depuis le réseau. Conserver tout le reste du code en place, notamment la lecture de l'​état des boutons et l'​affichage de la chaine dans **DBPRINTF**
 +  - Tester votre programme en demandant sur le PC superviseur,​ via l'​application BroadcastReceiver qui communique avec votre carte PIC, de commuter chacune des LEDs. 
 + 
 + 
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} 
  
 Mettre à jour le suivi de version en saisissant dans une console: Mettre à jour le suivi de version en saisissant dans une console:
Ligne 424: Ligne 442:
   gitk &   gitk &
   echo fini   echo fini
 +====Exercice 4: Émission de l'​état des boutons ====
 +  - Compléter les fonctions **etudiantSocketAppInit()** et **etudiantSocketAppTask()** pour gérer l'​envoi périodique à une fréquence d'un Hertz d'une chaîne de caractères codant l'​état des boutons poussoirs vers le PC superviseur. ​
  
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} +Pour cette tâche, il faut configurer l'​ouverture ​du socket avec une seule machine sur le réseau. Dans un premier temps, nous n'​utiliserons pas le mécanisme ARP et nous devrons donc régler l'​adresse IP et l'​adresse MAC de la machine ​distante ​(le PC superviseur) avant d'​ouvrir ​le socket en définissant une variable globale ​**NODE_INFO myRemoteNode;​** puis en l'​initialisant dans la fonction ​**etudiantSocketAppInit()** ​avec les valeurs que vous aurez déterminées ​grâce aux commandes ping et arp:
- +
-===Émission de l'​état des boutons === +
-  - Remplir les fonctions Init et Task pour gérer l'​envoi périodique à une fréquence d'un Hertz d'une chaîne de caractères codant l'​état des boutons poussoirs vers le PC superviseur.  +
- +
-Pour cette tâche, il faut configurer l'​ouverture ​de la socket ​pour qu'​elle s'​établisse ​avec une seule machine sur le réseau. Dans un premier temps, nous n'​utiliserons pas le mécanisme ARP et nous devrons donc régler l'​adresse IP et l'​adresse MAC de la machine ​destination ​(le PC superviseur) avant d'​ouvrir ​la socket en définissant une variable globale NODE_INFO myRemoteNode;​ puis en l'​initialisant dans la fonction ​Init avec les valeurs que vous aurez déterminée ​grâce aux commandes ping et arp:+
  
   myRemoteNode.IPAddr.v[0] = XXX;  //Adresse IP du PC superviseur,​ premier octet  (de poids fort)   myRemoteNode.IPAddr.v[0] = XXX;  //Adresse IP du PC superviseur,​ premier octet  (de poids fort)
Ligne 436: Ligne 451:
   myRemoteNode.IPAddr.v[2] = XXX;   myRemoteNode.IPAddr.v[2] = XXX;
   myRemoteNode.IPAddr.v[3] = XXX;   myRemoteNode.IPAddr.v[3] = XXX;
-  myRemoteNode.MACAddr.v[0]= XXX; //Adresse MAC du PC superviseur,​ premier octet+  myRemoteNode.MACAddr.v[0]= XXX; //Adresse MAC du PC superviseur,​ premier octet (de poids fort)
   myRemoteNode.MACAddr.v[1]= XXX;   myRemoteNode.MACAddr.v[1]= XXX;
   myRemoteNode.MACAddr.v[2]= XXX;   myRemoteNode.MACAddr.v[2]= XXX;
Ligne 443: Ligne 458:
   myRemoteNode.MACAddr.v[5]= XXX;    myRemoteNode.MACAddr.v[5]= XXX; 
  
-Ensuite, passer ​ myRemoteNode en paramètre à la fonction UDPOpen lors de l'​ouverture ​de la socket en émission.+Ensuite, passer ​un pointeur sur **myRemoteNode** en paramètre à la fonction ​**UDPOpen()** lors de l'​ouverture ​du socket en émission. 
 + 
 + 
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}}
  
  
Ligne 452: Ligne 470:
   gitk &   gitk &
   echo fini   echo fini
-  ​ 
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} 
  
  
- +====Exercice 5: Gestion de l'ARP pour la communication avec le PC superviseur==== 
-===Gestion de l'ARP pour la communication avec le PC superviseur=== +On souhaite maintenant mettre en place le mécanisme d'ARP dans l'​application sur le PIC. Vous allez dans un premier temps "​casser"​ l'​initialisation de **myRemoteNode.MACAddr.v[i]** en mettant des 0 dans toutes les cases et nous allons utiliser les fonctions suivantes pour remplir automatiquement ​ce tableau:
-On souhaite maintenant mettre en place le mécanisme d'ARP dans l'​application sur le PIC. Vous allez dans un premier temps "​casser"​ l'​initialisation de **myRemoteNode.MACAddr.v[i]** en mettant des 0 dans toutes les cases et nous allons utiliser les fonctions suivantes pour remplir automatiquement ​le tableau:+
  
   ARPResolve(type pointeur sur adresse IP  );   ARPResolve(type pointeur sur adresse IP  );
Ligne 464: Ligne 479:
   bool ARPIsResolved(type pointeur sur adresse IP, type pointeur sur adresse MAC)   bool ARPIsResolved(type pointeur sur adresse IP, type pointeur sur adresse MAC)
  
-Dans la fonction ​Task, à l'​intérieur de la tâche périodique à 1Hz, ajouter une machine à état **simple** permettant de faire des requêtes ARP avec la fonction **ARPResolve**. Ceci permet d'​envoyer une requette ARP avec l'​adresse IP passée en argument. Dans les appels suivants de la fonction ​task, il vous faudra tester si **ARPIsResolved** a renvoyé ​true, ce qui signifie que la réponse ARP est arrivée et donc que le champ adresse MAC est mis à jour. Dans ce cas il faudra ouvrir ​la socket (une seule fois) puis effectuer l'​envoi des données comme dans l'​exercice ​précedent. Dans le cas contraire, il faudra appeler à nouveau **ARPResolve** pour envoyer une nouvelle requête.+Dans la fonction ​**etudiantSocketAppTask()**, à l'​intérieur de la tâche périodique à 1Hz, ajouter une machine à état **simple** ​(l'​état étant codé par une variable **static int**) ​permettant de faire des requêtes ARP avec la fonction **ARPResolve**. Ceci permet d'​envoyer une requette ARP avec l'​adresse IP passée en argument. Dans les appels suivants de la fonction** etudiantSocketAppTask()**, il vous faudra tester si **ARPIsResolved** a renvoyé ​**TRUE**, ce qui signifie que la réponse ARP est arrivée et donc que le champ adresse MAC est mis à jour. Dans ce cas il faudra ouvrir ​le socket (une seule fois) puis effectuer l'​envoi des données comme dans l'​exercice ​précédent. Dans le cas contraire, il faudra appeler à nouveau **ARPResolve** pour envoyer une nouvelle requête. 
  
 <color red> <color red>
-Il est important que la fonction ​ etudiantSocketAppTask() soit NON BLOQUANTE!</​color>​+Il est important que la fonction ​**etudiantSocketAppTask()** soit NON BLOQUANTE!</​color>​
  
-<​graphviz dot 500x90>+<​graphviz dot 350x90>
 ////////////////////////////////////////////////////////////////////////////////​ ////////////////////////////////////////////////////////////////////////////////​
 // Finite State Machine .dot diagram autogenerated by FsmProcess V 1.0 B. VANDEPORTAELE LAAS-CNRS 2016 // Finite State Machine .dot diagram autogenerated by FsmProcess V 1.0 B. VANDEPORTAELE LAAS-CNRS 2016
Ligne 478: Ligne 494:
     nodesep=0.1;​     nodesep=0.1;​
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////​ ///////////////////////////////////////////////////////////////////////////////////////////////////////////​
-// Finite State Machine Name: arp+// Finite State Machine Name: arp2
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////​ ///////////////////////////////////////////////////////////////////////////////////////////////////////////​
 //////////////////​display ​ states//////////////////​ //////////////////​display ​ states//////////////////​
Ligne 496: Ligne 512:
     //Action on state:     //Action on state:
     stateaction_1 ​ [shape=box,​label= ​  <<​TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4">​     stateaction_1 ​ [shape=box,​label= ​  <<​TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4">​
-        <​TR><​TD>​F</​TD><​TD COLSPAN="​2">​UDPOPEN</TD> </TR>+        <​TR><​TD>​F</​TD><​TD COLSPAN="​2">​UDPPUTARRAY</TD> </TR>
         </​TABLE>> ​ ];         </​TABLE>> ​ ];
     //attach the action on the state     //attach the action on the state
     state_1 ->​stateaction_1 ​ [arrowhead=none ]     ;     state_1 ->​stateaction_1 ​ [arrowhead=none ]     ;
- ​}; ​ 
-    //​---------State: ​  ​2 ​   ----------------- 
- { rank = same; 
-    state_2 [shape=circle,​fixedsize=true,​width=0.63,​ label= "​2"​ ]; 
-    //Action on state: 
-    stateaction_2 ​ [shape=box,​label= ​  <<​TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4">​ 
-        <​TR><​TD>​F</​TD><​TD COLSPAN="​2">​UDPPUTARRAY</​TD>​ </TR> 
-        </​TABLE>> ​ ]; 
-    //attach the action on the state 
-    state_2 ->​stateaction_2 ​ [arrowhead=none ]     ; 
  ​}; ​  ​}; ​
 //////////////////​display ​ transitions//////////////////​ //////////////////​display ​ transitions//////////////////​
     state_0 -> state_1[ shape=box, ​ label= ​ <<​TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4">​     state_0 -> state_1[ shape=box, ​ label= ​ <<​TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4">​
-        <​TR><​TD COLSPAN="​2">​ARPISRESOLVED</​TD>​ </​TR>​ +        <​TR><​TD COLSPAN="​3">​ARPISRESOLVED</​TD>​ </​TR>​ 
-        </TABLE>>  ]; +        <TR><TD>F</TD><TD COLSPAN="​2">​UDPOPEN</TD> </TR>
-    state_1 -> state_2[ shape=box, ​ label=  ​<<TABLE BORDER="​0"​ CELLBORDER="​1"​ CELLSPACING="​0"​ CELLPADDING="​4"​> +
-        <TR><TD COLSPAN="​2">​1</TD> </TR>+
         </​TABLE>> ​ ];         </​TABLE>> ​ ];
 } }
- 
 </​graphviz>​ </​graphviz>​
  
  
 +Pour débugger, vous pourrez afficher l'​adresse IP demandée dans la requête ARP à l'aide de: 
 +  sprintf(chaine,​ "​ARPResolve adresse IP= %d.%d.%d.%d\n",​ myRemoteNode.IPAddr.v[0],​ myRemoteNode.IPAddr.v[1],​ myRemoteNode.IPAddr.v[2],​ myRemoteNode.IPAddr.v[3]);​
 +  DBPRINTF(chaine);​
 +Puis afficher l'​adresse MAC obtenue à l'aide de 
 +  sprintf(chaine,​ "ARP OK: adresse mac= %02x:​%02x:​%02x:​%02x:​%02x:​%02x\n",​ myRemoteNode.MACAddr.v[0],​ myRemoteNode.MACAddr.v[1],​ myRemoteNode.MACAddr.v[2],​ myRemoteNode.MACAddr.v[3],​ myRemoteNode.MACAddr.v[4],​ myRemoteNode.MACAddr.v[5]);​
 +  DBPRINTF(chaine);​
 +        ​
 +
 +
 +Tester l'​émission avec le mécanisme d'ARP avec le PC superviseur. Utiliser le logiciel Wireshark sur le PC superviseur pour observer la requête et la réponse ARP suivies des datagrammes UDP échangés entre votre carte PIC et l'​application correspondante sur le PC superviseur.
 +
 +  ​
 +{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}}
  
  
-Tester l'​émission avec le mécanisme d'ARP avec le PC superviseur. 
  
 Mettre à jour le suivi de version en saisissant dans une console: Mettre à jour le suivi de version en saisissant dans une console:
Ligne 533: Ligne 548:
   gitk &   gitk &
   echo fini   echo fini
-  ​ 
-{{http://​homepages.laas.fr/​bvandepo/​files/​iut/​tp_pic/​validation.png}} 
- 
  
 <ifauth @prof> <ifauth @prof>
Ligne 654: Ligne 666:
 Commentaire pour watch, or le débugger déconne: Commentaire pour watch, or le débugger déconne:
  
-  - Utiliser View->​Watch pour suivre les valeurs de variables (par exemple le compteur incrémenté à chaque appel de la fonction ​Task). Pour cela, sélectionner le nom de la variable dans la liste et cliquer sur add, la variable ainsi que sa valeur sont alors ajoutés en bas de liste. Pour visualiser la valeur d'un registre à usage spécial, procéder de la même façon dans la liste SFR.+  - Utiliser View->​Watch pour suivre les valeurs de variables (par exemple le compteur incrémenté à chaque appel de la fonction ​etudiantSocketAppTask() ​). Pour cela, sélectionner le nom de la variable dans la liste et cliquer sur add, la variable ainsi que sa valeur sont alors ajoutés en bas de liste. Pour visualiser la valeur d'un registre à usage spécial, procéder de la même façon dans la liste SFR.
  
  
tppic.1550131281.txt.gz · Dernière modification: 2019/02/14 09:01 par bvandepo