Telechargé par Thorsten Mons

poly RTOS 3AIA 2018

publicité
3A INSTRUMENTATION AVANCEE
SYSTEMES TEMPS REEL
&
Capteurs connectés
2017
SYSTEMES TEMPS REEL
CONTACTS
Établissement
ENSICAEN
6 boulevard Maréchal Juin
CS 45053
14050 CAEN cedex 04
Référents
Hugo Descoubes
[email protected]
+33 (0)2 31 45 27 61
+33 (0)6 22 07 21 51
https://fr.linkedin.com/in/hugo-descoubes-823a4268
Philippe Lefebvre
[email protected]
+33 (0)2 31 45 27 58
SYSTEMES TEMPS REEL
RESSOURCES
Les différentes ressources numériques sont accessibles sur la
plateforme pédagogique de l'ENSICAEN (aucune authentification
requise)
 Lien direct : https://foad.ensicaen.fr/course/view.php?id=213
 Lien indirect : http://foad.ensicaen.fr/
 Formation Classique
 Spécialité Électronique et Physique Appliquée
 3ière année
 Majeure Instrumentation Avancée
 Systèmes Temps Réel
 Ne pas oublier de s'inscrire au cours avant tout dépôt !
SYSTEMES TEMPS REEL
Sommaire
0. OUTILS DE DÉVELOPPEMENTS
1. COURS FREERTOS
2. TP TEMPS RÉEL
3. TP PROGRAMMATION IP
4. CONFÉRENCE INTERNET DES OBJETS
SYSTEMES TEMPS REEL
OUTILS DE DEVELOPPEMENT
Installer les outils de développement et venir en séance avec vos machines
personnelles (IDE MPLABX et toolchain C XC32). Les TP peuvent être réalisés
indifféremment sur plateforme Windows ou GNU\Linux.
 IDE MPLAB X (Environnement de Développement Intégré):
http://www.microchip.com/mplabx
 Toolchain C XC32 (anciennes versions, installer XC32 v1.21 – Free mode) :
http://www.microchip.com/development-tools/downloads-archive
 Toolchain C XC32 (Free mode) :
http://www.microchip.com/xc32
La trame de TP n'utilisant comme interface que le module UART 1 du PIC32 en
mode transmission, il est alors possible de valider la compilation et le fonctionnement
de vos programmes depuis chez vous en mode Simulateur. Voici la procédure :
 Ouvrir les propriétés du projet : fenêtre Project > clic droit sur le nom du projet
> Properties
 Sélectionner le simulateur : Hardware Tool > Simulator
 Configurer le simulateur : Simulator > Options Categories [UART1 IO Options] >
Enable UART1 IO
 Sauvegarder les propriétés du projet : Apply > OK
 Ouvrir une console de debug : Window > Debugging > Debug Console
 Compiler et exécuter le projet en mode Debug : Debug > Debug Main Project
 Visualiser la console de sortie : sélectionner la nouvelle fenêtre de sortie "UART
1 Output" et Hop c'est magique (normalement) !
SYSTEMES TEMPS REEL
FREERTOS
SYSTEMES TEMPS REEL
FreeRTOS
SOMMAIRE
1. PREAMBULE
2. SYSTEME D'EXPLOITATION TEMPS REEL
2.1. Tâche
2.2. Gestion mémoire
2.3. Gestion du tas
2.4. Création de tâche
2.5. Mode préemptif
3. QUEUE DE MESSAGES
3.1. API de FreeRTOS
3.2. Timeout
4. SEMAPHORE
4.1. Sémaphore binaire
4.2. MUTEX
4.3. Sémaphore à compteur
1
SYSTEMES TEMPS REEL
FreeRTOS
1. PREAMBULE
Durant la lecture de cette partie, nous allons nous intéresser à l'exécutif temps réel ou RTOS
(Real Time Operating System) FreeRTOS. La traduction littérale en Français de RTOS est Système
d'Exploitation Temps Réel. Il serait néanmoins plus rigoureux d'appeler ce type d'outil scheduler ou
ordonnanceur, plus que système d'exploitation, à l'image par exemple de systèmes comme GNU/Linux,
Android, Windows, MacOS. Néanmoins, l'acronyme OS est un abus de langage fréquemment utilisé
dans le monde de l'embarqué pour parler des systèmes d'exploitation temps réel.
Un scheduler ou ordonnanceur nous propose des services logiciel (tâches, queues de
messages, sémaphores ...). Bien maîtrisé, il s'agit d'une aide précieuse durant les phases de
développement d'un projet (évolutivité, modélisation, gestion optimale des ressources CPU ...).
Néanmoins, encore beaucoup de systèmes autour de nous fonctionnent sans OS (cf. sondage cidessous, UBM Tech). La question d'utiliser ou pas un ordonnanceur dépend bien sûr de l'application.
Dès que les spécifications fonctionnelles d'une application mettent en avant un certain nombre
(difficile à estimer) de traitements pouvant potentiellement s'exécuter en parallèle, la question
d'utiliser un RTOS se pose. Pour des applications communicantes (Bluetooth, WIFI, réseaux de
terrains ...), l'utilisation d'un OS peut s'avérer très utile.
Il existe un grand nombre de RTOS, libres, open Sources et propriétaires (RTX, MicroC/OS III,
FreeRTOS, VxWorks...) possédant des jeux d'avantages et d'inconvénients différents afin de s'adapter
au très grand nombre de problématiques du marché. Nous avons de notre côté à l'école porté notre
attention sur FreeRTOS, un petit scheduler temps réel offrant un certain nombre d'avantages. La
documentation de FreeRTOS est directement accessible en ligne depuis le site internet
(http://www.freertos.org/).
2
SYSTEMES TEMPS REEL
FreeRTOS
En 2017, FreeRTOS est l'un des RTOS leader sur le marché de l'embarqué. FreeRTOS est libre de
droit d'utilisation et open source (sous licence). Il est officiellement supporté par 34 architectures (TI,
Microchip, Atmel, NXP, Intel ...) et 18 chaînes de compilation. Il a par exemple été téléchargé plus de
100000 fois l'année passée, cela implique une communauté assez riche d'utilisateurs. Il existe de plus
en tout 4 variantes de FreeRTOS :
●
FreeRTOS : cf. ci-dessus
●
FreeRTOS + Trace : idem FreeRTOS avec des outils propriétaires permettant
d'instrumenter le code. Par exemple des outils graphique de trace.
●
OpenRTOS : version commerciale sous licence de FreeRTOS
●
SafeRTOS : version certifié SIL3 TUV
De plus en 2016, FreeRTOS est le RTOS actuellement le plus utilisé et celui le plus regardé pour
démarrer de nouveaux projets. Observons le marché en 2015 des OS et RTOS pour l'embarqué
(www.eetimes.com) :
3
SYSTEMES TEMPS REEL
FreeRTOS
2. SYSTEME D'EXPLOITATION TEMPS REEL
FreeRTOS, comme n'importe quel autre noyau, est un outil purement logiciel, ce n'est qu'un
système de fichiers. FreeRTOS nous propose une API de programmation pour gérer un environnement
multitâches. La notion de tâche sera présentée par la suite. Vous trouverez ci-dessous le systèmes de
fichiers du noyau :
4
SYSTEMES TEMPS REEL
FreeRTOS
2.1. Tâche
Dans un environnement multitâches, l'application est découpée en plusieurs tâches
correspondant à des actions à effectuer. Le rôle de l'ordonnanceur est alors de gérer cet environnent
sachant que potentiellement, plusieurs d'entre-elles chercheront à s'exécuter en même temps.
N'oublions pas qu'un PIC32 ne possède qu'un seul CPU, l'ordonnanceur ne pourra donc donner la main
qu'à une seule tâche à la fois. Vous constaterez qu'à première vue, une tâche ressemble beaucoup à
une simple fonction. Nous verrons par la suite qu'une tâche est bien plus que ça. Observons un
exemple de tâche sous FreeRTOS :
void Task1( void *pvParameters ){
}
// Faire toujours
for( ;; ){
// code utilisateur
}
Une tâche est le plus souvent implémentée sous forme d'une boucle infinie. De plus,
l'ordonnanceur a la capacité de pouvoir faire passer une tâche dans différents états :
●
Running (en cours) : il s'agit de la tâche en cours d'exécution par le CPU. Une seule tâche peutêtre dans cet état.
●
Ready (prêt) : les tâches dans cet état sont prêtes à être exécutées. Il suffit que la tâche à l'état
en cours redonne la main à l'ordonnanceur ou que celui-ci la reprenne et selon le contexte
d'exécution (priorité supérieure, round-robin ...) une nouvelle tâche s'exécutera.
●
Blocked (bloqué) : les tâches dans cet état sont en attentes d'un événement pour se réveiller
(queue de messages, sémaphores, timeout ...). Une fois l'événement arrivé, la tâche concernée
repasse alors à l'état prêt.
●
Suspended (suspendu) : Cet état, peu utilisé, est propre à FreeRTOS et est à manier avec
précaution. Une tâche dans cet état n'est plus vue de l'ordonnanceur.
5
SYSTEMES TEMPS REEL
FreeRTOS
États d'une tâche sous FreeRTOS :
Une différence très importante entre une simple fonction et une tâche est qu'à chaque tâche
est associée un TCB (Task Control Block). Un TCB est une structure de données décrivant une tâche
(descripteur de tâche). L'ordonnanceur utilise ensuite les TCB pour le management de son
environnement multitâches. Sous FreeRTOS, un TCB comporte par exemple :
●
la priorité de la tâche
●
le ou les événements qu'elle attend
●
le pointeur de base de la pile associée à la tâche
●
le pointeur de sommet de pile
●
...
6
SYSTEMES TEMPS REEL
FreeRTOS
2.2. Gestion mémoire
Ce sont les TCB que l'ordonnanceur analyse afin de savoir à quelle tâche prendre ou donner du
temps CPU. Depuis la première année, tous les programmes que vous avez développés sur MCU
n'étaient constitués que d'un main() voir d'ISR's, aucun OS n'était embarqué. Effectuons quelques
rapides rappels sur le fonctionnement du main() et notamment les mécanismes de gestion mémoire
réalisés conjointement par la chaîne de compilation et le processeur.
●
Sans noyau, si une application n'est constituée que d'un main(), la mémoire des données peutêtre découpée en deux grandes zones. La zone où se trouvent les variables statiques (variables
globales, locales static ...) et celle nommée pile ou stack où sont notamment gérées les
variables locales (dynamiques). Selon l'application, un tas peut également être utilisé. Toutes
les variables locales du main() ou des fonctions appelées depuis le main() sont allouées
dynamiquement dans la pile du main() ou pile système. Il en est de même des variables locales,
paramètres de fonction et des sauvegardes de contexte des fonctions d'interruption. Prenons
un exemple de mapping mémoire pour une application sans OS et sans Tas système :
unsigned char stringBuffer[100] = "FreeRTOS test !";
/**
* @fn main
* @brief main entry point
*/
int main(void){
// Configurations matérielles
UserInit();
// envoi d'une chaîne de caractères via UART
UARTputs(stringBuffer);
}
// On reste bloqué ici ... pour le moment !
while(1);
●
Sous FreeRTOS, le noyau utilise une zone de taille configurable nommée Tas ou Heap.
Attention, en fonction de la stratégie de gestion du tas choisie (fichiers heap_1.c, heap_2.c,
heap_3.c ou heap_4.c) le tas peut-être le tas système ou une simple très large variable globale.
Chaque tâche possède sa propre pile dans le Tas du kernel. Chaque tâche possède donc un
environnement d'exécution indépendant.
7
SYSTEMES TEMPS REEL
FreeRTOS
void Task1( void *pvParameters );
void Task2( void *pvParameters );
/**
* @fn main
* @brief main entry point
*/
int main(void){
// Création de 2 tâches
xTaskCreate( Task1, "Task 1", configMINIMAL_STACK_SIZE, ...);
xTaskCreate( Task2, "Task 2", configMINIMAL_STACK_SIZE, ...);
// Démarrage ordonnanceur
vTaskStartScheduler();
}
while(1);
// ... Nous ne reviendrons jamais ici !
void Task1( void *pvParameters ){
// Faire toujours
for( ;; ){ ... }
}
void Task2( void *pvParameters ){
// Faire toujours
for( ;; ){ ... }
}
2.3. Gestion du Tas
Dans le cas de FreeRTOS, le Tas ou heap n'est qu'un tableau déclaré en variable globale
(stratégies heap_1.c et heap_2.c). En tant que développeur, vous n'aurez pas directement accès à ces
fonctions d'allocation. Durant la création d'une tâche, le noyau génère un espace pour la TCB et la pile
de celle-ci dans le Tas.
Attention, en fonction de l'application et du MCU il faut être très prudent à l'espace alloué au
Tas et aux piles de chaque tâche. Par exemple, si la taille d'une pile est trop faible, en cas de
débordement de pile (stack overflow) nous pouvons écraser le contenu de la TCB de la tâche suivante
dans le Tas ... et donc faire tomber l'application. FreeRTOS propose 3 principales techniques pour la
gestion du Tas. Il suffit pour cela d'inclure à votre projet l'un des trois fichiers sources ci-dessous :
●
●
●
heap1.c : seules des allocations dynamiques sont possibles (exemple, créations de tâches).
Nous utiliserons ce fichier durant la trame de TP.
heap2.c : allocations et désallocations dynamiques sont possibles (exemple, créations et
suppressions de tâches). Soyez très prudent avec la désallocation de ressources et la gestion
par le kernel d'une mémoire fragmentée.
heap3.c : idem heap2.c, mais utilise les API standards malloc() et free() proposées par la chaîne
de compilation.
8
SYSTEMES TEMPS REEL
FreeRTOS
Exemple de mapping mémoire après la création de 2 tâches sous FreeRTOS :
void Task1( void *pvParameters );
void Task2( void *pvParameters );
/**
* @fn main
* @brief main entry point
*/
int main(void){
// Création de 2 tâches
xTaskCreate( Task1, "Task 1", configMINIMAL_STACK_SIZE, ...);
xTaskCreate( Task2, "Task 2", configMINIMAL_STACK_SIZE, ...);
// Démarrage ordonnanceur
vTaskStartScheduler();
}
// Nous ne reviendrons jamais ici !
while(1);
void Task1( void *pvParameters ){
// Faire toujours
for( ;; ){
// code utilisateur
}
}
void Task2( void *pvParameters ){
// Faire toujours
for( ;; ){
// code utilisateur
}
}
Vous constaterez que nous n'avons créé que deux tâches alors que le noyau en a créé trois. En
effet juste avant de démarrer l'ordonnanceur, le noyau crée une ultime tâche nommée tâche Idle qui
est la tâche de plus basse priorité de l'application. Lorsque aucune tâche ne tourne (tâches bloquées),
c'est en fait la tâche Idle qui est en cours d'exécution. Nous ne reviendrons donc jamais dans le main().
Nous verrons dans la trame de TP qu'il est d'ailleurs possible de détourner la tâche Idle. Pour
information, certains noyau considèrent le main() comme une tâche, ce n'est pas le cas de FreeRTOS.
9
SYSTEMES TEMPS REEL
FreeRTOS
2.4. Création de tâche
Nous avons précédemment vu qu'à la création d'une tâche, le noyau alloue un espace pour la
TCB et la pile dans le Tas. Découvrons maintenant le rôle des paramètres passés à l'API de création de
tâche (xTaskCreate()) :
void Task1( void *pvParameters );
const char *pvParametersTask1 = "Passage d'un pointeur sur une chaîne de caractères !";
/**
* @fn main
* @brief main entry point
*/
int main(void){
}
// Création d'une tâche
xTaskCreate( Task1,
"Tache 1",
configMINIMAL_STACK_SIZE,
pvParametersTask1,
tskIDLE_PRIORITY + 1,
NULL);
...
// Pointeur sur la fonction implémentant la tâche
// Chaîne de caractères associée à la tâche (debug).
// Taille de la pile associée à la tâche
// Paramètre passé à la tâche
// Priorité associée à la tâche
// "handle" pour la gestion de la tâche
●
Task1 : pointeur sur la fonction implémentant le tâche
●
''Tache 1'' : chaîne de caractères associée à la tâche (sauvée dans la TCB). Utilisé par des outils
de trace ou pour de l'instrumentation de code (par exemple, stack overflow).
●
configMINIMAL_STACK_SIZE: taille de la pile associée à la tâche. Cette macro est définie dans le
fichier FreeRTOSConfig.h. Il s'agit par défaut de la taille de la pile pour la tâche Idle. Attention,
cette taille est donnée en ''Words'' et non en octets. La taille d'un Word dépend de
l'architecture matérielle utilisée. Dans notre cas un Word = 32bits (les PIC32MX sont des MCU's
32bits).
●
pvParametersTask1: possibilité de passer un paramètre à la tâche.
●
tskIDLE_PRIORITY + 1 : priorité de la tâche. tskIDLE_PRIORITY ou ''0'' est la priorité minimale qui
correspond à la priorité de la tâche Idle. La priorité maximale vaut configMAX_PRIORITIES
définie dans FreeRTOSConfig.h.
●
NULL : il s'agit d'un outil de préemption permettant de passer la tâche en cours de création à
l'état suspendu. A manipuler avec précaution.
10
SYSTEMES TEMPS REEL
FreeRTOS
2.5. Mode préemptif
En mode coopératif, chaque tâche doit explicitement permettre à une autre tâche de
s'exécuter. Ce mode de fonctionnement était encore très rencontré notamment jusqu'à MS-DOS et
Mac OS 9 qui étaient tout deux des OS coopératifs. Cependant ce mode peut amener de gros
problèmes de robustesse. Par exemple, imaginons que nous restons bloqué dans une tâche (bug). Les
autres tâches ne pourront donc jamais prendre la main ... nous venons de faire tomber l'application.
En mode préemptif, l'OS prend périodiquement la main et force un réordonnancement. La
référence de temps utilisée est nommée tick (timer clock). Ce mode de fonctionnement est plus
robuste, les principaux OS sur ordinateur sont préemptif (Windows 8, Mac OS X, Linux ...). Exemple
d'exécution en mode préemptif sous FreeRTOS :
Dans notre cas, FreeRTOS configure et utilise un timer du processeur. Ce timer interrompt
périodiquement le programme en cours d'exécution en envoyant une demande d'interruption au CPU.
Une demande d'interruption ou IRQ peut arriver n'importe quand. Ce qui signifie que, sauf dans
certains cas (par exemple sections critiques ...), n'importe quelle tâche peut être interrompue à
n'importe quel moment pour donner la main à l'ordonnanceur. Quelque soit la priorité de la tâche en
cours d'exécution.
11
SYSTEMES TEMPS REEL
FreeRTOS
3. QUEUE DE MESSAGES
Une queue de messages (messages queue ou queue) ou boîte aux lettres (mailbox) est un outil
logiciel asynchrone permettant des communications voir synchronisations entre tâches. Il lui est
associé deux files d'attentes, une préservant l'ordre d'arrivée des messages et une seconde préservant
l'ordre d'arrivée des tâches. Les deux appellations sont très rencontrées. A titre indicatif, DSP/BIOS ou
SYS/BIOS le RTOS embarqué sur le DSP TMS320C6xxx de Texas Instruments étudié en deuxième année
parle de ''Mailbox'' contrairement à FreeRTOS qui parle de queue. Nous parlerons donc de préférence
de queues de messages durant cet enseignement.
Une queue de messages (ou file d'attente) contient un nombre fini d'éléments dont la taille est
configurable. Elle est de façon générale régit par le principe de fonctionnement d'une FIFO (First In
First Out). Le premier entré dans la file sera le premier à en sortir. Nous constaterons que FreeRTOS
propose si nécessaire des alternatives à ce fonctionnement. De plus, sachez que FreeRTOS créé les
queues de messages et alloue les ressources mémoire nécessaires dans le Tas.
Une queue de messages peut avoir plusieurs écrivains et plusieurs lecteurs. Cependant, de
façon générale, elles sont utilisées avec des écrivains multiples et un seul lecteur. Les écrivains sont les
tâches pouvant écrire dans une queue de messages. Les lecteurs sont donc celles susceptibles de la
lire. Un élément lu est retiré de la file d'attente. Si un lecteur cherche à lire une queue de messages
vide, il se fait bloquer jusqu'à l'arrivée d'un nouveau message. Pour des tâches de même priorité, ce
sera la première bloquée qui sera la première réveillée (FIFO). FreeRTOS étant un exécutif temps réel,
si une tâche de plus haute priorité se fait bloquer, elle passe en tête de file. Exemple de scénario :
3.1. API de FreeRTOS
Les deux principales fonctions proposées par FreeRTOS sont :
•
•
xQueueSend() ou xQueueSendToBack() : envoi d'une donnée vers une queue de messages à la
suite des éléments déjà présents. Cette fonction n'est bloquante que si la queue de messages
est pleine.
XQueueReceive() : Récupère la donnée en tête d'une queue de messages. L'élément lu est retiré
de la file d'attente. Le second élément passe alors en tête de file. Cette fonction n'est
bloquante que si la queue de messages est vide.
12
SYSTEMES TEMPS REEL
FreeRTOS
Illustrons maintenant ces concepts. Dans l'exemple ci-dessous le noyau travaille en mode
coopératif. Ce scénario présente une application avec deux écrivains et un lecteur :
...
13
SYSTEMES TEMPS REEL
FreeRTOS
FreeRTOS propose également des fonctions permettant de rendre prioritaire des données
envoyées à une queue de messages. Par exemple xQueueSendToFront() écrit une donnée en tête de
file d'attente.
3.2. Timeout
Certaines fonctions pour la gestion de queue de messages et de sémaphores utilisent un
Timeout ou temps mort. Lorsqu'une tâche est bloquée après l'appel de l'une de ces fonctions, celle-ci
se réveillera (passage à l'état prêt) automatiquement après un laps de temps nommé Timeout, même
si l'événement attendu n'est pas arrivé. L'utilisation du Timeout permet de garantir la robustesse d'un
code en forçant par exemple le réveil d'une tâche en attente d'un événement devant être envoyé par
une tâche boguée. Prenons l'exemple de l'API suivante :
portBASE_TYPE xQueueReceive(
xQueueHandle xQueue,
void *pvBuffer,
portTickType xTicksToWait
);
Le paramètre xTicksToWait permet de fixer le Timeout. Sous FreeRTOS, le Timeout est donné
en ticks. Si nous ne souhaitons pas utiliser cette fonctionnalité (Timeout infini), il suffit de passer en
paramètre la macro portMAX_DELAY (définie dans portmacro.h).
14
SYSTEMES TEMPS REEL
FreeRTOS
4. SEMAPHORES
Un Sémaphore est un outil logiciel couramment (mais pas seulement !) utilisé pour la
protection de ressources partagées (variables, périphériques, espaces mémoires ...). Le principe de
fonctionnement des sémaphores est très proche de celui des queues de messages. La preuve en est,
sous FreeRTOS vous ne trouverez aucun fichier source propre aux sémaphores. Les API pour la gestion
des sémaphores ne sont que des macros appelant des fonctions propres aux queues de messages
(queue.c).
4.1. Sémaphore binaire
Un sémaphore binaire peut-être vu comme une variable booléenne associée à une file
d'attente préservant l'ordre d'arrivée des tâches (cf. queues de messages). Un sémaphore binaire Pris
(Take) par une tâche ne peut plus l'être par une autre, ni même par elle même tant qu'il n'est pas
explicitement Vendu (Give). Une tâche cherchant à prendre un sémaphore binaire déjà pris se verra
bloquée (blocked) jusqu'à ce que la ressource soit relâchée. Prenons un exemple de scénario :
...etc
15
SYSTEMES TEMPS REEL
FreeRTOS
Le scénario précédent reflète par exemple une application où 3 tâches de même priorité
cherchent simultanément à envoyer des données via un UART. La ressource partagée est alors l'UART
qui est protégé par un sémaphore binaire. Durant ce laps de temps nous nous trouvons dans une
section critique qui peut cependant être préemptée par le noyau. Les différentes tâches utiliseront
donc l'UART à tour de rôle (exclusion mutuelle) .
4.2. MUTEX
Mutex signifie MUTual EXclusion (ou exclusion mutuelle), il s'agit du concept très rapidement
présenté durant le scénario présenté ci-dessus. Une exclusion mutuelle traduit la notion de protection
de ressources partagées. Sous FreeRTOS, elle peut notamment être réalisée à partir d'un sémaphore
binaire (inversion de priorité) ou d'un mutex (héritage de priorité). Pour FreeRTOS, le principe de
fonctionnement de ces deux outils est exactement le même à ceci près que le Mutex effectue un
héritage de priorité. Illustrons le concept d'héritage de priorité :
●
Héritage de priorité : La tâche Task Low2 vient de prendre une ressource (Mutex) et elle ne la
rendra qu'une fois avoir fini ce pourquoi elle l'a pris. Cependant la tâche Task Low1 est
également prête (état ready), l'ordonnanceur applique donc le round-robin et partage le temps
CPU entre les deux tâches de même priorité.
Imaginons maintenant que la tâche Task High (de priorité supérieure) cherche
également à prendre la ressource (Mutex). Ceci est impossible, le MUTEX ayant déjà été pris et
elle se fait donc bloquer, c'est ce que l'on appel l'inversion de priorité. Une tâche de haute
priorité se fait bloquer par une tâche de plus basse priorité, le système de priorité choisi par le
développeur est inversé. Cependant avec l'héritage de priorité, la tâche Task Low2 hérite
temporairement de la priorité de Task High et pourra donc potentiellement finir de s'exécuter
plus rapidement que sans héritage (plus de round-robin avec la tâche de même priorité). De
façon général, dans un système temps réel une tâche ne doit jamais (ou le moins longtemps
possible !) rester bloquée par une tâche de moindre priorité.
16
SYSTEMES TEMPS REEL
FreeRTOS
4.3. Sémaphore à compteur
Le principe de fonctionnement d'un sémaphore à compteur est identique à celui d'un
sémaphore binaire sauf que la ressource protégée peut maintenant être prise (Take) à plusieurs
reprise. Elle peut être prise soit par la même tâche, soit par une nouvelle. Exemple de sémaphore à 4
jetons :
17
SYSTEMES TEMPS REEL
TRAVAUX PRATIQUES
SYSTEMES TEMPS REEL
Travaux Pratiques
SOMMAIRE
1. MODE COOPERATIF - séance n°1
1.1. Interface de communication
1.2. Mode coopératif
1.3. État bloqué
1.4. Tâche idle
2. MODE PREEMPTIF ET GESTION MEMOIRE - séance n°2
2.1. Mode préemptif
2.2. Gestion mémoire
3. QUEUE DE MESSAGE ET SEMAPHORE - séance n°3
3.1. Queue de Message
3.2. Timeout
3.3. Section critique
3.4. Sémaphore
3.5. Bibliothèque UART avec appels système
4. PROJET - séance n°4 et plus
4.1. Présentation
4.2. Spécifications
APPLICATION RESEAU - facultatif
5. PILE RESEAU MICROCHIP
5.1. Présentation
5.1.a. Pile Réseau Microchip
5.1.b. Berkeley sockets
5.2. Serveur TCP
5.3. Services TCP/IP
5.3.a Serveur UDP
5.3.b Serveur HTTP
6. PROJET RTOS ET PILE RESEAU
7. PORTAGE PILE RESEAU MICROCHIP
7.3. Présentation
7.4. Spécifications
1
SYSTEMES TEMPS REEL
Travaux Pratiques
2
SYSTEMES TEMPS REEL
Travaux Pratiques
1. MODE COOPERATIF
Travail préparatoire
•
1. (0,5pt) Quels états peu prendre une tâche sous FreeRTOS ?
•
2. (1,5pts) Ces états sont-ils les mêmes quelque soit l'OS ou le RTOS utilisé ? Donner un
exemple pour un autre RTOS.
•
3. (0,5pt) Que se passe-t-il sous FreeRTOS lorsqu'aucune tâche, précédemment créée via
xTaskCreate(), ne s'exécute (état running) ?
•
4. (0,5pt) Qu'est-ce qu'un TCB ?
•
5. (1pt) Que trouve-t-on en général dans un TCB (prendre l'exemple de FreeRTOS) ?
3
SYSTEMES TEMPS REEL
Travaux Pratiques
1. MODE COOPERATIF
Travail en séance
1.1. Interface de communication
Avant de commencer à découvrir FreeRTOS, un micro-noyau temps réel libre et open source,
nous allons devoir mettre en place une interface de communication avec l'ordinateur de
développement (ordinateur host). Même à notre époque, l'une des premières interfaces mise en œuvre
lors de développement sur MCU est une communication série asynchrone via UART. La rapidité de mise
en œuvre, la simplicité du protocole et sa robustesse en font sa force. Cet exercice ayant déjà été
réalisé en première année à l'école sur architecture PIC18 de Microchip, le programme de
configuration et de gestion de l'UART sur architecture PIC32 de Microchip vous est donné. Il vous est
seulement demandé de l'éditer, d'en comprendre le fonctionnement tout en réalisant quelques tests
après compilation.
•
Créer un projet uart dans le répertoire rtos/peripherals/uart/explorer16/ ou
rtos/peripherals/uart/pic32maxiweb/ en fonction de la plateforme de développement utilisée.
Ce projet doit inclure les fichiers sources uart.c, main.c présents dans ./src/ et le fichier d'entête uart.h présent dans ./h/
•
Ouvrir un terminal asynchrone de communication côté ordinateur (TeraTerm, PuTTY, minicom,
kermit …) et s'assurer de sa bonne configuration afin d'analyser les données envoyées depuis la
maquette. Prenons l'exemple de TeraTerm :
•
Compiler et interpréter le fonctionnement du programme. Ne pas hésiter à modifier le fichier
main.c afin de bien comprendre le fonctionnement de l'API de gestion de l'UART.
•
Pour information, lors de développement sur processeurs pour l'embarqué, nous utilisons des
convertisseurs USB-serial afin de communiquer avec l'ordinateur de développement. Ces
interfaces nécessitent l'installation de drivers sous Windows et sont nativement reconnus sous
Linux en apparaissant à la racine dans le répertoire /dev sous le nom ttyXXXX (teletypewriter
terminal) :
4
SYSTEMES TEMPS REEL
Travaux Pratiques
1.2. mode coopératif
Nous allons maintenant découvrir pas à pas les principaux services proposés par FreeRTOS.
Dans un premier temps, intéressons-nous au mode coopératif, très peu utilisé pour des problèmes de
robustesse et d'égalité de partage de temps CPU, problèmes que nous illustrerons dès le premier
exercice. En mode coopératif, chaque tâche doit explicitement permettre à une autre tâche de
s'exécuter en effectuant un appel système, sans quoi, aucune autre tâche ne pourra prendre la main.
Nous allons dans un premier temps créer 3 tâches de même priorité. Chaque tâche enverra une chaîne
de caractères à l'ordinateur par liaison série.
•
Créer un projet cooperative dans le répertoire rtos/cooperative/pjct. Ce projet doit inclure les
fichiers sources uart.c, utask.c (user tasks), ktrap.c (kernel trap), main.c présents dans
rtos/cooperative/src et les fichiers d'en-tête uart.h, utask.h, FreeRTOSConfig.h présents dans
rtos/cooperative/h
•
Inclure à votre projet les sources de FreeRTOS sans oublier de configurer vos chaînes de
compilation C et ASM avec les chemins vers les différents répertoires contenant des fichiers
d'en-tête. Ne pas hésiter à s'aider des documents d'annexe.
•
La documentation du noyau est accessible en ligne sur le site officiel de la société proposant
FreeRTOS :
http://www.freertos.org/
5
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Créer 3 tâches de priorité 1. Les fonctions implémentant les tâches se nommeront task1(),
task2() et task3(). Chaque tâche ne fera qu'envoyer une chaîne de caractères à l'ordinateur puis
attendre un délai de quelques centaines de millisecondes via une temporisation logicielle avant
de répéter l'opération. Prenons l'exemple de la tâche 1 :
uartPutS("\r\ntask1\r\n");
// wait few 100ms
int i;
for (i=0; i<4000000; i++);
•
Compléter, compiler et interpréter le fonctionnement du programme en visualisant les données
reçues côté ordinateur.
Pour ce premier exercice, l'analyse du fonctionnement du programme est donnée. Ce travail
sera bien entendu à votre charge pour la totalité des exercices qui suivent :
Les traits pleins apparaissant sur les chronogrammes représentent le code en cours d'exécution
par le CPU. Nous constatons que nous sommes bloqués dans la tâche 3. Du coup, trois questions se
soulèvent :
•
Pourquoi sommes-nous bloqués ? tout simplement car en mode coopératif, la tâche doit
appeler elle même l'ordonnanceur ou une fonction système réalisant un appel du
scheduler.
•
Pourquoi dans la tâche 3 ? Avec FreeRTOS, au démarrage si plusieurs tâches de même
priorité sont susceptibles de prendre la main, c'est la dernière créée qui sera la
première à démarrer. Cette politique est différente en fonction de l'OS rencontré.
•
Dans quel état se trouvent les tâches 1 et 2 ? elles se trouvent à l'état prêt (ready). Elles
sont toutes les deux prêtes à prendre la main si la tâche 3 le leur donne.
6
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Nous allons maintenant forcer des commutations de contexte en appelant l'ordonnanceur.
Dans chaque tâche, à la suite de la temporisation logicielle, appelez la fonction suivante :
taskYIELD();
Vous constaterez que le noyau donne la main à chaque tâche à tour de rôle. Beaucoup d'OS
temps réel légers travaillent ainsi, il s'agit de la technique dîtes du round-robin qui suit le principe de
fonctionnement d'un tourniquet. Chaque tâches de même priorité prêtes ou en court d'exécution
prendra la main à tour de rôle. Le principal avantage de cette technique est de ne nécessiter qu'une
intelligence très réduite au niveau du code du kernel.
Nous venons d'illustrer le principe de la coopération entre tâches ainsi que le principal
problème amené si une boucle infinie (bug) intervient dans le code d'une tâche. Les tâches bloquées
ou prêtes ne peuvent plus prendre la main et votre application tombe !
•
Pour information, durant la totalité de la trame de TP, nous étudierons le fonctionnement de
nos programmes à l'aide de chronogrammes comme ci-dessus. Sachez néanmoins qu'il existe
des outils dédiés, souvent propriétaires et donc payant permettant ce type d'analyses. Prenez
quelques minutes pour visualiser la vidéo présentant les outils de trace proposés par FreeRTOS
(outils payant en fonctions des services demandés) :
http://www.youtube.com/watch?feature=player_embedded&v=WTNc1PwoMG4
7
SYSTEMES TEMPS REEL
Travaux Pratiques
1.3. État bloqué
Intéressons-nous à la fonction bloquante vTaskDelay(). Afin de pouvoir utiliser cette fonction,
ne pas oublier de mettre à 1 la macro INCLUDE_vTaskDelay présente dans le fichier d'en-tête
FreeRTOSConfig.h.
•
Compléter le programme précédent en remplaçant dans la tâche 1 la temporisation logicielle
et taskYIELD() par :
uartPutS("\r\ntask1 delay 3s\r\n");
// task blocked during 3000 ticks
vTaskDelay(3000);
•
Compléter le chronogramme ci-dessous en étant prudent aux quelques pièges pouvant
apparaître. Pour information, 3000 signifie 3000 ticks donc 3 secondes dans notre cas (1 tick =
1ms cf. FreeRTOSConfig.h). Préciser à chaque fois les appels des fonctions taskYIELD() et
vTaskDelay(3000) ainsi que l'état pris par chaque tâche (R = ready et B = blocked) :
•
Remplacer maintenant les temporisations logicielles et taskYIELD() par vTaskDelay(3000) dans
chaque tâche. Compléter le chronogramme suivant et préciser l'état pris par chaque tâche (R =
ready et B = blocked) :
•
Quel code s'exécute lorsque nous nous trouvons dans aucune des 3 tâches ?
8
SYSTEMES TEMPS REEL
Travaux Pratiques
1.4. Tâche idle
Intéressons-nous à la tâche Idle et découvrons comment la détourner afin d'y insérer du code
utilisateur. Par défaut en mode coopératif la tâche Idle ne fait que forcer des commutations de
contexte en appelant la fonction taskYIELD().
•
Mettre à 1 la macro configUSE_IDLE_HOOK présente dans le fichier d'en-tête
FreeRTOSConfig.h.
•
Créer alors une fonction (et non une tâche !) nommée vApplicationIdleHook(). Attention ce
nom est imposé par le système. Cette fonction ne fera qu'envoyer une chaîne de caractères :
/**
* @fn void vApplicationIdleHook( void )
* @brief function called by idle task
*/
void vApplicationIdleHook( void ){
uartPutS("i");
}
•
Tester votre code et compléter le chronogramme ci-dessous :
•
Proposer des cas d'applications et exemples d'utilisation de la tâche Idle. Ne pas hésiter à
s'aider du web et d'exemples de détournement de la tâche Idle sur d'autres noyaux temps réel.
9
SYSTEMES TEMPS REEL
Travaux Pratiques
10
SYSTEMES TEMPS REEL
Travaux Pratiques
2. MODE PREEMPTIF ET GESTION MEMOIRE
Travail préparatoire
•
1. (0,5pt) Quels sont les inconvénients et avantages d'un OS coopératif (aidez-vous du Web) ?
•
2. (0,5pt) Quels sont les inconvénients et avantages d'un OS préemptif (aidez-vous du Web) ?
•
3. (1pt) Que trouve-t-on sur le Tas ?
•
4. (1,5pt) Les stratégies de gestion du tas par FreeRTOS sont implémentées dans les fichiers
heap_1.c, heap_2.c, heap_3.c et heap_4.c présents dans le répertoire
/rtos/FreeRTOS/Source/portable/MemMang de notre arborescence de TP.
•
•
Quelles sont les différences entre les stratégies utilisant heap_1.c ou heap_2.c ?
Quelles sont les différences entre les stratégies utilisant heap_2.c ou heap_3.c ?
•
5. (1pt) Qu'est-ce qu'une pile ou stack et que trouve-t-on sur la pile ?
•
6. (1,5pt) Qu'elle est la taille par défaut de la pile de la tâche Idle dans le cadre de notre trame
de TP ? Expliquez votre démarche pour répondre à cette question.
11
SYSTEMES TEMPS REEL
Travaux Pratiques
2. MODE PREEMPTIF ET GESTION MEMOIRE
Travail en séance
2.1. mode préemptif
A partir de maintenant et jusqu'à la fin de la trame de TP nous travaillerons exclusivement en
mode préemptif (macro configUSE_PREMPTION à 1 dans le fichier FreeRTOSConfig.h). En mode
préemptif, le scheduler prend périodiquement la main, interrompant ainsi une tâche en cours
d'exécution, puis force un ré-ordonnancement. Cette périodicité se nomme tick (timer clock) et est
configurable sous FreeRTOS à travers la macro configTICK_RATE_HZ présente dans FreeRTOSConfig.h.
•
Créer un projet preemptive dans le répertoire rtos/preemptive/pjct. Ce projet doit inclure les
fichiers sources uart.c, utask.c (user tasks), ktrap.c (kernel trap), main.c présents dans
rtos/preemptive/src et les fichiers d'en-tête uart.h, utask.h, FreeRTOSConfig.h présent dans
rtos/preemptive/h
•
Inclure à votre projet les sources de FreeRTOS sans oublier de configurer vos chaînes de
compilation C et ASM avec les chemins vers les différents répertoires contenant des fichiers
d'en-tête. Ne pas hésiter à s'aider des documents d'annexe.
•
Créer 3 tâches, une de priorité 2 et deux de priorité 1. Les fonctions implémentant les tâches
se nommeront respectivement task1(), task2() et task3(). Chaque tâche appellera une fonction
bloquante puis ne fera qu'envoyer une chaîne de caractères à l'ordinateur.
•
Prenons l'exemple des tâche 2 et 3 (exemple de la tâche 2) :
// task blocked during 1000 ticks
uartPutS("\r\ntask2\r\n");
vTaskDelay(1000);
•
La tâche 1 sera bloquée quant-à elle durant 3000 ticks :
// task blocked during 3000 ticks
uartPutS("\r\ntask1\r\n");
vTaskDelay(3000);
12
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Compléter, compiler et interpréter le fonctionnement du programme en visualisant les données
reçues côté ordinateur. Le comportement du programme peut sembler étrange dans un
premier temps, mais s'explique bien entendu très bien !
•
Compléter le chronogramme suivant et préciser l'état pris par chaque tâche (R = ready et B =
blocked). Attention aux pièges :
•
Dans notre cas, la tâche 1 est-elle périodique ?
•
De quoi dépend la périodicité d'une tâche appelant la fonction vTaskDelay()?
•
FreeRTOS propose la fonction xTaskGetTickCount() permettant de récupérer la valeur courante
du tick. Récupérer à chaque réveil de la tâche 1 cette valeur, puis l'envoyer à l'ordinateur
(s'aider de la fonction standard sprintf) :
uartPutS("\r\ntask1 prio, current tick value ");
// get and send current tick value
…
uartPutS("\r\n");
•
Utiliser maintenant la fonction vTaskDelayUntil() puis interpréter le résultat obtenu.
13
SYSTEMES TEMPS REEL
Travaux Pratiques
2.2. Gestion mémoire
La partie qui suit est extrêmement importante et sujette à énormément de bugs et mauvais
développement en milieu industriel, notamment lorsque nous travaillons sur de petits exécutifs temps
réel comme FreeRTOS. Problématique différente sur OS évolué (GNU\Linux, Android …) et processeur
avec MMU (Memory Managment Unit). Sur RTOS, le développeur doit avoir une très bonne gestion et
maîtrise des ressources mémoire utilisées par la chaîne de compilation et le système. Prenons un petit
programme d'exemple et observons le mapping mémoire de données du processeur.
int gbl;
/**
* @fn int main(void)
*/
void main(void){
int lclMain;
xTaskCreate(task, "task", 100, NULL, 1, NULL);
vTaskStartScheduler();
}
/**
* @fn void task(void *pvParameters)
*/
void task(void *pvParameters){
int lclTask;
}
•
Représenter ci-contre un découpage du mapping mémoire en
faisant apparaître : tas de FreeRTOS, pile fonction main, pile de
la tâche, TCB de la tâche
•
Que trouve-t-on dans le reste de la mémoire (hors zones
spécifiées dans la question précédente) ?
•
Où si situe physiquement la chaîne de caractères ''task'' ?
Mettre à jour le schéma ci-contre.
•
Où si situe physiquement la variable globale gbl ? Mettre à jour
le schéma ci-contre.
•
Où si situe physiquement la variable locale lclMain ? Mettre à
jour le schéma ci-contre.
•
Où si situe physiquement la variable locale lclTask ? Mettre à
jour le schéma ci-contre.
14
SYSTEMES TEMPS REEL
Travaux Pratiques
FreeRTOS propose une API de programmation permettant de détecter certaines exceptions du
noyau et d'appeler des fonctions de callback en cas d’occurrence. Le kernel permet notamment de
détecter certains stack overflow (débordement de pile) et heap overflow. Pour information, les stack
overflow font partis des bugs les plus répandus durant des développement sur STR et peuvent être
délicats à mettre au jour dans certains cas. Il vous est très très très fortement conseillé d'implémenter
ce type de détection durant vos phases de développement. Malheureusement, lorsque vous vous
trouvez dans l'une de ces fonctions de callback, il est déjà trop tard !
•
Nous allons maintenant mettre en place les mécanismes de détection de débordement de pile.
Forcer à 1 ou 2 la macro configCHECK_FOR_STACK_OVERFLOW présente dans le fichier
FreeRTOSConfig.h. En fonction de la valeur choisie différentes stratégies de détection de stack
overflow seront appliquées par le kernel :
http://www.freertos.org/Stacks-and-stack-overflow-checking.html
•
Dé-commenter la fonction vApplicationStackOverflowHook présente dans le fichier ktrap.c
(kernel trap).
/**
* @fn void vApplicationStackOverflowHook ...
* @brief kernel hook here if stack overflow detection
*/
void vApplicationStackOverflowHook( xTaskHandle xTask, signed char *pcTaskName ){
uartPutS("\r\nerror stack overflow by ");
uartPutS(pcTaskName);
uartPutS(" \r\n");
while(1); // it's a trap
}
•
Éditer la fonction suivante et l'appeler dans la tâche 1. Interpréter et illustrer le comportement
du programme sur le schéma ci-contre :
/**
* @fn void growStack( void )
* @brief current stack allocation until overflow
*/
void growStack( void ) {
vTaskDelay( 1 );
return growStack();
}
•
Effectuer le même exercice avec la fonction suivante. Interpréter et
illustrer le comportement du programme sur le schéma ci-contre :
void growStack( void ) {
return growStack();
}
15
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Nous allons maintenant mettre en place les mécanismes de détection de débordement de tas.
Forcer à 1 la macro configUSE_MALLOC_FAILED_HOOK présente dans le fichier
FreeRTOSConfig.h. Dé-commenter la fonction vApplicationMallocFailedHook dans le fichier
ktrap.c (kernel trap).
/**
* @fn vApplicationMallocFailedHook()
* @brief kernel hook here if malloc allocation failed detection
*/
void vApplicationMallocFailedHook( void ){
uartPutS("\r\nerror malloc failed \r\n");
// it's a trap
while(1);
}
•
Éditer le code suivant dans la tâche 1. Nous allons créer une tâche depuis
la tâche 1 dont la pile dépasse la taille du tas. Interpréter et illustrer le
comportement du programme sur le schéma ci-contre :
// force heap allocation failed
uartPutS("\r\ntask creation with a too large stack\r\n");
xTaskCreate(task1, "mfailed",
configTOTAL_HEAP_SIZE,
NULL,
tskIDLE_PRIORITY + 2,
NULL);
16
SYSTEMES TEMPS REEL
Travaux Pratiques
17
SYSTEMES TEMPS REEL
Travaux Pratiques
3. QUEUE DE MESSAGE ET SEMAPHORE
Travail préparatoire
•
1. (2pts) Exemple de communication entre 3 tâches via queue de messages :
void prodTask1( void *pvParam ){
int x=1;
void prodTask2( void *pvParam ){
int x=2;
while(1){
if (xQueueSend(xQueue, \
&x, 0) == pdTRUE ){
x += 2;
vTaskDelay( 1 );
}
}
while(1){
if (xQueueSend(xQueue, \
&x, 0) == pdTRUE ){
x += 2;
vTaskDelay( 1 );
}
}
}
}
void consTask( void *pvParam ){
int y;
char sBuffer[20];
while(1){
xQueueReceive(xQueue, &y, \
portMAX_DELAY );
sprintf(sBuffer, ''%d'', y);
uartPuts(sBuffer) ;
}
}
L'application présentée ci-dessus met en œuvre 2 tâches producteur de priorité 1
(prodTask1() et prodTask2()) et une tâche consommateur de priorité 2 (consTask()) sachant que
le kernel fonctionne en mode préemptif. Représenter la séquence d'exécution des tâches à
partir du démarrage de l'application. Notez bien sur le chronogramme les instants clés ainsi que
les appels de fonction associés (R = ready et B = blocked) :
•
2. (0,5pt) Qu'observerait-on au niveau d'un terminal asynchrone côté ordinateur ?
18
SYSTEMES TEMPS REEL
Travaux Pratiques
•
3. (1,5pt) En utilisant 3 sémaphores binaires, proposez une solution permettant de chaîner
l'exécution de 3 tâches en respectant l'ordre suivant : task3, task1, task2, task3, task1, task2,
task3 ...
void task1( void *pvParam ){
void task2( void *pvParam ){
while(1){
}
}
void task3( void *pvParam ){
while(1){
}
}
while(1){
}
}
•
4. (0,5pt) Comment faire pour chaîner 6 tâches ?
•
5. (1,5pt) Compléter le chronogramme ci-dessous de la totalité des prises et ventes de
sémaphores sachant qu'avant le démarrage de l'ordonnanceur le sémaphore 3 (S3) a été vendu
une fois (Give) et les deux autres ont déjà été pris (Take). Ne pas oublier de représenter les
états de chaque tâche (R = ready et B = blocked) :
19
SYSTEMES TEMPS REEL
Travaux Pratiques
3. QUEUE DE MESSAGE ET SEMAPHORE
Travail en séance
3.1. Queue de message
Intéressons-nous maintenant aux outils de communication, synchronisation et protection
proposés par FreeRTOS. Dans cette partie nous allons nous attarder sur les files d'attente (ou queue de
message ou boîte aux lettres ou mail boxes selon le système utilisé) ainsi que sur les sémaphores, qui
ne sont qu'un dérivé sans message des files d'attente. D'ailleurs, sous FreeRTOS il n'existe aucun fichier
source propre aux sémaphores. Les sémaphores sont implémentés et utilisent les mêmes sources que
les files d'attente, seul un fichier d'en-tête existe permettant de wrapper l'API de gestion des
sémaphores vers celle pour le queue (simple skin).
•
Créer un projet queue dans le répertoire rtos/queue/pjct. Ce projet doit inclure les fichiers
sources uart.c, utask.c (user tasks), ktrap.c (kernel trap), main.c présents dans rtos/queue/src et
les fichiers d'en-tête uart.h, utask.h, FreeRTOSConfig.h présent dans rtos/queue/h
•
Inclure à votre projet les sources de FreeRTOS sans oublier de configurer vos chaînes de
compilation C et ASM avec les chemins vers les différents répertoires contenant des fichiers
d'en-tête. Ne pas hésiter à s'aider des documents d'annexe.
•
Créer 3 tâches, la première, périodique de priorité 2 et les deux autres de priorité 1. Les
fonctions implémentant les tâches se nommeront respectivement task1(), task2() et task3().
Chaque tâche ne fera qu'envoyer une chaîne de caractères à l'ordinateur puis se bloquer.
•
La tâche 3 ne fera qu'envoyer un chaîne de caractères côté ordinateur puis se bloquera
durant 1s :
// task blocked during 1000 ticks
vTaskDelay(1000);
uartPutS("\r\ntask3\r\n");
•
La tâche 1 devra être périodique avec un périodicité de 5s. Elle devra récupérer la valeur
courante du tick (sans l'envoyer à l'ordinateur) puis la postera dans une queue de
message pour la tâche 2. La fonction d'écriture dans la file d'attente ne devra pas être
bloquante.
// block periodically current task during 5000 ticks
vTaskDelayUntil( … );
uartPutS("\r\ntask1 prio, message queue post for task2\r\n");
// post current tick value by message queue
// ...
20
SYSTEMES TEMPS REEL
Travaux Pratiques
•
La tâche 2 devra être synchronisée avec la tâche 1 et récupérera la valeur courante du
tick avant de la renvoyer à l'ordinateur via liaison série. Le reste du temps, cette fonction
devra rester bloqué.
// ...
uartPutS(''\r\ntask2, current tick value '');
// print current tick value ...
uartPutS(''\r\n'');
•
Ne pas oublier de créer un queue de message. A vous de fixer la taille de la file d'attente
ainsi que la taille de chaque élément.
•
Compléter, compiler et interpréter le fonctionnement du programme en visualisant les données
reçues côté ordinateur.
•
Compléter le chronogramme ci-dessous (R = ready et B = blocked). Attention aux pièges :
•
Quel est la période d'exécution de la tâche 2 ?
Nous venons ici d'illustrer deux concepts importants dans le domaine des systèmes d'exploitation,
la synchronisation et la communication. La synchronisation permet notamment de synchroniser
l'exécution d'une tâche (par exemple implémentant un traitement long) suite à l'exécution d'une autre
tâche ou d'une ISR (traitement toujours court). La communication inter-tâche consiste quant-à-elle en
la capacité d’effectuer des échanges sécurisés d'informations entre différentes tâches de l'application.
Notion de partage d'information dans des cas d'usage (use case) avec plusieurs écrivains et/ou
plusieurs lecteurs. Un troisième concept important, est l'exclusion mutuelle.
21
SYSTEMES TEMPS REEL
Travaux Pratiques
3.2. Timeout
Certaines fonctions pour la gestion de queue de messages ou de sémaphores utilisent un
Timeout. La notion de timeout ne s'applique qu'à des appels système bloquant. Lorsqu'une tâche est
bloquée, celle-ci se réveillera (passage à l'état prêt) automatiquement après un laps de temps nommé
Timeout, même si l'événement attendu n'est pas arrivé (libération de sémaphore, écriture dans une
file d'attente ...).
•
Forcer le réveil de la tâche 2 toutes les secondes en utilisant le Timeout associé à la fonction
xQueueReceive(). Après avoir testé la nature du réveil de la tâche, envoyer l'une des deux
chaînes de caractères suivantes :
•
Réveil par lecture du message présent dans la queue :
uartPutS(''\r\ntask2, current tick value '');
// print current tick value ...
uartPutS(''\r\n'');
•
Réveil par timeout :
uartPutS(''\r\ntask2, timeout'');
•
Que se passe-t-il si nous forçons à 0 le Timeout d'une fonction bloquante ?
•
Que se passe-t-il si nous forçons à portMAX_DELAY le Timeout d'une fonction bloquante (ainsi
que la macro INCLUDE_vTaskSuspend à 1) ? À quelle valeur théorique de timeout correspond
cet argument ?
•
Peut-on trouver un timeout sur une fonction système non bloquante ?
22
SYSTEMES TEMPS REEL
Travaux Pratiques
3.3. Section Critique
Une section critique est une région de code pour laquelle nous devons garantir sa bonne
exécution et l'intégrité des données à sa sortie. Il s'agira le plus souvent de protéger une ressource
partagée (variable globale, accès à un périphérique …). Une section critique peut-être protégée par
différents outils système :
•
•
•
Sémaphores
Mutex (mutual exclusion)
fonctions dédiées le plus souvent par masquage d'interruption
Vous avez normalement dû constater que les tâches 2 et 3 étant de même priorité, elles se
partagent à tour de rôle l'accès à l'UART. Nous allons donc protéger l'accès à ce périphérique. Cela
signifie qu'une tâche ayant pris cette ressource matérielle la gardera jusqu'à-ce qu'elle ait fini le
traitement en cours.
•
Pour les tâches 2 et 3, placer la fonction d'envoi de données à l'ordinateur dans une section
critique. Utiliser pour cela les macros taskENTER_CRITICAL() et taskEXIT_CRITICAL().
•
Compléter le chronogramme suivant et préciser l'état pris par chaque tâche (R = ready et B =
blocked). Attention aux pièges :
•
Cette implémentation des sections critiques par FreeRTOS est assez dangereuse, notamment
dans l'exemple actuellement présenté, vu que les Ticks (générés par timer matériel) ne sont
plus vus de l'ordonnanceur pendant la durée d'exécution de la section (section longue en
temps d'exécution). Quel problème cela peut-il poser ?
Nous découvrirons par la suite une solution à base de sémaphores plus douce et surtout
interruptible par le kernel. Attention, une section critique doit-être la plus courte possible par principe.
Ne pas oublier qu'elle peut potentiellement être partagée avec d'autres tâches voir ISR's. Les solutions
utilisant le principe de masquage d'interruption sont donc à utiliser pour des sections de code très
courtes en temps d'exécution.
23
SYSTEMES TEMPS REEL
Travaux Pratiques
3.4. Sémaphore
Durant l'exercice précédent vous avez été amené à manipuler des sections critiques en utilisant
les fonctions taskENTER_CRITICAL() et taskEXIT_CRITICAL(). Cependant sous FreeRTOS, ces deux
fonctions sont à manier avec précaution car une région critique ainsi créée ne peut plus être
préemptée par le noyau, ni par les interruptions matérielles en dessous d'un certain niveau de priorité
système (section non interruptible). Ceci peut donc devenir très dangereux en cas de mauvaise
programmation et en fonction de la criticité de l'application. A l'aide de sémaphores, nous allons créer
des sections critiques pouvant être préempté par le système et également interrompues par les
périphériques matériels.
Dans l'exercice qui suit, nous allons réécrire en partie la bibliothèque C de gestion de l'UART et
donc modifier le fichier source uart.c ainsi que le fichier d'en-tête uart.h.
•
retirer les sections critiques précédemment insérées
•
copier les fichiers uart.c et uart.h dans le répertoire du projet actuel et renommer
respectivement les fichiers kuart.c et kuart.h (kernel uart). Modifier dans un premier temps les
sources voire la configuration de la chaîne de compilation afin d'assurer une bonne compilation
du projet modifié.
•
Créer un sémaphore binaire en choisissant un nom adapté au travail en cours puis modifier le
code source de la fonction uartPutS afin de s'assurer qu'une seule tâche à la fois puisse prendre
en main l'UART en transmission.
•
Interpréter le fonctionnement du programme puis compléter le chronogramme suivant en
précisant l'état pris par chaque tâche (R = ready et B = blocked) :
•
Sous FreeRTOS, qu'elle différence existe-t-il entre un sémaphore binaire et un mutex ?
•
Dans notre cas, est-il plus intéressant d'utiliser un sémaphore binaire ou un mutex ? Justifier
votre réponse puis modifier si nécessaire le programme.
24
SYSTEMES TEMPS REEL
Travaux Pratiques
3.5. Bibliothèque UART avec appels système
Nous allons, dans cet ultime exercice, modifier plus profondément les sources de la librairie de
gestion du module UART. Le but étant d'obtenir une bibliothèque optimisée pour travailler avec
FreeRTOS (pas en vitesse d'exécution mais en robustesse et efficacité).
A titre indicatif, beaucoup d'applications font cohabiter bibliothèque réseau (ou stack réseau) et
système d'exploitation. Microchip propose par exemple une librairie réseau libre et open source
indépendante de tout OS, qui n'est donc pas optimisée pour travailler avec notre kernel. FreeRTOS
propose en revanche une librairie réseau implémentant des appels système qui est donc optimisée
pour cohabiter avec le noyau, néanmoins cette stack est un outil propriétaire. Observons rapidement
le coût de certains de ces services en 2014 :
•
Supprimer dans les fichiers /peripherals/kuart/<board-selection>/src/kuart.c et
/peripherals/kuart/<board-selection>/h/kuart.h toute référence à l'utilisation du buffer circulaire
permettant l'échange d'information entre l'ISR de réception de l'UART et la fonction uartGetC.
•
Modifier l'ISR ainsi que la fonction uartGetC en synchronisant par queue de message les réveils
de la fonction d'interruption avec l'appel de la fonction uartGetC. Chaque caractère reçu sera
posté dans la file d'attente et la fonction de réception de caractères implémentera donc un
appel système bloquant en vidant cette queue de message.
•
Une fois ce travail réalisé, modifier le code de la tâche 3 de façon à réceptionner puis renvoyer
des chaînes de caractères envoyées depuis l'ordinateur. S'assurer du bon fonctionnement du
programme. Ultime test, envoyer un fichier texte depuis l'ordinateur et s'assurer de sa bonne
réception et renvoi par l'application embarquée. Le fichier est présent dans le répertoire
rtos/queue/rxfile.txt. Sous TeraTerm, aller dans Fichier → Envoyer un fichier...
// received string
uartGetS(strTmp);
// echo of received string
uartPutS("\r\ntask3, received message : ");
uartPutS(strTmp);
uartPutS("\r\n");
25
SYSTEMES TEMPS REEL
Travaux Pratiques
26
SYSTEMES TEMPS REEL
Travaux Pratiques
4. PROJET
Travail préparatoire
•
1. (0,5pt) Sachant que le capteur de température utilisé est un TC1047, si en sortie du capteur
je mesure 0,85V, quelle température fait-il approximativement au niveau du boîtier ?
•
2. (0,5pt) Sachant que la plage d'acquisition analogique d'entrée de l'ADC 10bits dans le cadre
de notre application est comprise entre Vref+ - Vref- = VCC - 0 = 3,3V, quelle serait la valeur
numérique précédemment obtenue après conversion ?
•
3. (3pts) Comme dans la plupart des projets industriels utilisant des systèmes temps réel, les
premières ébauches de l'environnement multitâches de l'application sont réalisées par
l'architecte système logiciel sur un bout de papier.
En utilisant le formalisme imposé ci-dessous, représenter graphiquement
l'environnement logiciel de votre application ainsi que les différents mécanismes de
synchronisation, communication et protection mis en œuvre.
A titre indicatif, vous pouvez trouver un exemple de réalisation de projet industriel et
d'environnement multitâches proposé par FreeRTOS à partir de leur solution (Real Time Application
Design Tutorial). Le projet est présenté sous plusieurs angles, solution pleinement préemptive,
optimisée au regard de l'usage de la RAM ...
http://www.freertos.org/tutorial/index.html
27
SYSTEMES TEMPS REEL
Travaux Pratiques
4. PROJET
Travail en séance
4.1. Présentation
Il vous est demandé durant ce projet de mettre en place une plateforme d'acquisition de
température communicante avec un ordinateur muni d'un terminal asynchrone de communication. Le
capteur de température instrumenté est un TC1047 présent sur la maquette de développement
explorer 16.
•
Capteur de température
Le capteur de température TC1047 est physiquement connecté à la broche AN4 du MCU qui est
elle même mappée vers une entrée de l'ADC interne du processeur. Nous nous trouvons actuellement
dans un enseignement de découverte et mise œuvre de système temps réel, le travail n'est donc pas
de passer du temps sur la configuration et la gestion de périphérique interne. La gestion du module
ADC sur MCU Microchip a d'ailleurs déjà été vue en première année à l'école. Vous trouverez donc une
librairie C permettant par défaut de lire les valeurs converties présentent sur la broche AN4 du
microcontrôleur. Cette librairie se trouve dans le répertoire rtos/peripherals/adc/<board-selection>/,
charge à vous de la prendre en main.
Si vous le souhaitez durant vos phases de développement, un potentiomètre est également
connecté à la broche AN2 du MCU. Par simple modification des sources de la librairie ADC (cf. librairie)
vous pouvez également effectuer des acquisitions sur cette broche.
28
SYSTEMES TEMPS REEL
Travaux Pratiques
Observons maintenant la réponse tension/température du capteur TC1047. Le schéma
présenté ci-dessous est directement issu de la documentation technique du capteur.
•
Analog to Digital Converter
Le convertisseur analogique numérique de donnée interne aux PIC32MX de Microchip est un
ADC 10bits. Cela implique une plage numérique de conversion comprise entre 0 et 1023 (format entier
non signé). La plage analogique de conversion a quant-à-elle été fixée après configuration entre 0 et
3,3V.
•
Reset logiciel
Afin d'effectuer un reset logiciel du MCU, il vous suffit d'appeler la fonction standard SoftReset()
proposée avec la chaîne de compilation.
•
Light Emitting Diode
La maquette de développement explorer 16 propose 8 LED's utilisateur. Utiliser la LED de
gauche physiquement reliée à la broche RA7 du MCU pour répondre au cahier des charges.
29
SYSTEMES TEMPS REEL
Travaux Pratiques
4.2. Spécifications
L'application devra être multitâches et réalisera les traitements suivants. Création du projet
dans le répertoire rtos/tempserver :
•
une LED servira d'interface utilisateur. Si la température courante est supérieure à 38°C,
la LED restera allumée. Si la température est inférieure, la LED devra clignoter avec une
périodicité de 0,5s.
•
L'application devra réaliser des acquisitions toutes les 20ms et devra toujours garder en
mémoire les 100 dernières mesures converties.
•
L'application devra proposer un interpréteur de commande (console) accessible de tout
ordinateur muni d'un terminal asynchrone (TeraTerm, PuTTY, GTKTerm, minicom,
kermit ...). Cet interpréteur sera relativement simple et ne proposera à l'opérateur qu'un
jeu de 6 commandes :
•
read : retourne la dernière valeur convertie
•
dump : retourne les 100 dernières valeurs converties
•
stream : retourne toutes les 20ms la dernière valeur convertie en effaçant côté
terminal la précédente valeur affichée. Il suffira d'appuyer sur la touche
<Entrée> côté ordinateur pour quitter le mode stream
•
reset : force un reset logiciel de l'application
•
baudrate : modifie le débit de la liaison série pour la communication avec
l'ordinateur
•
help : retourne le menu des commandes supportées par l'application
Au démarrage de l'application, le programme devra proposer l'interface cidessous. L'application sera alors en attente de saisie d'une commande par l'opérateur.
30
SYSTEMES TEMPS REEL
Travaux Pratiques
Exemple d'échanges avec l'application :
•
A partir de maintenant, débrouillez-vous et bon courage !
31
SYSTEMES TEMPS REEL
Travaux Pratiques
32
SYSTEMES TEMPS REEL
Travaux Pratiques
5. PILE RESEAU MICROCHIP - facultatif
5.1. Présentation
Dans cette ultime partie facultative (uniquement pour les curieux et votre CV), nous allons nous
intéresser aux outils et piles réseaux proposées pour le monde des systèmes embarqués. Plusieurs
types de solutions logicielles sont proposés à notre époque sur le marché (fin 2013).
•
Fondeurs (NXP, STmicro ...) ne développant pas de solutions logicielles et passant de des
sociétés tierces (Keil, IAR …). Ces sociétés assurent un support technique sur leurs outils de
développement et bibliothèques fournies. Ces outils sont souvent très onéreux.
•
Fondeurs (Microchip, Texas Instruments, Stmicro, NXP … ) développant et proposant des
solutions logicielles à des prix plus ou moins attractifs (IDE, pile réseaux, pile USB, pile
graphique ...).
•
Solutions libres, le plus souvent open sources, pouvant être multiplateformes. Le support se fait
en ligne par forum interposés, le plus souvent par la communauté d'utilisateurs voir par les
équipes de développeurs et mainteneurs.
Prenons l'exemple de deux sociétés de développement de suites logicielles très rencontrées
dans le domaine de l'embarqué, Keil et IAR (développement sur MCU's, SoC's, DSP's … notamment sur
architectures ARM). Illustrons les services proposés par Keil, notamment le contenu de la librairie
réseau (TCP/IP Networking Suite) :
33
SYSTEMES TEMPS REEL
Travaux Pratiques
A titre indicatif, une grande partie des services proposés sont payants et très coûteux. Une
version complète, au tarif éducation, n'incluant pas les sources des librairies (sources payants) mais
seulement les binaires, avoisine un coût de ~4000-5000€ par poste. Compter ~12000€ afin d'obtenir
une bibliothèque réseau avec fichiers sources. Des tarifs légèrement plus attractifs sont néanmoins
possibles via des licences à jeton.
5.1.a Pile réseau Microchip
Nous allons quant à nous utiliser les outils Microchip (IDE, chaîne de compilation, pile
réseau ...), développés par Microchip, outils gratuits, libres (sous quelques conditions) et open sources.
Il faut savoir que cette stratégie reste très peu rencontrée dans le domaine de l'embarqué, même si de
plus en plus de fondeurs franchissent le pas. Observons par exemple les services proposés par la
bibliothèque réseau Microchip :
Une bibliothèque ou stack réseau propose au développeur une API de fonctions implémentant
les différents services de chaque couche réseau. Cette pile réseau est supportée par grand nombre de
processeurs Microchip (PIC18, PIC24, dsPIC, PIC32) et l'empreinte mémoire de la pile complète
avoisine sur PIC32 les 90Ko, contre 15Ko pour la couche TCP et couches inférieures. Néanmoins, les
couches basses de la pile nécessitent une communication entre matériel et couches logicielles
supérieures (drivers). La stack Microchip ne propose que le support de quelques contrôleurs PHY
externes (implémentent la couche physique) ou contrôleurs Ethernet MAC/PHY externes
(implémentent les couches MAC et physique).
34
SYSTEMES TEMPS REEL
Travaux Pratiques
Prenons l'exemple de notre maquette de développement (PIC32 MAXI WEB de Olimex) :
5.1.b Berkeley sockets
Berkeley sockets ou BSD sockets est une API de programmation C (supportée par d'autres
langages) implémentant des sockets internet et sockets UNIX. De même, cette API très standard reste
très proche de l'API POSIX. Il faut savoir que Microchip propose une API propriétaire (syntaxe et
fonctionnement propre à Microchip), mais supporte également l'API BSD. Il s'agit en fait d'une
redirection d'une API BSD vers leur librairie. Observerons le descriptif succinct des fonctions BSD
proposées :
•
accept : accepte les requêtes de connexion et les place en file d'attente pour une socket en
cours d'écoute.
•
Bind : assigne un numéro de port client ou serveur à une socket
•
closesocket : ferme une socket existante
•
connect : permet à un client de se connecter à un serveur en mode TCP
•
gethostname : retourne le nom du host au système
•
listen : écoute une socket ciblée
•
recv : réception de données ayant été mises en file d'attente pour une socket
•
recvfrom : réception des données ayant été mises en file d'attente pour une socket
•
send : envoie de données vers une socket actuellement connectée
•
socket : création d'une nouvelle socket BSD
35
SYSTEMES TEMPS REEL
Travaux Pratiques
Observons un exemple de machine d'état présentant la connexion entre un client (client TCP
par exemple) et un serveur.
36
SYSTEMES TEMPS REEL
Travaux Pratiques
5.2. Serveur TCP
Nous allons maintenant embarqué, dans notre MCU, une partie des services proposés par la
stack réseau de Microchip et mettre en œuvre un serveur TCP. Le client se trouvera quant-à-lui côté
ordinateur. Les premières phases de validation se feront via Telnet, afin de s'assurer du bon
fonctionnement de notre serveur.
•
Observons rapidement l'arborescence du projet :
•
Créer un projet tcp dans le répertoire network/tcp/pjct. Ce projet doit inclure les fichiers
sources uart.c, main.c, tcp.c. Concernant l'UART, utiliser les fichiers présents dans
../peripherals/uart/<board-selection>/src et le fichier d'en-tête uart.h présent dans
../peripherals/uart/<board-selection>/h
•
Ajouter maintenant à votre projet les sources strictement nécessaires de la pile réseau
Microchip. Pour réaliser cet exercice, loin d'être trivial, s'aider de la documentation technique
de la pile (network/Microchip/Help/TCPIP Stack Help) dans la rubrique Using the stack –
Required files.
37
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Lister ci-dessous le système de fichiers minimal permettant une première implémentation et
compilation de la pile réseau de Microchip :
•
Compléter maintenant le fichier main.c puis s'assurer de la bonne compilation du projet.
S'aider de la documentation technique de la pile (TCPIP Stack Help) dans la rubrique Using the
stack – Main File.
•
Lister ci-dessous les appels de fonctions nécessaires à une bonne configuration et utilisation de
la pile :
38
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Spécifier le travail réalisé par chacune de ces fonctions. Ne pas hésiter à ouvrir les sources de
chaque fonction afin d'en démystifier leur travail !
•
Compiler votre projet et appeler cycliquement la pile. Néanmoins, elle n'implémente pour le
moment aucun service. Nous allons rajouter les services TCP, ICMP (afin de pouvoir réaliser des
ping depuis l'ordinateur) ainsi que l'utilisation de l'API BSD. Pour ce faire, à chaque famille de
contrôleurs réseau supporté par la librairie correspond un fichier d'en-tête de configuration
utilisé pour savoir quels services rajouter à la compilation. Celui nous concernant est
network/Microchip/Configs/TCPIP ETH795.h. Étudions son contenu :
/* Application Level Module Selection
* Uncomment or comment the following lines to enable or
* disabled the following high-level application modules.
*/
//#define STACK_USE_UART
// Application demo using UART for IP address ...
//#define STACK_USE_UART2TCP_BRIDGE
// UART to TCP Bridge application example
//#define STACK_USE_IP_GLEANING
//#define STACK_USE_ICMP_SERVER
// Ping query and response capability
//#define STACK_USE_ICMP_CLIENT
// Ping transmission capability
//#define STACK_USE_HTTP2_SERVER
// New HTTP server with POST, Cookies, Authenticati...
//#define STACK_USE_SSL_SERVER
// SSL server socket support (Requires SW300052)
//#define STACK_USE_SSL_CLIENT
// SSL client socket support (Requires SW300052)
//#define STACK_USE_AUTO_IP
// Dynamic link-layer IP address automatic configur...
//#define STACK_USE_DHCP_CLIENT
// Dynamic Host Configuration Protocol client ...
//#define STACK_USE_DHCP_SERVER
// Single host DHCP server
//#define STACK_USE_FTP_SERVER
// File Transfer Protocol (old)
//#define STACK_USE_SMTP_CLIENT
// Simple Mail Transfer Protocol for sending email
//#define STACK_USE_SNMP_SERVER
// Simple Network Management Protocol ...
//#define STACK_USE_SNMPV3_SERVER
// Simple Network Management Protocol v3 Agent
//#define STACK_USE_TFTP_CLIENT
// Trivial File Transfer Protocol client
//#define STACK_USE_GENERIC_TCP_CLIENT_EXAMPLE
// HTTP Client example in GenericTCPClient.c
//#define STACK_USE_GENERIC_TCP_SERVER_EXAMPLE
// ToUpper server example in
//#define STACK_USE_TELNET_SERVER
// Telnet server
//#define STACK_USE_ANNOUNCE
// Microchip Embedded Ethernet Device ...
//#define STACK_USE_DNS
// Domain Name Service Client for resolving
hostna...
//#define STACK_USE_DNS_SERVER
// Domain Name Service Server for redirection
to...
//#define STACK_USE_NBNS
// NetBIOS Name Service Server for repsonding to …
//#define STACK_USE_REBOOT_SERVER
// Module for resetting this PIC remotely. Primarily...
//#define STACK_USE_SNTP_CLIENT
// Simple Network Time Protocol for obtaining ...
//#define STACK_USE_UDP_PERFORMANCE_TEST // Module for testing UDP TX performance...
//#define STACK_USE_TCP_PERFORMANCE_TEST
// Module for testing TCP TX performance...
//#define STACK_USE_DYNAMICDNS_CLIENT
// Dynamic DNS client updater module
//#define STACK_USE_BERKELEY_API
// Berekely Sockets APIs are available
//#define STACK_USE_ZEROCONF_LINK_LOCAL
// Zeroconf IPv4 Link-Local Addressing
//#define STACK_USE_ZEROCONF_MDNS_SD
// Zeroconf mDNS and mDNS service discovery
En dé-commentant les macros correspondants aux services désirés et en incluant les sources
associés au projet, nous pouvons ainsi rajouter à la compilation les services souhaités. Dé-commenter
les services en fonction de nos besoins (ICMP, TCP et BSD API). Vous constaterez à la compilation que
l'utilisation de l'API BSD nécessite l'ajout d'un fichier source supplémentaire.
39
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Nous sommes maintenant prêt à développer un serveur TCP. Pour ce faire, rien de compliquer,
nous allons utiliser les fichiers d'exemples fournis par Microchip. Compléter le fichier source
tcp.c présent dans notre projet en vous aidant du fichier source de démonstration fourni avec la
stack (network/Microchip/Demo App). Prendre celui qui semble le plus proche du cahier des
charges puis analyser le code ainsi importé.
•
Représenter sous forme graphique (rectangle et flèches) le fonctionnement de la machine
d'état implémentée par le serveur TCP BSD du programme précédent :
•
Quel traitement réalise ce programme ?
•
Avant de tester votre application, réaliser un ping sur l'adresse du serveur et s'assurer de la
bonne réponse du système.
•
Pour tester votre serveur, votre allons établir une communication depuis Telnet. Ouvrir un
client Telnet sur votre machine puis établir une communication avec le serveur embarqué.
•
Modifier le code du serveur afin qu'il réalise un echo vers l'UART des caractères reçus. Voilà,
vous venez d'implémenter un bridge TCP/UART !
40
SYSTEMES TEMPS REEL
Travaux Pratiques
5.3. Services TCP/IP
5.3.a Serveur UDP
•
Sans pour autant le tester, expliquer rigoureusement ci-dessous quelle aurait été votre
démarche afin d'implémenter un serveur UDP utilisant l'API BSD.
5.3.b Serveur HTTP
Un serveur web est une application dont le service de base est de distribuer des fichiers écrits
en HTML. On se propose d'écrire un programme affichant des relevés de températures. Lorsqu'un
utilisateur tape ceci dans la barre d'URL de son navigateur :
http://machine.nomDeDomaine:1999/repertoire/fichier.html
Le navigateur essaye de se connecter à la machine ''machine.nomDedomaine'' et à un
programme écoutant le port 1999. Ensuite, il envoie une série de chaînes de caractères dont la
première est :
''GET /repertoire/fichier.html HTTP/1.1\n\n''
Le serveur renvoie alors une entête HTTP qui est une chaîne de caractères qui précise entre
autre la version du protocole HTTP, un code d’erreur (200 : pas d’erreur) et le type de document
transporté. Par exemple :
''HTTP/1.1 200 OK \n content-type: text/html \n\n"
Ensuite, le serveur envoie le fichier d'un seul bloc, puis ferme la connexion. Si le fichier est
absent, il renvoie la chaîne suivante à la place et ferme la connexion. Le port par défaut des serveurs
web est 80 et non pas 1999.
"http/1.1 404 ERROR\n\n"
•
Écrire un programme qui écoute le port 80 et envoie sur l'UART la première ligne qu'il reçoit.
•
Se connecter au précédent programme via un navigateur web (modifier les paramètres du
proxy : connexion direct à internet). Écrire un programme qui renvoie une page web statique,
quelque soit la requête du navigateur. Attention à bien transmettre l'entête HTTP avant le code
HTML.
41
SYSTEMES TEMPS REEL
Travaux Pratiques
6. PROJET RTOS ET PILE RESEAU
Voilà, nous arrivons à la fin de cet exercice complémentaire. Dernier travail à réaliser, intégrer
au projet réalisé sous FreeRTOS (serveur de température via UART) un serveur TCP. Comme pour le
projet précédent, l'application devra proposer non seulement un shell vers l'UART mais également un
shell TCP sur le port 5151.
Attention, après intégration à votre projet de FreeRTOS et de la pile réseau de Microchip, vous
allez rencontré un problème à la compilation. En effet, la stack et le RTOS utilisent le même timer afin
d'implémenter leurs références internes de comptage (Timer1). Utiliser le fichier TickTimer2.c présent
dans /network/Microchip/TCPIP Stack au lieu de Tick.c. Ce fichier à été modifié par nos soins et ne fait
que reconfigurer le timer 2 ainsi que l'ISR associée au lieu du Timer1 (niveau première année).
42
SYSTEMES TEMPS REEL
Travaux Pratiques
7. PORTAGE PILE RESEAU MICROCHIP
Intéressons-nous à la méthodologie de portage de la pile réseau proposée par Microchip. Cette
méthodologie peut bien entendu être étendue à d'autres stack proposées par Microchip voir d'autres
fondeurs.
•
Télécharger la pile réseau sur le site officiel de Microchip (travail déjà réalisé sur les postes
école). Si vous attaquez un nouveau projet, toujours utiliser (si possible) la dernière version
disponible, le plus souvent plus robuste. Garder toujours les anciennes versions pour soucis de
compatibilité avec vos anciens projets :
www.microchip.com/tcpip
Vous constaterez que Microchip concentre toutes ses librairies évoluées (stack
graphique, USB, SD card …) dans un même outils, appelé MAL (Microchip Application Libraries,
www.microchip.com/mal). A l'installation, vous pouvez choisir de n'installer que la pile réseau.
•
Voici le contenu de l'arborescence de fichiers, si vous ne téléchargez que la pile réseau.
L'installation se fait par défaut à la racine du disque c:\ sous Windows. Ne pas hésiter à aller
observer le contenu de ce système de fichiers sur votre machine de développement :
43
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Si seule la pile réseau nous intéresse, vous pouvons choisir de n'importer vers vos projets que
les sources et fichiers d'en-tête nécessaires. Il faut néanmoins garder l'arborescence imposée
par Microchip par soucis de dépendance des fichiers d'en-tête. Ne pas oublier de rapatrier
également le contenu du répertoire C:\microchip_solutions_v2013-06-15\TCPIP\Demo
App\Configs contenant des headers propres aux contrôleurs externes PHY ou MAC/PHY
supportés par la stack. Observons l'arborescence minimale pour réaliser du développement sur
la pile réseau Microchip :
•
Après importation de la pile vers votre répertoire de projet, nous sommes maintenant prêt à le
créer. Ouvrir MPLABX, créer un nouveau projet et ajouter les fichiers sources strictement
nécessaires à une utilisation minimale de la pile. Pour réaliser cet exercice, loin d'être trivial,
s'aider de la documentation technique de la pile (Help\TCPIP Stack Help) dans la rubrique Using
the stack – Required files.
•
•
•
•
•
•
•
•
main.c
APR.c
Delay.c
Physical layer files ? (vu juste après)
Helper.c
IP.c
StackTsk.c
Tick.c
44
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Observons une capture d'écran de MPLABX à ce niveau là du projet :
•
La partie qui suit peut en revanche être délicate en fonction du contrôleur matériel externe
PHY ou MAC/PHY que vous souhaitez interfacer (composant entre MCU et connecteur RJ45).
•
Si votre contrôleur est supporté par la pile réseau (ENC28J60, ENCX24J600, ETH97J60,
SMSC8700 ...),nous n'avons qu'à rajouter les fichiers sources et headers propres au
contrôleur
•
Si votre contrôleur n'est pas supporté par la pile réseau et n'est pas compatible broche à
broche et registre à registre avec un des contrôleurs supportés, nous avons à
développer nous même les drivers. Ce travail peut prendre plusieurs jours de
développement. Toujours s'inspirer de drivers proches de celui en cours de
développement. Ne jamais réinventer la poudre.
•
Si votre contrôleur n'est pas supporté par la pile réseau mais est compatible broche à
broche et registre à registre avec un des contrôleurs supportés (notre cas sur la
maquette PIC32 MAXI WEB), nous n'avons qu'à rajouter les fichiers sources et headers
propres au contrôleur déjà supporté.
Par exemple, le contrôleur PHY présent sur la maquette est un KS8721B et est
compatible (broche/broche et registre/registre) avec le SMSC8700 qui lui est supporté.
En ajoutant la macro CFG_INCLUDE_PIC32_ETH_SK_ETH795 à la configuration de votre
projet, vous pouvez pré-configurer, avant compilation, l'inclusion de tous les fichiers
d'en-tête nécessaires :
45
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Inclure les fichiers sources propres au contrôleur utilisé. Dans notre cas, nous utiliserons le
contrôleur MAC interne aux PIC32 et un contrôleur PHY externe. Observons le projet après
inclusion des sources nécessaires :
•
Ajouter maintenant les fichiers d'en-tête nécessaires à une bonne compilation du projet. Ces
fichiers sont présents dans les répertoires Microchip/Configs, Microchip/Include et
Microchip/Include/TCPIP Stack. Cette étape n'a pour but que de proposer des raccourcis vers les
headers, ne pas oublier donc de configurer la chaîne de compilation.
46
SYSTEMES TEMPS REEL
Travaux Pratiques
•
Configurer maintenant sous L'IDE les chemins vers les tous les fichiers d'en-tête nécessaires au
projet. Cette étape configure les paths/chemins de votre chaîne de compilation et dépend de
l'arborescence et du système de fichier du projet :
•
Voilà, nous sommes enfin prêt pour une première compilation.
•
Afin de commencer à compléter le fichier main.c, s'aider de l'aide fournie avec la stack (TCPIP
Stack Help) via la rubrique Using the stack – Main File :
47
SYSTEMES TEMPS REEL
Travaux Pratiques
48
SYSTEMES TEMPS REEL
ANNEXES
PhL - 01/10/2018 - Page 1 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Systèmes embarqués et objets connectés
Spécialité Électronique et Physique appliquée
3A Instrumentation avancée
Partie 1 – réseaux IP et protocoles
Ph Lefebvre – 4e trimestre 18
clipart from openclipart.org
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 2 / 20
TP_reseaux3AIA_2018.odt
Séance 1 – Configuration et outils de base des réseaux
1. Travail préliminaire
Pour configurer l'accès réseau d'une machine, il faut d'abord lui associer une adresse IP. Une adresse IP est
constituée de 4 octets dont la notation classique est « décimale pointée » ; par exemple 10.5.7.8.
Ces 4 octets constituent en fait un mot de 32 bits divisé en 2 parties. La partie haute est l'identifiant du réseau
local. La partie basse est l'identifiant de la machine dans ce réseau. Où se situe la limite entre la partie haute et
basse ? C'est une autre information qui s'appelle le « netmask » ou masque de réseau qui le détermine. Le
netmask est également un mot de 32 bits dont tous les bits correspondant à la partie réseau sont à 1, et tous les
autres sont à zéro ; par exemple « 255.255.255.0 ». Un netmask peut aussi être noté à la façon CIDR (Class InterDomain Routing). Dans notre exemple, il sera ainsi noté « /24 » puisqu'il y a 24 bits à 1 dans le mot
255.255.255.0.
L'adresse du réseau est la première adresse disponible (bits de la partie basse à 0).
L'adresse de diffusion (broadcast) est la dernière adresse disponible (bits de la partie basse à 1).
D'autre part, les utilisateurs d'internet connaissent les machines par leur nom, mais pas par leur adresse IP,
comme par exemple « www.ensicaen.fr ». C'est une machine s'appelant le DNS (Domain Name System) qui se
charge de traduire les noms en adresse IP. Une machine doit donc connaître l'adresse IP du DNS.
Enfin, grâce au protocole physique (Ethernet, wifi...) une machine peut dialoguer avec toutes les machines qui
sont situées sur le réseau local. Si elle veut atteindre une machine hors du réseau local, elle doit envoyer son
message à un routeur (appelé aussi passerelle), dont il faut aussi connaître l'adresse IP.
Exemple :
Si l'adresse IP d'une machine est : 10.5.7.8/23
En binaire, son adresse s'écrit :
00001010 . 00000101 . 00000111 . 00001000
son netmask s'écrit :
11111111 . 11111111 . 11111110 . 00000000 == 255.255.254.0
L'adresse réseau est donc :
00001010 . 00000101 . 00000110 . 00000000 == 10.5.6.0
L'adresse de diffusion est donc :
00001010 . 00000101 . 00000111 . 11111111 == 10.5.7.255
Le réseau peut donc contenir 2^9-2 = 510 machines. En effet, l'adresse du réseau et l'adresse de broadcast sont
des adresses réservées.
Exercice :
Soit
1)
2)
3)
4)
le réseau d'adresse 10.6.8.0/22.
La machine 10.6.10.37 fait elle partie de ce réseau ?
Donnez le netmask en notation décimale pointée
Donnez l'adresse de diffusion sur ce réseau.
Combien de machines peuvent-être adressées sur ce réseau ?
2. Configuration réseau
Dans cette partie nous utiliserons les commandes en ligne sous Linux. Ces commandes sont similaires sous
windows.
Ifconfig (ou ipconfig sous windows)
C'est la commande de bas niveau permettant de configurer les interfaces réseaux. Nous ne pouvons pas le faire
car il faut les droits de « Super User ou root » pour le faire. Nous utiliserons donc cette commande seulement pour
afficher les détails.
Entrez /sbin/ifconfig
La liste des interfaces est alors affichée :
– lo correspond à l'interface locale (ou loopback) 127.0.0.1
– eth0 correspond à la première carte ethernet trouvée.
PhL - 01/10/2018 - Page 3 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
L'adresse MAC est l'identifiant de votre carte ethernet. C’est un numéro unique au niveau mondial C'est une
adresse de la couche physique. Elle est notée par 6 nombres hexadécimaux séparés par « : » ou par « - ».
1) Quelle est l'adresse MAC de votre machine ?
2) Comparez à celles de vos voisins. Quels sont les points communs ?
3) Quel est votre adresse IP et son netmask associé ?
4) Pour afficher la table de routage, entrez /sbin/route ­n. La route 0.0.0.0 est la route par défaut. Quelle
est l'adresse IP de la passerelle par défaut ?
ping
Ping permet de tester l'état d'une liaison entre 2 machines. Cette commande donne en plus les temps d'allerretour d'un échange. Elle prend en argument le nom d'une machine ou une adresse IP. Appuyez sur CTRL-C pour
l'arrêter.
Testez un ping sur votre propre adresse IP.
Testez la connexion avec votre voisin.
L'adresse IP 127.0.0.1 est une adresse avec laquelle une machine peut communiquer avec elle même, testez un
ping sur cette adresse.
5) Quels sont les temps d'aller-retour pour ces 3 tests ?
ARP
Losqu'une machine veut envoyer un paquet à une autre machine (sur le même réseau local), elle doit connaître
l'adresse MAC de la carte ethernet destinataire. Pour cela elle utilise le protocole ARP (Address Resolution
Protocol) pour faire l'association adresse IP/adresse MAC.
Faites arp ­a.
Cette commande permet de visualiser le cache ARP qui contient les couples (@IP/@MAC) que la machine a
appris.
Faites une série de ping sur les machines autour de vous et constatez que le cache ARP augmente.
6) Pourquoi le cache ARP se vide-t-il avec le temps ?
Analyse de trames
Pour échanger de l’information, il faut établir des règles de codage, de vitesse, de tour de parole. Ces règles
s’appellent des protocoles. Internet, Ethernet, ARP, HTTP… sont des protocoles.
Les problématiques que gèrent les protocoles ne se situent pas sur le même plan : supervision du réseau, intégrité
des données échangées… On les classe donc par niveau. C’est le modèle OSI (Open System Interconnection) en
couches :
No
nom
Rôle
exemple de protocole
7
Application
Applications s'appuyant sur le réseau : transfert de fichiers,
émulation de terminal, messagerie, partage de fichiers,
web…
telnet, HTTP, mail, NFS, FTP
6
Présentation
Conversion des données numériques propres au réseau
dans leur version finale ou abstraite compréhensible par le
programme. Cette couche est souvent associée à un
langage possédant des règles lexicales (les mots),
syntaxiques (la grammaire) et sémantique (le sens).
XDR, ASN1
UTF-8
MPEG, JPEG
5
Session
Gestion d'une session : ouverture, mots de passe, reprise en Netbios
cas d'erreur, fermeture.
cookies
4
Transport
Multiplexage/démultiplexage des paquets, segmentation,
contrôle de flux, correction des erreurs. Service de bout en
bout.
~TCP
3
Réseau
Assure le routage, l'adressage.
~IP
2
Liaison
Délimitation d'une trame, contrôle et correction d'erreurs,
contrôle de flux, règle d'accès au médium. Service point à
point.
HDLC, ethernet
wifi
1
Physique
Conversion des signaux électriques en bits. Définition des
caractéristiques électriques et mécaniques du support de
transmission.
RS232
ethernet
PhL - 01/10/2018 - Page 4 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Ensuite, les données sont regroupées en paquet. Chaque protocole ne voit pas le format du paquet de la même
manière. Un protocole de transfert de fichiers s’intéresse aux fichiers. Mais l’envoie d’un fichier peut nécessiter de
découper le fichiers en plusieurs paquets.
Les protocoles de haut niveau ont besoin des protocoles de bas niveau. Par exemple pour envoyer un fichier, il
faut le coder, le découper en trame, puis l’acheminer vers de relais en relais et transformer les bits en signaux
électriques.
A l’intérieur du paquet on retrouvera donc des informations de chaque protocole (ou presque).
Les données du protocole supérieure sont encapsulées dans le protocole du niveau d’en dessous.
wireshark
Cet utilitaire permet d’écouter une interface réseau et d’afficher les trames capturées. Lancez « wireshark ».
Pour capturer une trame, cliquer sur Capture puis Interfaces.
Choisir l’interface sur laquelle vous voulez écouter puis « start ».
Pour arrêter la capture cliquez sur l'icône représentée par un cercle rouge et une croix blanche.
La fenêtre est divisée en trois parties.
•
La première partie présente un résumé des trames capturées.
•
La deuxième partie de la fenêtre reprend la trame sélectionnée et la détaille.
•
La troisième et dernière partie est une vision de la trame en codage hexadécimal.
Analyse ARP
Dans une fenêtre de commande lancez un ping sur une machine qui n'est pas listée dans le cache ARP de votre
machine. Arrêtez le, puis relancez ce ping.
7) Combien de trames sont utiles à votre machine pour tester la communication avec une autre machine par
ping ?
8) Combien de trames sont utiles à votre machine pour faire la correspondance adresse MAC / adresse IP ?
9) Décrivez le mécanisme ARP et celui de ping.
Par une série de ping sur des machines dont les adresses MAC ne sont pas dans le cache ARP, capturez une
trame ARP-request et une trame ARP-reply et analysez les avec les formats de trames ci-dessous.
10) Donnez la valeur de tous les champs.
Format de trame Ethernet
Préambule
8 octets
Adresse
destination
6 octets
Adresse
source
6 octets
Types : 0806 (ARP) / 0800 (IP)
Type de
protocole
2 octets
Données
Bourrage
CRC
1 à 1500 oct
Seult. si données < 46
o.
4 o.
PhL - 01/10/2018 - Page 5 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Format d’une trame ARP :
bit 0 à 7
bit 8 à 15
bit 16 à 23
bit 24 à 31
Typed’adresse physique : MAC = 0001 Type d’adresse réseau: IP = 0800
long. @ physique long. @ réseau
Code : demande (0001) / réponse (0002)
adresse physique de l’émetteur ...
... du paquet
Adresse réseau de l’émetteur du ...
... paquet
Adresse physique du ...
... récepteur du paquet
adresse réseau du récepteur du paquet
En analysant la capture d'une trame « echo request » déterminez où se trouvent les adresses MAC destination et
source et les adresses IP sources et destination.
11) Se trouvent-elles toujours au même endroit ?
3. Notions de routage
Voici une vision simplifiée du réseau de l'école.
Ensi privé
192.168.200.0/24
Salles Bât A/E
172.28.X.0/16
Ensi publique
193.49.200.0/24
172.28.0.1
192.168.200.1
PC
172.28.X.Y
192.168.200.Z
routeur 1
193.49.200.1
routeur 2
vers internet
cybele
193.49.200.151
DNS
193.49.200.14
12) Avec wireshark relevez les adresses source/destination MAC et IP d'un échange ping entre votre machine et
celle de votre voisin.
13) Faites de même lors d'un échange de trames ping entre cybele et votre machine.
14) Connectez-vous à cybele en utilisant « ssh » (ssh [email protected]) et le login habituel de
l'école. En utilisant ifconfig, déterminez l'adresse MAC de cybele. Expliquez. Pourquoi l'adresse MAC
destination capturée par wireshark n'est pas celle de cybele ?
15) Donnez une adresse MAC du routeur 2 ?
16) Combien peut-on adresser de machines sur le réseau du bâtiment E ?
traceroute / tracepath (tracert sous window's)
Cette commande permet de connaître le nombre de routeurs séparant deux machines. Par exemple :
tracepath 193.49.200.1 liste les routeurs vous séparant du routeur d'adresse 193.49.200.1.
Pour des raisons de sécurité, cette commande ne fonctionne pas à l'Ensi. Nous allons cependant analyser son
fonctionnement et utiliser la commande ping pour retrouver les informations que cette commande aurait pu nous
donner.
17) Lancez cette commande et analysez à l'aide de wireshark le champ TTL de chaque trame IP envoyée.
Expliquez alors le fonctionnement de tracepath.
18) Quel protocole de couche 4 est utilisé par tracepath ?
Ce protocole étant filtré nous allons utiliser le protocole ICMP. Entrez les commandes suivantes et
expliquez :
ping ­t 1 193.49.200.16
ping ­t 2 193.49.200.16
ping ­t 3 193.49.200.16
19) A l'aide de wireshark donnez le type des trames « Time to live exceeded » ?
20) Connectez vous au site « www.whatismyip.com ». Avec quelle adresse IP êtes-vous « vus » depuis
l'extérieur ?
21) Que fait la commande mtr -n sydney.edu.au Analysez avec wireshark.
22) Ouvrez la carte du réseau Renater sur www.renater.fr , cliquez sur « Réseau », puis « Infrastructure en
Métropole ». Par quel chemin passent les données pour atteindre « www.ensicaen.fr » et « www.univbordeaux.fr » ?
PhL - 01/10/2018 - Page 6 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
23) Consultez « http://submarine-cable-map-2015.telegeography.com/ »
interconnexions mondiales.
pour
vous
faire
une
idée
des
4. La résolution de noms
Lorsqu'une application veut envoyer un message à une autre elle utilise en général le nom de domaine. Par
exemple la machine cybele de l'école possède le nom suivant : cybele.ecole.ensicaen.fr. Cependant, le protocole
IP n'utilise pas les noms de machines pour qu'un paquet arrive à la bonne destination, mais les adresses IP, par
exemple 193.49.200.151.
La machine doit donc pouvoir faire la correspondance entre les noms et les adresses IP.
Plusieurs techniques existent :
– fichier local faisant la correspondance. Ce fichier se trouve souvent dans « etc/hosts »
– Netbios Name Server : service offert sur un réseau local par les machines Windows
– Domain Name server : Le système hiérarchique le plus utilisé.
– Multicast DNS : utilisé par Avahi/zeroconf sur les machines Linux
Interrogation d'un DNS (Domain name System)
Un serveur DNS est une machine qui répond à des requêtes de noms de domaines. Ainsi chaque domaine ou
sous-domaine est géré par une machine qui fait autorité. C'est elle qui connaît toutes les adresses IP de toutes les
machines du domaine. Cette machine est capable aussi d'aller interroger le bon serveur DNS quand elle ne
connaît pas la réponse. Souvent, elle stocke en cache la réponse et devient capable de donner la réponse la
prochaine fois. Cette réponse sera dite « non authoritative ». Les serveurs DNS permettent aussi de fournir
l'adresse IP du serveur de mail (serveur SMTP ) d'un domaine.
?
Exemple d'interrogation DNS : Un serveur de l'école demande l'adresse IP de www.wikipedia.org.
o
6)
rg
8)
91 .wik
.1
98 iped
.1
ia.
74
w
w
.2
w
25
A
DNS wikimedia
91.198.174.4
.
rg
1)
o
w
w
A
5
22
4.
17
a.w
di
8.
19
e
ip
ik
w
.
91
7)
PC1
école
?
DNS org
199.19.56.1
2) org NS ?
4) org.wikipedia NS ?
5) 91.198.174.4
DNS Ensicaen
193.49.200.14
3) 199.19.56.1
DNS root
198.41.0.4
Il y a une phase récursive : le PC demande au serveur DNS de l'ENSICAEN de prendre en charge sa requête et
récupère la réponse à la fin. Le DNS de l'ENSICAEN, lui, résout la requête de manière itérative : interrogation d'un
serveur racine, puis du serveur gérant « org », puis du serveur gérant « org.wikipedia ».
PhL - 01/10/2018 - Page 7 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Arbre de nommage du DNS (vue partielle)
root /
fr
ensicaen
www
com
unicaen
dnsc
org
wikipedia
www
nslookup
Cette commande permet d'interroger le serveur de nom (DNS) et de connaître l'adresse IP d'une machine dont
vous connaissez le nom ou l'inverse.
Tapez nslookup puis entrez le nom ou l'adresse IP à rechercher. Quels sont les adresses IP de
« www.ensicaen.fr » et de « www.dailymotion.fr » ?
23) À quelle machine correspond l'adresse wwwensicaen.ecole.ensicaen.fr ? Qu'en conclure ?
Pour connaître l'adresse IP d'un serveur de courrier électronique correspondant à un domaine tapez :
nslookup ­type=MX
puis tapez le nom de domaine à rechercher.
24) Quel est le serveur de courrier de ensicaen.fr ?
25) Avec wireshark, donnez les noms des protocoles de couche 3 et 4 utilisés par nslookup ?
26) Quel est l'adresse IP du serveur DNS qui a répondu à vos requêtes ?
Une machine peut aussi faire la correspondance « @IP / nom de domaine » par le fichier hosts se situant dans
C:\WINDOWS\system32\drivers\etc . Attention, dans ce cas, le nom n'est défini que pour votre machine, et ne
sera partagé avec personne d'autre...
Rajouter le nom de la machine de votre voisin.
Tester l’ajout avec « ping nom ».
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 8 / 20
TP_reseaux3AIA_2018.odt
Séance 2 – Les services applicatifs simples.
Travail préparatoire – À rendre au début de la séance.
Ex1
Soit le réseau d'adresse 172.16.0.0/12 (pour info, c'est l'un des 3 réseaux privés)
1) découpez ce réseau en 2 réseaux /14 et un /13.
Ex2
Voici un schéma de réseau composé de 3 PC, 2 switches et 1 routeur.
M1 et M2 sont sur le réseau 192.168.13.0/24.
M3 est sur le réseau 10.0.0.0/16.
Les adresses MAC des machines sont les suivantes :
M1 : 00AA00 0000AA
M2 : 00BB00 0000BB
M3 : 00CC00 0000CC
Interface 1 du routeur : 001100 000011
Interface 2 du routeur : 002200 000022
1) Donnez des adresses IP au routeur et aux 3 machines.
2) Quelle est l'adresses IP de la passerelle par défaut de M2 ?
3) Quelle est l'adresses IP de la passerelle par défaut de M3 ?
4) On s'intéresse aux trames échangées entre la machine M1 et M3. La machine M1 envoie 10 octets de
données en UDP sur le port n° 9 de la machine M3. La machine M1 utilise le port 2000. Le TTL est initialisé
à 127 par M1. On rappelle que la taille de l'entête IP est de 20 octets et que l'entête UDP fait 8 octets.
Sachant que la trame est capturée par Wireshark lancé sur M1, donnez la valeur des champs suivants dans
cette trame : adresse MAC source, adresse MAC destination, protocole transporté par ethernet,
adresse IP source, adresse IP destination, protocole transporté par IP, longueur totale IP, TTL, port
source, port destination.
5) La trame est maintenant capturée par Wireshark lancé sur M3, donnez la valeur des champs précédemment
listés.
6) Quels sont les protocoles dans la trame ?
7) Précisez à quelle couche appartient chacun de ces champs.
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 9 / 20
TP_reseaux3AIA_2018.odt
1. Telnet / netcat
Telnet permet de se connecter à distance sur une autre machine en mode texte. C'est un logiciel très simple. Il est
utilisé par exemple pour configurer du matériel à distance. Lorsque vous lancez telnet celui-ci effectue les actions
suivantes :
1) Connexion à la machine distante par des trames TCP de type SYN.
2) Envoie les caractères entrés au clavier et affiche les caractères reçus.
3) Déconnexion par des trames TCP de type FIN.
Depuis les machines libre service de l'Ensicaen il n'est pas possible de se connecter à un serveur de telnet. Nous
allons donc analyser en local le fonctionnement de telnet en le faisant communiquer avec la commande netcat.
Cette dernière est un outil simple qui lit et écrit des données transportées par un réseau en utilisant les protocoles
TCP ou UDP.
Lancez wireshark.
Demandez à votre voisin de taper dans une fenêtre : nc ­l 2014 .
Connectez-vous en tapant : telnet <@IP_du_voisin> 2014
1) Quelles trames viennent d'être échangées (protocoles dans les trames) ?
2) Quels ports source/destination sont utilisés ?
3) Tapez « ABCDE » suivi de la touche <Entrée>. Quelles trames viennent d'être échangées ? (protocoles,
longueur des données transportées par TCP...)
4) Tapez en même temps les touches <ctrl><atl Gr>< ] > suivi de la touche <entrée>.
Tapez « QUIT ».
Quelles trames viennent d'être échangées ?
Nous allons utiliser telnet pour découvrir quelques protocoles applicatifs utilisant le codage ASCII-0. En effet
certains protocoles, qui utilisent IP/TCP, codent les données en mode texte. Puisque telnet affiche tout ce qu'il
reçoit (sauf la partie Ethernet/IP/TCP) nous observerons tout le protocole. Nous pourrons même interagir avec lui
si nous envoyons les bonnes chaînes de caractères.
5) Consulter le fichier «/etc/services » de la machine de TP. Quels services sont associés aux ports 21, 23, 25,
80, et 443 ?
6) Essayez telnet www.ecole.ensicaen.fr. Que se passe-t-il ?
7) Essayez telnet proxy.ensicaen.fr 80 puis tapez « GET / HTTP/1.0 » suivi de 2 fois entrée.
Vous venez d'envoyer une requête HTTP au serveur web de l'école comme le ferait un navigateur. Puisque la
syntaxe de cette requête est correcte, le serveur vous renvoie une réponse HTTP transportant du HTML. HTTP
veut dire Hyper Text Transfer Protocol. C'est le protocole qui permet de dialoguer avec un serveur web. Il est
organisé de la façon suivante :
entête
saut de ligne : '\r\n'
corps
Le corps du message contient soit des options pour la requête, soit la réponse du serveur. Il peut être codé en
HTML, mais aussi transporter des images, de la video...
L'entête contient divers champs comme le type de la requête. Pour une réponse, il décrit sa longueur, son
format...
8) Essayez telnet proxy.ensicaen.fr 3128 puis tapez « GET / HTTP/1.0 » suivi de 2 fois entrée.
9) Comment s'appellent les champs HTTP qui décrivent le type de réponse et la longueur dans l'entête ?
10) Essayez telnet proxy.ensicaen.fr 3128, puis vous taperez GET http://www.google.fr/
HTTP/1.1 suivi de 2 fois entrée. Cette fois, l'application qui tourne sur le port 3128 de la machine
proxy.ensicaen.fr est un proxy. Son rôle est de relayer les requêtes HTTP. Pourquoi votre machine doit-elle
se connecter à un proxy pour pouvoir dialoguer avec google ?
PhL - 01/10/2018 - Page 10 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
2. SSH
SSH est un service de chiffrement des données. Il est basé sur le principe suivant. Il existe des algorithmes de
chiffrement dit asymétrique qui nécessitent 2 clés : 1 pour coder les données et une autre pour les décoder. Si la
clé de codage est suffisamment grande (par exemple 2048 bits) il est difficile de trouver la clé de décodage à
partir de cette première clé. Seul celui qui a généré la première clé connaît la clé de décodage. La clé de codage
est appelée clé publique et peut être distribuée à quiconque.
Cependant, le codage avec une telle clé est très coûteux en temps processeur. SSH utilise en fait cette clé pour
échanger une clé de session pour un algorithme de chiffrement symétrique, moins coûteux, qui sera utilisé pour le
temps du dialogue.
Serveur SSH
connexion
Client SSH
connexion
Envoyer clé publique Kpu
Générer clé de session Ks
Chiffrer Ks avec Kpu et envoyer
Dialogue avec Ks
Dialogue avec Ks
11) Connectez-vous à cybele avec ssh. Avec wireshark retrouvez les phases d'échange de clés. Puis déterminez
combien de trames sont générées pour l'envoi d'un caractère.
12) Combien d'octets sont nécessaires pour coder l'envoi d'un caractère avec ssh ?
13) Est-ce la même clé de codage pour coder un caractère à l'aller et au retour ?
14) Est-ce la même clé de codage pour 2 envois successifs ?
3. Netstat
15) Dans une autre fenêtre tapez « netstat ­antp ». A quoi sert cette commande ?
4. NFS
Network File System est un protocole permettant d'accéder à partir du système de fichier de la machine local à
un répertoire distant, hébergé sur une autre machine. On dit que le répertoire distant « est monté » sur le système
de fichier de la machine. La commande mount permet de visualiser les différents montage (locaux ou distant)
16) Tapez « mount ». A quoi sert cette commande ? Quel répertoire distant est monté ?
17) Copiez un fichier d'un répertoire local vers le répertoire distant ; à l'aide de wireshark, déterminez quels
protocols de couche 3 et 4 sont utilisés.
18) Quel numéro de port utilise NFS ?
FTP (File Transfer Protocol)
Cet outil permet de transférer des fichiers sur une autre machine. FTP est aussi le nom d'un protocole ; celui-là
même qui est parfois utilisé par les navigateurs pour faire du téléchargement de fichiers.
Pour l'utiliser, tapez ftp machine_distante, puis les commandes sont les suivantes :
bin : pour passer en mode de transfert binaire ;
ascii : pour passer en mode de transfert ascii ;
ls : pour lister le répertoire distant ;
cd : pour changer de répertoire à distance ;
put <nom_de_fichier> : pour transférer un fichier vers la machine distante ;
get <nom_de_fichier> : pour copier un fichier de la machine distante vers la machine locale ;
mget et mput : pour transférer plusieurs fichiers ;
mkdir : créer un répertoire ;
!commande (par exemple !ls) permet d'exécuter une commande sur la machine locale, sauf pour le changement
de répertoire où la commande s'appelle lcd ;
help : pour l'aide sur toutes les commandes ;
quit pour quitter.
Le protocole FTP n'étant pas sécurisé, nous ne pourrons pas l'utiliser à l'école. A la place, nous utiliserons sftp qui
chiffre les données avant de les envoyer.
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 11 / 20
TP_reseaux3AIA_2018.odt
5. SFTP (Secure File Transfer Protocol)
SFTP utilise les mêmes commandes que FTP.
Pour l'utiliser, il faut d'abord se connecter sur la machine distante (par exemple cybele) :
sftp [email protected]
Sur votre compte qui est sur cybele, trouvez un fichier assez volumineux (>150 ko).
Rapatriez le sur la machine de TP. (Attention placez vous pour cela dans le répertoire /tmp de la machine local
car votre répertoire de travail est un répertoire « réseau » qui se trouve justement sur cybele !)
19) La commande « pwd » génère-t-elle du trafic réseau ?
20) la commande « lcd /tmp » génère-t-elle du trafic réseau ?
21) Voici ce que génère la commande cd /tmp
Explications :
1. La machine 172.24.107.201 (le client) envoi la commande « ouvrir le répertoire /tmp » à la machine
193.49.200.151 (le serveur). Bien sûr la commande n’apparaît pas en clair;
2. Le serveur envoi qu'il a bien compris la commande
3. Le client accuse réception de la trame n°4 (uniquement au niveauTCP, pas d'infos SSH dans cette trame)
4. Le client envoi la commande « informations sur le répertoire /tmp » au serveur ;
5. Le serveur envoi la réponse ;
6. Le client accuse réception de la trame n°6
22) Avec wireshark, observez le nombre de trames et la taille des trames qu'il faut pour télécharger un fichier de
1 octets, de 3000 octets et de 4500 octets. Attention à lancer la capture juste avant la commande « GET ».
23) Donnez une estimation de l'overhead de SFTP par rapport aux données brutes ?
PhL - 01/10/2018 - Page 12 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Systèmes embarqués et objets connectés
Spécialité Électronique et Physique appliquée
3A Instrumentation avancée
Partie 2
Programmation
Ph Lefebvre – 4e trimestre 18
clipart from openclipart.org
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 13 / 20
TP_reseaux3AIA_2018.odt
1. Introduction
Dans ce TP nous nous intéresserons à la programmation réseau de la carte de démonstration PIC32MaxiWeb.
Un programme de démonstration est fourni sur le site de Olimex. Ce programme permet de montrer les différents
périphériques de la carte.
✔ écran graphique
✔ led, boutons, relais, accélérometre
✔ USB, RS232
✔ Ethernet
C’est évidemment le dernier point qui nous intéresse. Pour la programmation beaucoup de code serait
nécessaire : Pile TCP IP, FreeRTOS. La complexité qui en résultera va être trop importante pour une simple
séance de TP : une vingtaine de fichiers.
A la place, je vous propose de partir du programme de démonstration et de l’adapter à notre usage. Le but de ce
TP est de :
✔ programmer un serveur et un client TCP/IP sous windows avec CodeBlocks pour se familiariser avec la
programmation réseau et les sockets.
✔ programmer un client TCP/IP pour récupérer les données acquises par le programme de démonstration :
température, position du potentiomètre, accélérometre…
✔ programmer un client TCP/IP capable de dialoguer avec le programme de démonstration et de faire
commuter les relais ou allumer les led… On vous l’avait déjà dit en première année, le plus dur c’est
d’allumer une led
PhL - 01/10/2018 - Page 14 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
Programmation client/serveur en langage C
1. Présentation de l'API socket
Lors d'une communication sur Internet, il faut tout d'abord connaître le numéro de port de l'application destination
et l'adresse IP de la machine hébergeant l'application. Ensuite il faut connaître son mode de transmission qui peut
être en mode connecté (TCP) ou non (UDP). Les données ainsi envoyées sont donc encapsulées par différents
protocoles dont il faut correctement remplir les différents champs. Nous utiliserons pour cela une bibliothèque de
fonctions appelée API Socket (Application Programming Interface). Cette API est très populaire et se retrouve sur
tous les systèmes d'exploitation.
Le schéma ci-dessous récapitule les différentes phases et les différents appels de ces fonctions en mode
connecté. Dans ce mode, une fois la connexion entre le serveur et le client établie, il n'y a plus besoin de préciser
l'adresse de destinataire des messages. Au contraire, en mode non-connecté, chaque message peut venir d'un
émetteur différent et chaque destinataire peut être différent.
socket ()
bind()
L'API socket en
mode connecté
TCP
socket ()
listen()
accept()
connect()
recv()
send()
send()
recv()
shutdown()
shutdown()
(OS)
SERVEUR
socket ()
bind()
(OS)
socket ()
L'API socket en
mode non
connecté UDP
sendto()
recvfrom()
recvfrom()
sendto()
close()
close()
(OS)
SERVEUR
CLIENT
(OS)
CLIENT
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 15 / 20
TP_reseaux3AIA_2018.odt
Voici un résumé de ces fonctions. Certaines ne s'utilisent que dans le mode connecté et d'autres dans les 2
modes.
En UDP et TCP :
int socket(int domain, int type, int protocol);
but : prévenir le système d'exploitation (OS) qu'une communication va être établie.
return : la socket, qui est le descripteur de la communication ou -1 en cas d'erreur ;
domain : le type de socket. Pour Internet : AF_INET ;
type : SOCK_STREAM si communication en mode connecté et SOCK_DGRAM en mode non connecté ;
protocol : le numéro de protocole transporté par IP tel que définis dans la trame. cf. /etc/protocols.
int bind(int sockfd, struct sockaddr *addr, int addrlen);
but : lier le programme serveur à un numéro de port de la machine.
return : -1 en cas d'erreur, par exemple si le numéro de port est déjà affecté à un autre programme.
sockfd : la socket. Celle-ci sera alors destinée à attendre (socket d'écoute) les nouvelles connexions;
addr : structure d'adresse contenant le numéro de port et l'adresse IP de l'interface (ethernet, wifi...);
addrlen : la taille de la structure d'adresse.
in_addr_t inet_addr(char *cp);
but : converti une chaine de caractères contenant une adresse IP en adresse IP binaire.
return : l'adresse IP dans le type spécifié pour le champ (union) sin_addr de la structure sockaddr_in ;
cp : l'adresse IP en ascii.
short htons(short hostshort);
but : converti un mot de 16 bits en un autre de 16 bits de manière à ce que les bits soient rangés dans le bonne
ordre tel que défini dans la trame IP (big endian : l'octet de poids fort est à l'adresse mémoire la plus faible). Dans
le cas d'une architecture Intel, la mémoire est organisée en little endian.
return : le mot de 16 bits en big endian. Utilisé pour convertir le numéro de port et le ranger dans le champ
sin_port de la structure sockaddr_in.
hostshort : le mot de 16 bits à convertir.
int close(int sockfd);
but : libérer les ressources.
return : -1 en cas d'erreur ;
sockfd : la socket ;
En TCP, uniquement :
int listen(int sockfd, int backlog);
but : autoriser l'OS à mettre en attente des communications que le programme n'a pas le temps de gérer.
return : -1 en cas d'erreur ;
sockfd : la socket ;
backlog : le nombre maximum de communications en attente.
int accept(int sockfd, struct sockaddr *addr, int *addrlen);
but : attendre une connexion venant d'un client.
return : une nouvelle socket permettant de dialoguer avec le client ou -1 en cas d'erreur ;
sockfd : la socket d'écoute ;
addr : structure d'adresse qui contiendra après l'appel le numéro de port et l'adresse IP du client;
addrlen : contiendra la taille de la structure d'adresse.
int recv(int sockfd, void *buf, int len, int flags);
but : permet d'attendre la réception d'un paquet.
return : la longueur en octet du paquet reçu ou -1 en cas d'erreur ;
sockfd : la socket de dialogue;
buf : le tableau d'octets reçus ;
len : la taille maximum du tableau. C'est la taille allouée en mémoire ;
flags : permet de modifier le comportement de la fonction. on mettra 0 (comportement par défaut) dans notre cas.
int send(int sockfd, void *buf, int len, int flags);
but : envoie un paquet.
return : la longueur du paquet réellement envoyé ou -1 en cas d'erreur ;
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 16 / 20
TP_reseaux3AIA_2018.odt
sockfd : la socket de dialogue ;
buf : le paquet d'octets envoyés ;
len : la taille du paquet ;
flags : permet de modifier le comportement de la fonction. on mettra 0 (comportement par défaut) dans notre cas.
int connect(int sockfd, struct sockaddr *addr, int addrlen);
but : Permet à un cleint de se connecter à un serveur.
return : -1 en cas d'erreur ;
sockfd : la socket, initialisée par socket() ;
addr : structure d'adresse contenant le numéro de port et l'adresse IP du serveur auquel se connecter ;
addrlen : la taille de la structure d'adresse.
int shutdown(int sockfd, int how);
but : fermer une connexion TCP, en lecture, écriture ou dans les 2 sens.
return : -1 en cas d'erreur ;
sockfd : la socket ;
how : la valeur sera SHUT_RDWR pour fermer les 2 sens de la connexion.
En UDP, uniquement :
int recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr,
int *addrlen);
int sendto(int sockfd, void *buf, int len, int flags, const struct sockaddr
*dest_addr, int addrlen);
2. Programmation de clients/serveurs TCP simples avec Code Blocks
Dans l’environnement Windows, il faut ajouter quelques fonctions supplémentaires pour initialiser l'API socket :
WSAStartup( ) et WSACleanup ( ) dont un programme donné ci-dessous illustre l’utilisation.
Nous utiliserons CodeBlocks, et vous trouverez en annexe un tutoriel sur cet IDE.
Lors de l’utilisation des sockets, il faut ajouter la bibliothèque libws2_32.a qui contient les fonctions de gestion des
sockets.
Pour cela, aller cliquer « Project → Build Option... → Linker settings » puis cliquer sur « Debug » et « Add »
puis parcourir le répertoire d'installation de codeBlocks pour ajouter libws2_32.a
Ce fichier se trouvera probablement dans :
C:\Program Files (x86)\CodeBlocks\MinGW\lib\libws2_32.a
Cliquer maintenant sur« Release » et refaire de même.
Vous trouverez ci-dessous (et sur la plateforme ) un programme exemple. Ce programme est un serveur d'écho. Il
renvoie au client ce que ce dernier lui envoie.
1. Tester le programme en l’exécutant, puis en lançant teraterm, et sélectionner
service : « other»
host : « 127.0.0.1 »
port : « 3000 »
puis entrer des mots sur teraterm qui s'afficheront côté serveur et côté client.
2. Analysez son fonctionnement avec wireshark et dites à quelle fonction correspond quelle trame. Faire le
diagramme des séquences des paquets TCP/IP échangés entre le serveur et le client.
Remarque : Lors d'une communication locale, le CRC est non calculé ce qui fait que wireshark a
l'impression que la trame est erronée.
3. Testez le programme entre binômes voisins en leur demandant leur adresse ip et remplacer le champ
host de teraterm par cette adresse IP.
4. Modifier le programme serveur de façon à ce qu'il renvoie le texte reçu transformé en majuscule. Vous
pourrez utiliser la fonction « char toupper(char c) » qui transforme un caractère en son correspondant en
majuscule.
5. Écrire le programme client correspondant. Aidez-vous du programme serveur. Les fonctions listen, accept
et bind seront disparaîtront et le programme utilisera la fonction connect. Une seule socket sera
nécessaire pour le client. Il n’y aura plus de socket sd.
PhL - 01/10/2018 - Page 17 / 20
TP_reseaux3AIA_2018.odt
3A – EPA – IA
TP réseaux
// @TITLE : Serveur d'echo sur le port 3000 ­ VERSION WINDOWS
// @BRIEF : Répète ce qu'il reçoit et l'affiche. La connexion s'arrete après réception de bye.
// @AUTHOR : Ph Lefebvre ­ ENSI de Caen
#include <errno.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define PAQUET_LEN 64
int main( int argc, char **argv) {
int er, lgr;
int s;
int sd;
char paquet[PAQUET_LEN];
// biblio des erreurs
// bibliothèque socket
// biblio pour les E/S.
// gestion des erreurs
// socket d'ecoute du port
// socket de dialogue avec le client.
// paquet recu / envoye
struct sockaddr_in adTo, adFrom;
// adresse au format internet
int ladd=sizeof (struct sockaddr_in);
int port = 3000 ;
// longueur de l'adresse de reception
// port de connexion
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData); // préparation de la bibliothèque socket
/* On ouvre la socket
Internet en mode connecte. 6 est le numéro de TCP , cf. le fichier
/etc/protocols*/
if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
perror("\nERREUR socket\n"); exit(­1);
}
adTo.sin_family = AF_INET;
// adresses de type internet
adTo.sin_port = htons (port);
// numero de port du serveur
adTo.sin_addr.s_addr = INADDR_ANY;
// accepte les connexions
ethernet, wifi...
de
n'importe
quelle
interface
/* On attache la socket au port d'écoute */
er = bind (s, (struct sockaddr *) &adTo, sizeof (struct sockaddr_in));
if (er < 0) {
perror ("bind : "); exit(­1);
}
/* On fixe le nombre maximum de clients simultanes. Ici 1 seul*/
er = listen (s, 1);
if (er < 0) {
perror ("listen : "); exit(­1);
}
sd = accept( s, (struct sockaddr *) &adFrom, &ladd);
/* attente d'une connexion. La fonction
accept est boquante et crée une socket de dialogue si un client se connecte.*/
printf ("1 client !\n");
do {
lgr = recv( sd, paquet, PAQUET_LEN, 0 );
// on lit au maximum PAQUET_LEN octets venant du
client.
if (lgr == 0 ) {printf("Deconnexion par le client !\n\n") ; exit(0) ;}
if (lgr < 0 ) {perror ("pb recv") ; exit(­1) ;}
paquet[lgr]= '\0';
// le paquet reçu n'est pas une
chaîne de caractères => ajout de "\0" à la fin
printf ("paquet de longueur %d reçu : %s\n",lgr,paquet);
send (sd, paquet, lgr, 0);
// réémission du paquet recu.
}
while ( (strncmp ((char *)paquet, "bye", 3)));
// on compare les 3 premiers octets reçus a "bye"
printf (" Mon client s'est deconnecte.\n");
close (sd);
// fermeture de la socket de dialogue
close (s);
// fermeture de la socket d'écoute
WSACleanup();
// on libère les ressources windows utilisées par les sokets
return(0) ;
}
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 18 / 20
TP_reseaux3AIA_2018.odt
3. Interface avec la carte PIC32MaxiWeb
Veuillez télécharger le programme de démonstration :
https://www.olimex.com/Products/PIC/Development/PIC32-MAXI-WEB/
puis cliquer sur DemoSoft PIC32-MAXI-WEB v1.03 for MPLABX 1.80/MPLAB 8.91 and XC32 1.21
Ouvrir le projet MainProgram avec MplabX
Compilez-le et constatez qu’il manque beaucoup de bibliothèques.
Pour les ajouter, ouvrez les projets :
AdcServer
FreeRTOS
Graphics_lib
Sdcard_lib
TCPIP stack_lib
Et compilez-les. Enfin recompiler MainProgram et télécharger le sur la maquette.
Remarques, vous pouvez aussi directement charger le binaire PIC32-MAXI-WEB demo 1.03 Prebuilt.hex
Connectez à la maquette un câble RS232 et un câble RJ45
Lancez teraterm et régler le port série à 115 kbps.
Le programme a besoin d’un serveur DHCP pour avoir une adresse IP. Télécharger à partir de la plateforme
l’archive dhcpSever_win.zip. Cette archive contient le logiciel tftpd qui, comme son nom ne l’indique pas, propose
un serveur DHCP. Vous pouvez retrouver le site d’origine sur http://tftpd32.jounin.net/
Double-cliquer sur le fichier tftpd64.exe. Puis cliquer sur l’onglet « DHCP server ». Régler les champs
adresse IP : 172.24.121.230
netmask : 255.255.0.0
pool size : 5
Ces adresses sont compatibles avec celles des PC de la salle 121 (adaptez si nécessaire). Attention à n’avoir
qu’une carte Olimex sur le réseau local car celles-ci auront la même adresse MAC. Si besoin, changer
l’adresse MAC dans le code source.
La maquette devrait afficher ceci :
Chaque changement d’adresse IP de la board est notifié sur Teraterm.
Quelle adresse est récupérée par votre carte?
Lancer wireshark. et capturer ce que votre carte envoie. Pour plus de faciliter, débrancher le PC du réseau de
l’école afin de n’avoir que les trames échangées entre le PC et la carte.
Supposons que votre carte ait l’adresse 172.24.121.231. Ouvrir un navigateur et taper dans l’URL
« http://172.24.121.231/ ».
Arrêter la capture Wireshark et cliquer sur la première trame TCP-SYN é »mise par votre PC vers votre carte.
sélectionner Analyse → Follow TCP stream.
Cette fonctionnalité de Wireshark permet de suivre le flux des caractères échangés entre les 2 entités (PC et
carte).
1) Quels sont les protocoles utilisés par le navigateur pour interroger le serveur web de la carte ?
2) Quel port utilise le serveur web de la carte ?
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 19 / 20
TP_reseaux3AIA_2018.odt
3) Quelle chaîne de caractère le navigateur envoie-t-il pour récupérer la page d’accueil ?
4) Quelles chaînes envoie-t-il ensuite pour l’actualisation ? Pourquoi fait-il cela ? A quel rythme ?
5) quel est le résultat ?
6) Allumez par le navigateur la led 0. Quelle chaîne est envoyée pour allumer la led0 ?
Nous allons maintenant écrire un client côté PC qui enverra une chaîne de caractères (cf. plus loin), attendra la
réponse, l’affichera, puis fermera la connexion (utilisation de shutdown).
Pour recevoir la réponse on prévoira un buffer d’au moins 2000 caractères.
Nous ferons 3 tests, avec 3 chaines différentes :
"GET / HTTP/1.1\r\nHost : 172.24.121.231\r\n\r\n"
"GET /status.xml HTTP/1.1\r\nHost : 172.24.121.231\r\n\r\n"
"GET /leds.cgi?led=0 HTTP/1.1\r\nHost : 172.24.121.231\r\n\r\n"
Essayez maintenant de déclencher 10 fois un relais avec un intervalle de 1 seconde. Attention, la fonction Sleep
de windows (avec une majuscule) prend un entier qui représente le temps d’attente en milliseconde.
Si vous avez du temps, regardez le code source du programme de la carte.
Quelle est la priorité de la tâche TCPIP ?
Quel est le temps alloué aux autres tâches ?
4. Tutoriel programmation C sous Code Blocks
Installation de code Blocks sous windows
Aller sur :
www.codeblocks.org/downloads
Puis clicker sur « Download the binary release »
Puis télécharger codeblocks-17.12mingw-setup.exe
Cette version n'est peut-être plus disponible. Choisissez la dernière version « mingw » car elle permet
d'être au plus près des outils gnu pour Linux : compilateur gcc et debugger gdb.
Exécuter ce programme, suivez les instructions, et laissez les options par défaut.
Notre premier programme
Lancez codeBlocks
clickez sur « File → New Project »
puis double-cliqez sur « Console Application »
puis « Next »
puis choisir « C » puis « Next »
puis choisir un nom à votre projet et choisir le répertoire où il sera sauvegarder. Puis cliquer sur « Next »
Choisissez « GNU GCC Compiler » pour le champ « compiler ».
Laissez les cases « create Debug » et « create Release » cochées.
Cliquer sur « Finish »
Dans l'onglet « Projects » (sur la gauche de l'écran ) double-cliquer sur « sources », puis sur « main.c ».
Pour exécuter l'exemple, juste cliquer sur le triangle vert
Débogage
Pour Débugger avec code Blocks, il faut préciser que l'on utilise GDB :
Sur la barre de menu, cliquer sur « settings → Debugger » puis double-cliquer sur GDB/CDB puis sur default.
Dans le champs « Executable Path » parcourez vos dossiers afin de trouver le fichier « gdb32.exe » qui se trouve
très probablement dans :
« C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb32.exe »
Puis cliquer sur « GDB » et enfin « OK »
3A – EPA – IA
TP réseaux
PhL - 01/10/2018 - Page 20 / 20
TP_reseaux3AIA_2018.odt
Pour mettre un point d’arrêt sur une ligne du code source: faites click droit sur le numéro de la ligne puis « add
breakpoint ».
Pour exécuter en mode déboggage, cliquer sur le triangle rouge :
A côté vous trouverez les boutons pour :
–
–
–
–
debugger jusqu'à une certaine ligne
exécuter une instruction
entrer dans le code d'une fonction
…
Pour voir les variables, cliquer sur « Debug → Debugging windows → Watches »
2
Introduction à LoRa
SEDIVER
Formation intra LoRa
Applications et marchés
4
 Alternative aux réseaux cellulaires
pour communication M2M
LPWAN = LowPower WAN (Wide Area Network)
• Réseau
• Sans fil
• Spécialisé sur des communications
• Bas débit
• Longue portée
• Basse consommation
LPWAN - Définition
3
• Sécurité et secours : analyse de présence en zones
dangereuses/interdites, présence de liquides dangereux, niveau
de radiation, détection de substances explosives, …
• Commerce: contrôle de la SupplyChain, rotation de produits en
rayon, …
• Logistique: suivi des conditions de transport, localisation de colis,
traçabilité de flotte, …
• Contrôle industriel : suivi de machines, état des équipements,
qualité de l’air intérieur, suivi de la température, localisation
d’équipements/produits en intérieur, …
• Smart Agriculture : suivi des vignes, suivi des serres, contrôle
irrigation des golfs, station météorologique, compost,
trackingd’animaux, …
Applications et marchés
6
• Smart Cities: parking intelligent, détection des personnes, gestion
du trafic, gestion de l’éclairage public, gestion des ordures
ménagères, affichage public, …
• Smart Environnement : détection d’incendies, pollution de l’air,
niveau d’enneigement, prévention des avalanches, détection des
tremblements de terres, …
• Smart Water : monitoring d’eau potable, détection de
contaminations chimiques, suivi des piscines, détection des
fuites, suivi des crues, …
• Smart metering/smart Grid: compteurs intelligents
électrique/eau/gaz, mesure de niveaux, suivi d’installations
photovoltaïques, calcul de stock dans des silos, …
• Tracking: véhicules, vélos, objets de valeurs, animaux, personnes
Applications et marchés
5
Positionnement du LoRa
8
• Fermes Animalières Intelligentes : traçabilité du pâturage, suivi
du niveau de gaz toxique, suivi du développement des animaux,
culture hydroponique…
• Domotique et Bâtiments Intelligents : utilisation de l’eau et de
l’électricité, contrôle à distance, détection d’intrusion, détection
de fumée, surveillance de biens précieux, …
• eSanté: détection de chutes, stockage de médicaments, suivi
sportif, surveillance des patients, radiation ultraviolet, …
Applications et marchés
7
1
0
LoRa – Modèle OSI, classe device
Texte Verdana cyan
Texte Verdana gris
Texte Verdana bleu
Comparatif des technos LPWAN
9
1
2
LoRa – Fragmentation en fréquence
Texte Verdana cyan
Texte Verdana gris
Texte Verdana bleu
LoRa – Architecture réseau
1
1
Pour améliorer le débit sur canal à SNR fixe
 augmenter la bande passante
Pour compenser le SNR d’un signal dégradé
 augmenter la bande passante
Théorème de Shanon Hartley :
LoRa – Etalement de spectre
1
4
Modulation propriétaire Semtech :
• A étalement de spectre
• Dérivée du CSS (Chirp Spread Spectrum)
• Sur une bande passante fixe
• Proposant un débit variable (adaptatif)
LoRa - Modulation
1
3
Avantages:
­Robuste aux interférences
­Robuste au multipath, fading & doppler
­Basse consommation
­Simple à implémenter
LoRa – Modulation par chirp
1
6
LoRa – Modulation / démodulation
par étalement de spectre
1
5
Code de
correction
d’erreur
1
8
Spreading factor (SF)
Découpage
en chip
Bandwidth (BW)
Modulation
sur chirp
Si CR  => Overhead  => Time on Air 
LoRa – Influence de la correction
d’erreur
Signal
LoRa – étapes de modulation
1
7
Le fonctionnement en bande 868MHz impose un duty cycle de 1%
=> Le Spreading Factor et la bande passante ont un impact fort sur
la qualité de service
LoRa – Contraintes et limitations
2
0
➔ Bande passante adaptative
➔Modulation à enveloppe constante
➔Robuste aux interférences
➔Robuste au multipath et au fading
➔Résistant à l’effet doppler
➔Longue portée
➔Grande capacité réseau
➔Possibilité de géolocalisation
LoRa – Avantages de la modulation
1
9
2
2
3 éléments:
• Preamble = Préambule (longueur variable)
• Header = Entête (optionnel)  longueur, EC rate, usage CRC
• Payload = Données
LoRaWAN – Format de trame
Canaux par défaut:
Les dispositifs peuvent transmettre sur tous les canaux disponibles
avec tous les débits disponibles, en respectant:
• Changement pseudo­random de canal de transmission pour
chaque envoi
• Respect du duty­cycle maximum (régulation locale)
• Respect de la durée de transmission (régulation locale)
LoRa – Règle pour la couche PHY
2
1
Texte Verdana cyan
Texte Verdana gris
Texte Verdana bleu
LoRaWAN – Architecture réseau
2
4
LoRaWAN – Débits standards
2
3
•
•
DevEUI (identifiant unique pour chaque node, géré par IEEE)
AppEUI (Identifiant de l’application, géré par l’intégrateur)
NwkSKey (Network Session Key
AppSKey (Application Session Key, clé AES 128 bits unique pour chaque node)
DevAddr (Device Address, adresse utilisée par le device après le join)
•
•
•
DevEUI
AppEUI
AppKey
OTAA (Over The Air Activation)
• Utilisé principalement pour les réseaux publiques, « négociation » des clés
NwkSKey, AppSKey et attribution du DevAddr lors de la phase de join request
(envoi DevEUI, AppEUI, et MIC = hash de la clé privé)
• Informations de connexion entrés côté capteur et côté réseau:
•
•
•
•
•
ABP (Activation By Personalization)
• Utilisé principalement pour les réseau privés, pas de négociation
• Informations de connexion entrés côté capteur et côté réseau:
2 possibilités de Join:
LoRaWAN – Accostage réseau
2
6
Role essentiel :
• Gestion du réseau
• Filtrage des paquets redondants
• Gestion de la Sécurité
• Gestion des acquittements via la meilleure gateway
• Adaptive Data Rate
• Etc…
LoRaWAN – Network Server
2
5
 2 fenêtres d’écoute peuvent être ouverte par le device :
• Rx1 1s ou 5s après l’envoi de la trame
• Même fréquence que le uplink
• Débit selon le dédit du uplink
• Rx2 2s ou 6s après l’envoi de la trame (toujours Rx1+1s)
• Fréquence fixe configurable
• Débit fixe configurable
LoRaWAN – Downlink
2
8
LoRaWAN – Accostage réseau OTAA
2
7
Encryption AES 128bits
Clés uniques
2 niveaux de sécurité :
• Réseau (Network Session Key)
• Encryption de la couche réseau + payload
• Application (Application Session Key)
• Encryption de la payload
LoRaWAN – Sécurité
3
0
• Demande d’acquittement des trames (ACK)
• Découpage des trames en plusieurs envoi (FramePending)
• Vérification du lien (côté device = LinkChackReq et côté réseau =
LinkCheckAns)
• Modification de changement de débit (à l’initiative du réseau =
LinkADRReq, LinkADRAns)
• Limitation du débit d’un device (à l’initiative du réseau =
DutyCycleReq, DutyCycleAns)
• Modification du débit de la fenêtre Rx1 et/ou modifier la
fréquence et le débit de Rx2 (à l’initiative du réseau =
RXParamSetupReq,RXParamSetupAns)
• Récupération du status d’un device (à l’initiative du réseau =
DevStatusReq, DevStatusAns) …
LoRaWAN – Possibilités réseau
2
9
Exemple de mise en
oeuvre
3
2
Ajout d’un serveur de gestion de clé (KMS) :
• L’opérateur n’a plus accès à l’AppKey
• Les données ne peuvent plus être décryptées par l’opérateur
• Décriptage des données par un Application server externe
LoRaWAN – Ajout de Sécurité
3
1
www.eolane.com
La Fresnay
49123 Le Fresne-sur-Loire
FRANCE
Tél : +33 (0)2 41 19 90 54
[email protected]
Texte Verdana cyan
Texte Verdana gris
Texte Verdana bleu
Visualisation des données
3
3
Téléchargement