µC-OSII sur carte d’évaluation Blackfin
GUILBERT Tamara JOFFE Daniel
JUAN Matthieu KOZLOWSKI Frédéric
Electronique option SE 2012 - 2013
1. Introduction
1.1.Présentation du projet
Dans le cadre des projets avancés de l’option Systèmes Embarqués, nous avons choisi de réaliser le
portage de µC/OS II sur une carte DSP Blackfin BF537. Ce portage est nécessaire dans le but de faire
évoluer les TP d’introduction au temps réel. Ceux-ci utilisent déjà un noyau µC/OS II mais sur un
microcontrôleur 68HC11 aujourd’hui désuet et sur une carte présentant régulièrement des faux
contacts. Ces TP sont aujourd’hui réalisés sous une machine virtuelle Windows ce qui est en
contradiction avec l’esprit de l’option SE qui se base sur l’utilisation toujours plus importante des
logiciels libres. Le projet consiste donc à porter ces TP sous Linux en utilisant de nouvelles cartes,
basées sur des processeurs Blackfin.
1.2. Objectifs
L’objectif de ce projet est d’actualiser les Travaux Pratiques d’introduction au temps réel pour qu’ils
soient réalisés sur les cartes Blackfin, la série de TP Linux embarqué ayant déjà été réalisée sur cette
carte. Pour cela, nous devons fournir les fichiers pour implémenter µC/OS-II sur la carte Blackfin et
les makefile nécessaires à la réalisation des différents exercices. Nous devons également réalisé tous
les TP pour s’assurer du bon fonctionnement des fichiers que nous fournirons. Les futurs étudiants
ne devraient donc pas rencontrer de problèmes face à la carte Blackfin ou à µC/OS-II lors de la
réalisation de ces TP.
1.3. Présentation de µC/OS II
Qu’est-ce que µC/OS-II?
µC/OS-II a été développé par le canadien Jean J. Labrosse, est un exécutif temps réel destiné au
départ à des environnements de très petite taille. Il est disponible sur un grand nombre de
processeurs et peut intégrer des protocoles standards comme TCP/IP (µC/TCP) pour assurer une
connectivité IP sur une liaison série. Il est utilisable gratuitement pour l'enseignement.
C’est un noyau multitâche portable, préemptif, « scalable », interruptible, déterministe, fiable et
robuste pour les microprocesseurs, les microcontrôleurs et les DSP.
Fonctionnement de µC/OS-II
µC/OS-II est une bibliothèque qui est liée avec l’application à développer. Les services de µC/OS-II
sont appelés depuis l’application comme des fonctions. Le code source est divisé en 2 sections, l’une
indépendante du processeur et la seconde dépendante du processeur.
µC/OS-II est un noyau ouvert avec un code source disponible entièrement en ANSI C. Il comprend la
gestion de sémaphore, de boites aux lettres, de files d’attentes, la gestion du temps… Le temps
d’exécution pour la plupart des services est constant, déterministe et ne dépend pas du nombre de
tâche en cours dans l’application.
Applications
µC/OS-II est utilisé dans un grand nombre d’application comme l’avionique (utilisé dans Mars
Curiosity Rover), les équipements médicaux, les téléphones portables, l’automobile et pour une large
gamme de systèmes embarqués critiques.
1.4.Présentation de la carte DSP Blackfin BF537
Le Blackfin 537 est un DSP (Digital Signal Processor) 32 bits développé, fabriqué et commercialisé
par Analog Devices. Le BF537 est un processeur unifié basse puissance qui permet de faire
fonctionner des systèmes d'exploitation, tout en réalisant des tâches plus complexes. Il est utilisé
pour les applications embarquées audio, vidéo ou de communication.
Le BF537 possède les caractéristiques suivantes :
- Monoprocesseur
- Peut travailler jusqu’à une fréquence de 600MHz
- Possède un jeu d’instructions 32 bits basé sur le RISC
- A une architecture SIMD (Simple Instruction Multiple Datas)
- Possède 132 Ko de RAM on-chip
- A une connectivité Ethernet intégrée
- Possède un MPU (Memory Protection Unit)
Figure 1 : Carte de développement Blackfin BF537 EZ lite
2. Communication
L’environnement dans lequel se dérouleront les TP sera constitué d’un PC hôte et de la carte cible.
Les moyens de communications entre ces deux entités sont la liaison série pour les échanges via
minicom et la liaison Ethernet pour les transferts d’images via tftp.
Les logiciels utilisés sont minicom et uboot. Dans la suite on considérera que les commandes réalisées
depuis l’ordinateur hôte commenceront par Host%, celles depuis uboot par Bfin>, et celles sur la
carte cible par Target#.
Minicom est un programme d’émulation de terminal qui permet d’établir une liaison avec la carte et
d’avoir accès à un terminal pour que l’utilisateur puisse entrer les commandes à exécuter sur la
carte. Celui-ci est appelé via la commande
Host% minicom
En particulier lors du reset de la carte, minicom nous permet d’accéder à uboot. Uboot (Universal
bootloader) est le bootloader installé et utilisé pour charger µC/OS-II. L’image générée lors de la
compilation est au format elf et contient µC/OS-II. ELF (Executable and Linkable Format) est un
format de fichier standard utilisé pour l’enregistrement de code compilé. L’image est transférée sur
la carte grâce à la commande suivante qui met en œuvre le protocole TFTP. Le protocole TFTP (Trivial
File Transport Protocol) est un protocole simplifié de transfert de fichiers et est surtout utilisé sur
réseau local, du fait de l’absence de contrôles de paquets, ce qui correspond à notre utilisation.
Bfin > tftp nomImage.elf @de chargement
Puis, une fois sur la carte, l’image chargée préalablement est lancée avec la commande bootelf
d’uboot.
Bfin > bootelf
Bootelf est une commande uboot qui permet de charger une image elf en mémoire. Par défaut
l’adresse de chargement est 0x1000000.
Les autres commandes disponibles sous uboot et qui seront utilisées sont lors de ces TP.
Bfin > md @Mem
afin d’afficher le contenu de la mémoire qui débute à l’adresse spécifiée
Bfin> mw @Mem valeur nbreoctets
qui permet de remplacer le contenu de la mémoire à partir de l’adresse renseignée et sur le nombre
d’octets spécifiés par la valeur donnée.
3. Portage de µC/OS-II sous environnement linux.
3.1. Architecture du projet
Après avoir détaillé l’environnement et le système d’exploitation temps réel uCOS-II que
nous utilisons dans ce projet, nous allons nous occuper de la partie du portage, c’est-à-dire
l’association des parties précédentes.
Tout d’abord, il nous faut acquérir les sources du code de uCOS-II adaptées pour notre cible,
c’est-à-dire la carte de développement blackfin. Celles-ci sont disponibles sur le site suivant :
http://micrium.com/page/downloads/ports/analog_devices
Nous choisissons le portage GNU, c’est-à-dire avec le compilateur gcc pour l’architecture
BF53x d’E.Sutter. Ce portage correspond à notre carte de développement la BF537 EZ lite.
Nous pouvons alors, compiler ce portage à l’aide du compilateur croisé bfin-elf-gcc qui
fournit une image de type .elf compilé par gcc pour la cible blackfin. Avant de lancer la compilation, il
faut installer la chaine de compilation bfin-elf-gcc puis pour simplifier les inclusions de fichiers, il est
préférable de changer l’arborescence des fichiers sources.
Une autre précision sur ce projet, ce portage utilise le moniteur micromon pour l’accès à des
fonctions comme « printf » très utiles pour le débugge. Mais nous n’allons pas utiliser ce moniteur
dans le cadre de notre projet. Nous implémenterons plus tard l’envoi de caractères par la liaison
série dans les fichiers bsp du « board support package » qui implémentent les fonctions de base
spécialement écrites pour la carte cible.
Figure 2 : Arborescence du projet
3.2. Détails sur le Makefile
Nous allons maintenant détailler le Makefile qui sera utilisé dans l’ensemble du projet.
Celui-ci est d’abord, composé de paramètres et de divers chemins qui seront utilisés lors de la
compilation comme l’adresse IP de la carte cible, l’adresse du point d’entrée du code dans la RAM et
le nom de l’application à compiler. Pour simplifier l’exécution de chaque exercice, nous conserverons
le même Makefile ainsi que les valeurs suivantes pour les paramètres précédents :
APPRAMBASE = 0x100000
TARGET_IP = 135.222.138.18
APPNAME = app
Passons désormais en revue, les différents chemins à renseigner :
UCOSDIR = ../../uCOS-II
KERNELDIR = $(UCOSDIR)/Source
PORTDIR = $(UCOSDIR)/Ports
ODIR = obj
Le premier correspond au dossier générique du système temps réel uCOS-II, avec deux parties
distinctes la partie noyau avec Source (« kernel ») indépendante de la cible et la partie portage avec
Ports qui elle est spécifique à la cible donc pour nous la carte de développement Blackfin. Enfin, le
dernier chemin concerne le dossier de destination des divers objets créés, ici obj.
Ensuite, nous incluons l’ensemble des dossiers précédemment cités ainsi que le dossier d’includes
avec la ligne suivante :
INCLUDES = -I $(KERNELDIR) -I $(PORTDIR) -I ./include -I .
Nous allons alors détailler les éléments nécessaires pour la compilation comme le compilateur choisi
bfin-elf-gcc, le linkeur bfin-elf-ld et l’outils pour observer le mapping mémoire bfin-elf-nm. Ensuite,
divers options de compilations sont précisés mais nous ne les détailleront pas.
CC = bfin-elf-gcc
LD = bfin-elf-ld
NM = bfin-elf-nm
La suite du Makefile se compose essentiellement de l’étape de création des fichiers objets .o dans les
trois grandes sections Kernel pour le noyau, Port pour le portage et enfin App pour l’application.
3.3. Board Support Package
Nous allons détailler ici, les fichiers qui implémentent les fonctions utiles lors des diverses
applications comme le contrôleur des leds, l’envoi et la réception d’un caractère. De plus, nous
associons à ces fichiers bsp, un autre printf.c pour l’implémentation de la fonction très utile
« printf ».
Détaillons d’abord, le manageur de leds qui nous permet de vérifier le bon fonctionnement
du portage une fois l’image compilée et transférée sur la carte de développement. Voici les quatre
fonctions utiles pour agir sur les leds :
void BSP_initLED (void);
void BSP_setLED (INT8U lite);
void BSP_clrLED (INT8U lite);
void BSP_toggleLED (INT8U lite);
Pour la gestion des leds, il faut assigner les leds en sortie par pPORTFIO_DIR puis nous
pouvons agir sur celles-ci au travers des pointeurs pPORTFIO_SET, pPORTFIO_CLEAR et
pPORTFIO_TOGGLE en décalant l’unité de 5 plus le numéro de la led passé en argument (« lite »).
Passons ensuite au détail de la gestion du timer qui peut être vérifié par le clignotement
d’une led toutes les secondes par exemple. La fonction qui gère le timer pour l’initialiser est :
void BSP_CoreTmrInit (void);
Nous utilisons cette fonction pour initialiser notre source de « tick » pour uCOS-II. Puis nous activons le timer pTCNTL nous obtiendrons alors un nombre OS_TICKS_PER_SEC de « ticks » par secondes au travers d’interruptions. Voici, la formule pour obtenir OS_TICKS_PER_SEC :
Nous fixons alors la valeur du compteur count avec cette constante OS_TICKS_PER_SEC pour obtenir un « tick » tous les 100 ms. Ce fait est vérifié en contrôlant le clignotement d’une led toutes les 10 ticks soit une seconde normalement.
Ensuite, passons aux fonctions putchar et getchar pour l’envoi et la réception d’un caractère.
void putchar (char c);
char getchar ();
Détaillons d’abord, l’envoi d’un caractère à l’aide de la fonction putchar dont on passe en argument
le caractère à émettre. Nous utilisons la liaison série UART0 avec le « Line Status Register » qui est le
registre d’état de la liaison et qui contient notamment le bit THRE, Transmitter Holding Register
Empty pour vérifier si le registre d’émission de la liaison série est vide ou non. Il faut d’ailleurs
effectuer cette vérification avant et après l’écriture du caractère sur l’uart dans le registre de
transmission THR pour avoir l’assurance d’émettre l’intégralité du message. De plus, si le caractère
est un retour à la ligne ‘\n’ il faut ajouter l’envoi d’un caractère ‘\r’ pour s’assurer de la portabilité du
système entre Linux et Windows pour la communication avec la carte.
Pour la seconde fonction, ce dernier problème ne se pose pas en effet, il suffit de récupérer un
caractère donc nous testons si le buffer de réception est plein pour ensuite, retourner le caractère
reçu à l’aide du bit DR du registre LSR pour le test et le registre RBR de l’UART0.
Pour finir, expliquons brièvement le fichier « printf.c » que nous avons trouvé sur internet.
void printchar(char **str, int c);
int prints(char **out, const char *string, int width,
int pad);
int printi(char **out, int i, int b, int sg, int width,
int pad, int letbase);
int print(char **out, int *varg);
int printf(const char *format, ...);
int sprintf(char *out, const char *format, ...);
Ce fichier utilise des fonctions d’affichage d’un caractère, d’un entier ainsi que d’une chaine de
caractère pour retrouver le printf ainsi que le sprintf habituel.
4. Tests des TPs
Les exercices dont les énoncés sont fournis en Annexes permettront aux étudiants d’appréhender
µC/OS-II, et donc de manière plus générale un système d’exploitation temps réel. Aux cours de ces
TP, plusieurs outils et fonctionnalités seront mis en œuvre : Multitâche, sémaphores,
communications inter-tâches et gestion de timers.
Ces exercices ont tous été testés, et sont présentés dans cette partie.
4.1. TP0 – Prise en main de l’environnement
Le but de ce TP est de comprendre tout le processus d’utilisation de la carte Blackfin ainsi que les
étapes de compilation et de lancement d’un code avec µC/OS-II comme système d’exploitation dans
notre environnement de travail.
4.2. TP1 – Multitâche avec µC/OS-II
Le but de cette partie est d’utiliser le multitâche au travers du système d’exploitation µC/OS-II.
Les premiers fichiers fournis implémentent deux tâches tournant en parallèle, incrémentant
régulièrement un compteur. Une tâche principale (rootTask) lance les deux tâches compteur (task1,
task2), puis entre dans une boucle d’attente infinie. Task1 et task2 incrémentent un compteur tous
les 100 ms.
En lisant directement en mémoire les valeurs de ces compteurs, on se rend compte que les deux
tâches semblent bien s’exécuter en parallèle.
4.3. TP2 – Ajout d’une fonction dans un système multitâche.
Ce TP consiste à ajouter une fonctionnalité au système multitâche existant. La fonction écho utilisant
intensivement les fonctions d’entrée/sortie sur la liaison série, on pourrait s’attendre à ce qu’elle
perturbe le fonctionnement des autres tâches, par exemple en déséquilibrant les deux compteurs.
Nous observons que les deux compteurs développés précédemment fonctionnent toujours comme
prévu, malgré l’ajout de la fonction écho dans la tâche principale (rootTask).
4.4. TP3 – Contrôle des LEDs
Car nous ne manquerions pour rien au monde une nouvelle façon de faire un chenillard. Cet exercice
permet de commencer à utiliser les périphériques de la carte (ici, les LEDs).
On vérifie que l’accès aux différents périphériques est possible, nous remplaçons alors le compteur
de la tâche 1 par un chenillard sur les LEDs à notre disposition tout en conservant l’écho dans la
tâche principale.
4.5. TP4 – Première utilisation des sémaphores
Une fois l’accès aux LEDs vérifié, nous pouvons nous lancer dans l’utilisation d’outils très utiles pour
le multitâche comme les sémaphores.
Ils vont nous permettre de contrôler l’accès à une ressource en restreignant son accès à une seule
tâche à la fois. Pour mettre en pratique ce concept nous décidons que la ressource est une LED que
nous ferons clignoter à l’aide des tâches 1 et 2. Nous utilisons alors les sémaphores de µC/OS-II avec
ses fonctions associées de libération et de prise d’un sémaphore.
4.6. TP5 – Mise en place d’un rendez-vous
Le but de cette partie est de réaliser une synchronisation de plusieurs tâches en effectuant un
rendez-vous. Celui-ci est réalisé à l’aide de sémaphores binaires et la vérification s’effectue en
allumant une LED avec la tâche en attente.
4.7. TP6 - Gestionnaire des tâches
Ce TP sert à comprendre le fonctionnement d’une tâche principale qui peut gérer plusieurs autres
tâches en parallèle en les autorisant ou en les laissant en attente. Nous utilisons encore un
sémaphore par tâche pour réaliser cette partie. Chaque tâche est bloquée sur son sémaphore et la
tâche principale les libère en fonction de l’action à réaliser.
4.8. TP7 – Problème des philosophes
Pour mieux comprendre l’utilisation des sémaphores nous allons tenter de résoudre le problème des
philosophes. Cinq philosophes peuvent manger et penser mais une seule chose à la fois, pour
pouvoir manger ils doivent avoir à disposition deux fourchettes qui sont partagées avec ses voisins
proches.
L’utilisation des LEDs pour vérifier les tâches actives et celle des sémaphores qui sont représentés par
les fourchettes dans le problème permettent de solutionner ce problème.
4.9. TP8 - Gestion du temps
Une autre notion importante dans l’utilisation d’un système d’exploitation est la gestion du temps
pour pouvoir agir à des temps définis. Pour cela nous utilisons le clignotement des LEDs toutes les
100ms, 1s et 10s pour vérifier le bon fonctionnement et la bonne gestion du temps dans notre
système.
4.10. TP9 – Mailbox
Un dernier point important qui peut s’avérer être utile lors de l’utilisation d’un système temps réel
est la gestion d’une mailbox pour pouvoir envoyer une requête à une tâche et conserver cette
requête jusqu’à ce que celle-ci soit réalisée.
Nous effectuons le traditionnel chenillard par mailbox entre les différentes tâches.
4.11. TP10 – Exercice final
L’exercice final est la gestion d’un chronomètre pour utiliser toutes les parties précédentes et les
diverses fonctions d’un système temps réel comme µC/OS-II.
En effet, cette partie requiert l’accès et le contrôle de différentes tâches, la prise en compte des
interventions de l’utilisateur et la gestion du temps donc l’utilisation des sémaphores, mailbox et
autres éléments détailler dans les parties précédentes.
5. Conclusion
Au niveau de l’avancement du projet, nous avons été freinés au début par nos sources qui n’étaient
pas forcément les plus adaptées à notre sujet. Puis, une fois les sources correctes trouvées, nous
avons fortement avancé, notamment grâce à l’aide de notre encadrant qui nous a fourni son
expérience dans le domaine pour faire aboutir le projet.
Ce projet fut pour nous l’occasion de se familiariser avec des notions techniques qui nous serons
utiles dans notre futur emploi en tant qu’ingénieur en systèmes embarqués notamment au niveau du
portage d’un système temps réel sur une carte de développement.
Mais cela fut aussi pour nous une découverte des conditions de travail d’un ingénieur qui doit
chercher et collecter les informations, savoir bien s’organiser pour avoir une architecture de travail
clair et aisément utilisable. De plus, le travail en groupe de quatre permet de développer nos qualités
de communication et d’organisation pour que tout le monde s’y retrouve.
ANNEXES GUILBERT Tamara
JOFFE Daniel JUAN Matthieu
KOZLOWSKI Frédéric
Electronique option SE
2012 - 2013
Introduction du polycopié de TP
Partie détaillant la carte Blackfin BF537 dans le polycopié des TP de uClinux
Partie sur µC/OS-II pour savoir comment utiliser l’OS dans le précédent polycopié de µC/OS-II sur le
68HC11.
EX0 : PRISE EN MAIN DU NOYAU µC/OS II
Le but de ce TP est de prendre en main le noyau temps réel µC/OS II. Un programme de test est fourni avec
le noyau. On va ainsi analyser le code donné puis l’exécuter.
1. Démarrer le PC sous Linux. Créer un répertoire de travail personnel et copier les sources :
% cd % mkdir mon_nom % cd mon_nom
% cp –r chemin_prof/ bf537-uCOS-II . % cd tp/Ex1
2. Analyser le fichier main.c. Que réalise la tâche rootTask ? Que réalise la fonction main() ?
Roottask fait clignoter les leds toutes les secondes et affiche un point sur l’écran
Main() lance l’OS
3. Analyser le makefile.
- Quel est l’adresse du point d’entrée de l’application ? 0x100000
- Renseigner et vérifier l’adresse IP de la carte cible
- Quel est le compilateur croisé utilisé ? bfin-elf-gcc
- Quel est le format du fichier image? .elf
- Dans quel fichier se trouve le fichier de mapping? app.sym
4. Compiler l’application de test
% make
5. Quels sont les fichiers créés lors de la compilation ?
Objets .o dans obj/
App.elf image de notre appli
App.sym mapping mémoire
6. Analyser le fichier de mapping
- Quel est la fonction à l’adresse précisée précédemment ? OSIntEnter
- Retrouver l’adresse des compteurs 1 et 2 ? 001088cc et 001084c8
Configuration et programmation de la carte
7. Déplacer le fichier image dans le dossier tftp
Host% cp app.elf /tftpboot
8. Lancer minicom dans un shell
Host% minicom
9. Il va ensuite falloir faire un reset de la carte puis appuyer sur n’importe quelle touche du clavier
pour éviter un autoboot.
10. A travers minicom, on va télécharger l’image grâce à tftp. Par défaut, l’image sera téléchargée à
l’adresse 0x1000000.
Bfin> tftp app.elf
11. Booter sur l’image du noyau
Bfin> bootelf
12. Vérifier le bon fonctionnement avec le clignotement de la LED.
EX1 : MULTITACHE AVEC LE NOYAU µC/OS II
Le but de ce TP est de prendre en main le multitâche sous le noyau temps réel µC/OS II. Un programme de
test est fourni avec le noyau. On va ainsi analyser le code donné puis l’exécuter.
1. Aller dans le dossier ex1 dans le répertoire de TP.
2. Analyser le fichier main.c. Que réalisent les tâches task1, task2 et rootTask ? Que réalise la
fonction main() ?
Roottask crée task1 et task2 puis fait clignoter les leds toutes les secondes et affiche un point sur
l’écran
task1() incrémente counter1 toutes les 1/10s
Parallèlement task2() idem counter2
Main() lance l’OS
3. Analyser le makefile.
4. Compiler l’application de test
% make
5. Quels sont les fichiers créés lors de la compilation ?
Objets .o dans obj/
App.elf image de notre appli
App.sym mapping mémoire
6. Analyser le fichier de mapping
- Quel est la fonction à l’adresse précisée précédemment ? OSIntEnter
- Retrouver l’adresse des compteurs 1 et 2 ? 001088cc et 001084c8
Configuration et programmation de la carte
7. Une fois le programme en mémoire à l’aide de la commande tftp, on va visualiser la valeur des
compteurs grâce à la commande md (Memory display) puis on va mettre cette valeur à 0 grâce à la
commande mw (Écriture à l’adresse spécifiée de la valeur 0 sur 16 octets)
Bfin> md 1088cc Bfin> mw 1088cc 0 16
8. On utilise md pour vérifier que les deux compteurs sont bien à la valeur 0.
9. Booter sur l’image du noyau
Bfin> bootelf
10. On va finir par faire un reset de la carte puis vérifier la valeur des deux compteurs grâce à la
commande utilisée précédemment
EX 2 : MULTITACHE. ECHO SUR RS.232 ET PLUS UN AVEC LE NOYAU µC/OS II
Le but de ce TP est d’écrire un programme PING sur une tâche, c’est-à-dire d’afficher au travers de la
liaison série les caractères tapés sur le clavier et en parallèle incrémenter les compteurs.
On partira du fichier main.c dans le dossier Exo2. On y inclura alors les lignes de code pour réaliser les
conditions suivantes :
tâche rootTask : lancement des tâches task1 et task2 et ensuite programme d’écho sur
RS.232.
tâche task1 : inchangée, fait du « plus 1 ».
tâche task2 : inchangée, fait du « plus 1 ».
1. Créer le programme C main.c suivant les conditions précédentes. L’ensemble des autres fichiers
est donné (Makefile, fichiers .h et .c).
2. Compiler à l’aide de la commande make.
3. Analyser le fichier de mapping app.sym. Retrouver les adresses des étiquettes Counter1 et
Counter2.
4. Mettre à zéro le contenu des adresses correspondant à Counter1 et Counter2.
5. Charger l’image app.elf dans la carte cible et booter sur elle.
6. Faire un reset de la carte et regarder le contenu des adresses Counter1 et Counter2 pour
vérification
EX 3 : MULTITACHE. ECHO SUR RS.232, CHENILLARD ET PLUS UN AVEC LE
NOYAU µC/OS II
Le but de ce TP est de faire exécuter par le noyau 3 tâches distinctes. On partira du fichier main.c
dans le dossier Exo3 dont voici les conditions :
tâche rootTask : lancement des tâches task1 et task2 et ensuite programme d’écho sur
RS.232.
tâche task1 : chenillard sur les leds numérotées de 1 à 6 (utilisez les fonctions contenues
dans les fichiers bsp.h)
tâche task2 : inchangée, fait du « plus 1 ».
1. Créer le programme C main.c suivant les conditions précédentes. L’ensemble des autres fichiers
est donné (Makefile, fichiers .h et .c dont les très utiles bsp.h et bsp.c).
2. Compiler à l’aide de la commande make.
3. Analyser le fichier de mapping app.sym.
4. Charger l’image app.elf dans la carte cible et booter sur elle.
5. Vérifier le bon fonctionnement des leds et de l’écho
EX 4 : SEMAPHORES BINAIRES. GESTION DE L’ACCES EXCLUSIF A UNE
RESSOURCE PARTAGEE
Le but de ce TP est de gérer l’accès exclusif à une ressource partagée. Celle-ci sera représentée par la
led 6.
L’accès exclusif sera géré par un sémaphore binaire Sem1.
On créera 3 tâches distinctes. On partira des fichiers précédents que l’on modifiera en conséquence :
tâche rootTask : création d’un sémaphore binaire Sem1, lancement des tâches task1 et task2
bloquées sur le sémaphore Sem1.
tâche task1 : bloquée sur le sémaphore binaire sem1. A sa libération, changement d’état de
la led 6 puis libération de Sem1.
tâche task2 : bloquée sur le sémaphore binaire sem1. A sa libération, changement d’état de
la led 6 puis libération de Sem1.
On pourra utiliser les fonctions présentes dans bsp.h pour retrouver son « printf » préféré et une
fonction BSP_toggleLED très agréable.
EX 5 : SEMAPHORES BINAIRES. SYNCHRONISATION DE TACHES. RENDEZ-
VOUS
Le but de ce TP est de synchroniser 2 tâches à un instant donné dans l’exécution de leur code.
Cela s’appelle un rendez-vous.
On créera 3 tâches distinctes. On partira des fichiers précédents que l’on modifiera en conséquence :
tâche rootTask : création d’un sémaphore binaire Sem et lancement des tâches task1 et
task2.
tâche task1 : bloquée sur le sémaphore binaire Sem.
tâche task2 : Donne un RDV à la tâche task1 par libération du sémaphore binaire Sem qui
allumera en conclusion la led 6
EX 6 : SEMAPHORES BINAIRES. RECAPITULATIF
Le but de ce TP est de réaliser un dispatching d’un travail par une tâche. On partira des fichiers
précédents que l’on modifiera en conséquence :
tâche rootTask : création de 3 sémaphores binaires lancement des tâches task1, task2 et
task3 bloquées sur sémaphore. Libération de sémaphores un à un pour activer chaque tâche.
tâche task1 : bloquée sur le sémaphore binaire sem1. A sa libération par rootTask, allumage
de la led 4.
tâche task2 : bloquée sur le sémaphore binaire sem2. A sa libération par rootTask, allumage
de la led 5.
tâche task3 : bloquée sur le sémaphore binaire sem3. A sa libération par rootTask, allumage
de la led 6.
EX 7 : SEMAPHORES BINAIRES. PROBLEME DES PHILOSOPHES
Le but de ce TP est traiter le problème des philosophes.
Le problème des philosophes et des spaghettis est un problème classique en théorie informatique, et
plus particulièrement pour les questions d'ordonnancement des processus. Ce problème a été
énoncé par Edsger Dijkstra, l’inventeur du concept des sémaphores.
La situation est la suivante :
• 5 philosophes se trouvent autour d'une table.
• Chacun des philosophes a devant lui un plat de spaghettis.
• A gauche de chaque assiette se trouve une fourchette
Un philosophe n'a que deux états possibles :
• Penser pendant un temps déterminé.
• Manger.
Des contraintes extérieures s'imposent à cette situation :
• Pour manger, un philosophe a besoin de deux fourchettes : celle qui se trouve à gauche de sa
propre assiette et celle qui se trouve à gauche de celle de son voisin de droite (soit les deux
fourchettes qui entourent sa propre assiette).
• Si un philosophe n'arrive pas à s'emparer d'une fourchette, il se met à penser pendant un temps
déterminé, en attendant de renouveler sa tentative.
Le problème est le suivant : si tous les philosophes essayent en même temps de manger :
1. Ils vont tous vouloir saisir les mêmes fourchettes en même temps.
2. Tous vont échouer.
3. Tous vont se mettre à penser pendant le même délai.
4. Tous vont renouveler leur tentative en même temps.
5. etc à l'infini.
L'une des principales solutions à ce problème est celle du sémaphore, proposée, comme ce
problème, par Edsger Dijkstra.
EX 8 : GESTION DU TEMPS
Le but de ce TP est de faire exécuter par le noyau 4 tâches distinctes qui affichent un message à des
périodes différentes. On partira des fichiers précédents que l’on modifiera en conséquence :
‰ tâche rootTask : lancement des tâches task1, task2 et task3.
‰ tâche task1 : affichage d’un message toutes les 100 ms.
‰ tâche task2 : affichage d’un message toutes les secondes.
‰ tâche task3 : affichage d’un message toutes les 10 secondes
EX 9 : GESTION D’UNE MAILBOX DE MESSAGES
Le but de ce TP est de mettre en œuvre une file de messages de type mailbox. Une tâche envoie
périodiquement des messages à une autre tâche qui sur réception du message change l’état courant
de la led x en fonction du contenu du message (x=1 pour led 1 à x=6 pour led 6). On partira des
fichiers précédents que l’on modifiera en conséquence :
tâche rootTask : création d’une file de messages mailbox et lancement des tâches task1, et
task2.
tâche task1 : postage d’un message dans la mailbox précisant le numéro de la led (1 à 6) et
son état (on ou off) toutes les secondes.
tâche task2 : attente d’un éventuel message dans la mailbox et changement de l’état de la
led considérée en conséquence en cas de réception d’un message.
On en profitera pour réaliser ainsi un chenillard.