24.06.2013 Views

Sujet du TP5, Prise en main de uC/OS-II sous ... - ETIS - ENSEA

Sujet du TP5, Prise en main de uC/OS-II sous ... - ETIS - ENSEA

Sujet du TP5, Prise en main de uC/OS-II sous ... - ETIS - ENSEA

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Université <strong>de</strong> Cergy­Pontoise<br />

TP <strong>de</strong> prise <strong>en</strong> <strong>main</strong> <strong>de</strong> <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong><br />

Le noyau temps réel<br />

Informatique Embarquée<br />

1. Intro<strong>du</strong>ction<br />

a. Le noyau temps réel <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong><br />

<strong>uC</strong>/<strong>OS</strong> (ou microC/<strong>OS</strong>) est un système d’exploitation temps réel multi­tâches préemptif.<br />

Développé par le Canadi<strong>en</strong> Jean J. Labrosse, <strong>uC</strong>/<strong>OS</strong> est un exécutif temps réel <strong>de</strong>stiné à<br />

<strong>de</strong>s <strong>en</strong>vironnem<strong>en</strong>ts <strong>de</strong> très petite taille construits autour <strong>de</strong> Microcontrôleurs. Il est<br />

<strong>main</strong>t<strong>en</strong>ant disponible sur un grand nombre <strong>de</strong> processeurs et peut intégrer <strong>de</strong>s<br />

protocoles standards comme TCP/IP (µC/IP) pour assurer une connectivité IP sur une<br />

liaison série par PPP. Il est utilisable gratuitem<strong>en</strong>t pour l'<strong>en</strong>seignem<strong>en</strong>t.<br />

Il est aujourd’hui développé et <strong>main</strong>t<strong>en</strong>u par la société Micrium :<br />

http://www.ucos­ii.com/<br />

<strong>uC</strong>/<strong>OS</strong> est développé <strong>en</strong> C, sauf <strong>en</strong> ce qui concerne les portions <strong>de</strong> co<strong>de</strong> qui sont cibledép<strong>en</strong>dant<br />

(portage), comme l’implantation <strong>de</strong>s opérations <strong>de</strong> changem<strong>en</strong>t <strong>de</strong> contexte<br />

qui sont écrites <strong>en</strong> assembleur.<br />

<strong>uC</strong>/<strong>OS</strong> fait partie <strong>de</strong>s nombreux systèmes d’exploitation temps réel aujourd’hui<br />

disponibles sur le marché : A<strong>de</strong>os, Chorus<strong>OS</strong>, eCos, ITRON, Lynx<strong>OS</strong>, MicroC/<strong>OS</strong>­<strong>II</strong>,<br />

Nucleus, <strong>OS</strong>­9, <strong>OS</strong>E, <strong>OS</strong>EK/VDX, pS<strong>OS</strong>, QNX, RSX­11, RT­11, RT<strong>OS</strong>­UH, SCIOPTA,<br />

VRTX, VxWorks, Windows CE, RTLinux, RTAI …<br />

b. Objectif <strong>de</strong> la séance<br />

i. Objectif<br />

L’objectif <strong>de</strong> la séance <strong>de</strong> TP est la prise <strong>en</strong> <strong>main</strong> <strong>de</strong>s comman<strong>de</strong>s <strong>de</strong> base (API 1 )<br />

d’un RT<strong>OS</strong> et <strong>de</strong> compr<strong>en</strong>dre le principe fondam<strong>en</strong>tal <strong>de</strong> fonctionnem<strong>en</strong>t <strong>de</strong> ce type <strong>de</strong><br />

système. <strong>uC</strong><strong>OS</strong> étant un exemple représ<strong>en</strong>tatif <strong>du</strong> fonctionnem<strong>en</strong>t d’un RT<strong>OS</strong>, le travail<br />

réalisé <strong>sous</strong> cet <strong>en</strong>vironnem<strong>en</strong>t serait facilem<strong>en</strong>t instanciable avec un autre système<br />

d’exploitation.<br />

Cette intro<strong>du</strong>ction au développem<strong>en</strong>t d’applications embarquées temps réel<br />

comm<strong>en</strong>ce par une utilisation <strong>de</strong> l’<strong>OS</strong> sur PC mais sera <strong>en</strong>suite suivi d’une utilisation<br />

sur une carte <strong>de</strong> développem<strong>en</strong>t embarquée. La compréh<strong>en</strong>sion <strong>de</strong>s mécanismes <strong>de</strong> base<br />

est donc primordiale pour la suite <strong>de</strong>s TPs.<br />

A ce titre, vous <strong>de</strong>vrez à l’issue <strong>de</strong>s séances <strong>de</strong> TP réaliser une sout<strong>en</strong>ance sur les<br />

manipulations, développem<strong>en</strong>ts et tests que vous aurez réalisés.<br />

ii. Sout<strong>en</strong>ance<br />

10 minutes <strong>de</strong> sout<strong>en</strong>ance seront allouées par personne plus 5 minutes <strong>de</strong> questions.<br />

Lors <strong>de</strong> cette sout<strong>en</strong>ance, il vous sera <strong>de</strong>mandé une ou <strong>de</strong>ux démonstrations sur les 7<br />

exercices réalisés. Vous <strong>de</strong>vrez pour chacune expliquer le co<strong>de</strong> <strong>de</strong> l’exercice. Des<br />

1 Application Protocole Interface<br />

1


Université <strong>de</strong> Cergy­Pontoise<br />

questions sont pour cela insérées dans ce sujet pour vous gui<strong>de</strong>r dans la compréh<strong>en</strong>sion<br />

<strong>du</strong> système <strong>uC</strong>/<strong>OS</strong>.<br />

Cette sout<strong>en</strong>ance <strong>de</strong>vra r<strong>en</strong>dre compte <strong>de</strong> la particularité <strong>du</strong> développem<strong>en</strong>t dans un<br />

cadre temps réel d’une part et embarqué d’autre part.<br />

Par ailleurs <strong>en</strong> tant que développeur d’applications temps réel au sein <strong>de</strong> l’équipe <strong>de</strong><br />

développem<strong>en</strong>t pédagogique <strong>du</strong> Départem<strong>en</strong>t Sci<strong>en</strong>ces Informatiques, vous pourrez si<br />

nécessaire r<strong>en</strong>dre compte <strong>de</strong>s problèmes techniques r<strong>en</strong>contrés, <strong>de</strong>s limites et contraintes<br />

<strong>de</strong> l’<strong>en</strong>vironnem<strong>en</strong>t <strong>de</strong> développem<strong>en</strong>t actuel, et <strong>de</strong>s év<strong>en</strong>tuels Buggs r<strong>en</strong>contrés à faire<br />

corriger par l’équipe <strong>de</strong> développem<strong>en</strong>t <strong>de</strong>s Outils d’exploitation.<br />

c. Environnem<strong>en</strong>t <strong>de</strong> développem<strong>en</strong>t<br />

Vous allez au cours <strong>de</strong> ces séances pr<strong>en</strong>dre connaissance <strong>de</strong> 2 <strong>en</strong>vironnem<strong>en</strong>ts <strong>de</strong><br />

développem<strong>en</strong>t selon que l’application que l’on cherche à implanter sera <strong>de</strong>stinée à une<br />

exécution sur PC ou à une exécution embarquée.<br />

L’<strong>en</strong>vironnem<strong>en</strong>t <strong>de</strong> développem<strong>en</strong>t sur PC est directem<strong>en</strong>t lié au langage <strong>de</strong><br />

programmation utilisé pour développer <strong>de</strong>s applications <strong>sous</strong> <strong>uC</strong><strong>OS</strong> : le langage C.<br />

Vous pourrez donc utiliser pour le développem<strong>en</strong>t <strong>de</strong>s programmes l’éditeur <strong>de</strong> votre<br />

choix.<br />

Le compilateur C est quand à lui soumis à quelques contraintes. En effet, les librairies<br />

<strong>de</strong> fonctions <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong> disponibles à l’Université ont été développées et compilées avec<br />

BorlandC/C++ version 4.51 pour Windows. Ce compilateur payant n’est pas disponible à<br />

l’Université. Aussi l’<strong>OS</strong> a­t­il été porté pour une version antérieure <strong>du</strong> compilateur<br />

Borland, la version TCPP1.01.<br />

L’<strong>en</strong>vironnem<strong>en</strong>t minimal <strong>de</strong> développem<strong>en</strong>t est l’utilisation d’un logiciel d’édition <strong>de</strong><br />

texte pour la programmation et le lancem<strong>en</strong>t <strong>de</strong>s comman<strong>de</strong>s <strong>de</strong> compilation par<br />

comman<strong>de</strong>s D<strong>OS</strong>.<br />

Vous pouvez selon les logiciels <strong>de</strong> votre PC utiliser un <strong>en</strong>vironnem<strong>en</strong>t <strong>de</strong> développem<strong>en</strong>t<br />

paramétré pour faire appel aux comman<strong>de</strong>s <strong>du</strong> compilateur (make, cc, asm…).<br />

Le compilateur est installé dans le répértoire c:\TOOLS\TCPP101\<br />

Si ce n’est pas le cas, décompresser l’archive prés<strong>en</strong>te sur<br />

http://www­etis.<strong>en</strong>sea.fr/Members/bmiramond/Cours/M1/UEF5.html<br />

à cet emplacem<strong>en</strong>t.<br />

Vos répertoires <strong>de</strong> travail seront situés dans c:\SOFTWARE\UC<strong>OS</strong>­<strong>II</strong>\. Ce répertoire<br />

sera désigné dans la suite par $WORK_DIR.<br />

d. Les primitives utiles <strong>de</strong> la librairie <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong><br />

Vous trouverez <strong>en</strong> annexe à la fin <strong>de</strong> ce docum<strong>en</strong>t les fonctions C principales <strong>de</strong> la<br />

librairie ucos_ii (API).<br />

Note : En cours <strong>de</strong> TP, vous pouvez <strong>de</strong>man<strong>de</strong>r un livre <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong> disponible dans les armoires<br />

<strong>de</strong> la salle pour le détail <strong>de</strong> certains appels ou paramètres d’appel à l’API.<br />

2. Exercice 1 : Concurr<strong>en</strong>ce <strong>de</strong> tâches<br />

a. Un modèle <strong>de</strong> co<strong>de</strong><br />

Vous trouverez dans le répertoire $WORK_DIR\EX1_X86L\TCPP101\TEST les fichiers<br />

nécessaires à la compilation <strong>du</strong> premier exercice : Test.mak (Makefile), Maketest.bat<br />

(script).<br />

2


Université <strong>de</strong> Cergy­Pontoise<br />

Pour lancer la compilation, vous <strong>de</strong>vez lancer le script Maketest.bat.<br />

L’affichage qui apparaît n’est pas complet, ce sera à vous <strong>de</strong> compléter le co<strong>de</strong> et <strong>de</strong><br />

compr<strong>en</strong>dre sa fonctionnalité.<br />

Vous trouverez pour cela dans l’annexe B le co<strong>de</strong> complet <strong>de</strong> l’application temps réel<br />

simple développée avec les fonctions <strong>de</strong> la librairie ucos_ii.<br />

L’objectif <strong>de</strong> ce premier exercice est tout d’abord <strong>de</strong> compr<strong>en</strong>dre la structure d’un<br />

programme <strong>sous</strong> cet <strong>en</strong>vironnem<strong>en</strong>t, puis d’analyser l’utilité <strong>de</strong>s fonctions <strong>uC</strong><strong>OS</strong>.<br />

Pour satisfaire au premier objectif, la première étape <strong>de</strong> ce TP est <strong>de</strong> recopier le co<strong>de</strong><br />

fourni <strong>en</strong> annexe dans le fichier test.c prés<strong>en</strong>t dans<br />

$WORK_DIR\EX1_X86L\TCPP101\SOURCE<br />

Au cours <strong>de</strong> l’écriture <strong>du</strong> co<strong>de</strong>, vous placerez <strong>de</strong>s comm<strong>en</strong>taires indiquant la<br />

fonctionnalité <strong>de</strong>s fonctions <strong>de</strong> l’<strong>OS</strong> <strong>en</strong> vous aidant <strong>de</strong> l’annexe A.<br />

D’autres fichiers sont déjà prés<strong>en</strong>ts dans ce répertoire comme Inclu<strong>de</strong>.h et Os_cfg.h.<br />

b. Analyse <strong>du</strong> co<strong>de</strong><br />

Après avoir correctem<strong>en</strong>t compilé le co<strong>de</strong> et réaliser son exécution, vous allez<br />

<strong>main</strong>t<strong>en</strong>ant procé<strong>de</strong>r aux modifications suivantes :<br />

Enlever l’appel à la fonction PCDosSaveReturn() dans la fonction <strong>main</strong>.<br />

Recompiler et exécuter. Que se passe­t­il ? Expliquer pourquoi.<br />

En quoi l’utilisation <strong>de</strong> <strong>uC</strong><strong>OS</strong> sur PC est­elle différ<strong>en</strong>te d’une utilisation sur plateforme<br />

embarquée ?<br />

3. Exercice 2 : Mesure <strong>de</strong> taille <strong>de</strong> pile d’exécution<br />

a. Compréh<strong>en</strong>sion <strong>de</strong> co<strong>de</strong><br />

Vous allez <strong>main</strong>t<strong>en</strong>ant dans le répertoire<br />

$WORK_DIR\EX2_x86l\TCPP101\<br />

Vous y retrouvez la même organisation que dans l’exemple précéd<strong>en</strong>t.<br />

Compiler le co<strong>de</strong> et exécuter l’application.<br />

Observer ce qui se passe. Id<strong>en</strong>tifier le problème.<br />

Vous allez <strong>main</strong>t<strong>en</strong>ant <strong>en</strong>trer dans le co<strong>de</strong> (répertoire SOURCE) et écrire la fonction<br />

d’affichage TaskStartDispInit() <strong>de</strong> manière à ce qu’un utilisateur compr<strong>en</strong>ne les<br />

données brutes affichées à l’écran. Vous <strong>de</strong>vez pour cela à partir <strong>du</strong> co<strong>de</strong> déjà prés<strong>en</strong>t<br />

compr<strong>en</strong>dre la nature <strong>de</strong>s informations affichées et vous inspirer <strong>du</strong> co<strong>de</strong> <strong>de</strong> l’exercice 1<br />

pour apporter <strong>de</strong>s indications à l’affichage.<br />

Cette application est composée <strong>de</strong> 9 tâches, que font chacune <strong>de</strong> ces tâches ?<br />

b. Analyse <strong>de</strong> comportem<strong>en</strong>t<br />

Cet exercice fait appel à la fonction <strong>OS</strong>TaskStkChk() qui réalise <strong>de</strong>s vérifications et <strong>de</strong>s<br />

mesures <strong>de</strong> taille <strong>de</strong> la pile d’exécution.<br />

L’analyse <strong>de</strong> pile d’exécution est primordiale <strong>en</strong> informatique embarqué et <strong>en</strong> temps réel<br />

lorsque l’on ne connaît pas <strong>de</strong> manière statique et déterministe la place mémoire utilisée<br />

par chaque tâche.<br />

Dans ce cas, une solution est d’allouer plus <strong>de</strong> place que nécessaire et <strong>de</strong> laisser <strong>uC</strong>/<strong>OS</strong>­<br />

<strong>II</strong> mesurer la pile réellem<strong>en</strong>t utilisée. Pour cela l’application doit être lancée<br />

3


Université <strong>de</strong> Cergy­Pontoise<br />

suffisamm<strong>en</strong>t longtemps pour être représ<strong>en</strong>tative d’une exécution <strong>en</strong> <strong>en</strong>vironnem<strong>en</strong>t<br />

réel. Votre mesure finale doit pouvoir s’adapter à <strong>de</strong>s variations non prévues <strong>de</strong><br />

l’<strong>en</strong>vironnem<strong>en</strong>t. Une marge <strong>de</strong> 15 à 20 % est donc nécessaire.<br />

Dans les applications critiques, une marge <strong>de</strong> 100% est indisp<strong>en</strong>sable.<br />

Après mesure, adapter la taille <strong>de</strong> pile <strong>de</strong> chaque tâche et vérifier le bon comportem<strong>en</strong>t<br />

<strong>du</strong> système. Que se passe­t­il si la taille <strong>de</strong> pile allouée est insuffisante ?<br />

La fonction <strong>OS</strong>TaskStckChk() rempli l’espace réservé pour la pile <strong>de</strong> valeurs nulles à<br />

la création <strong>de</strong> chaque tâche.<br />

La vérification et la mesure <strong>de</strong> la taille <strong>de</strong> pile comm<strong>en</strong>ce au bas <strong>de</strong> la pile (pointeur<br />

Bottom Of Stack : B<strong>OS</strong>). En avançant dans la pile le pointeur est incrém<strong>en</strong>té jusqu’à<br />

trouver une <strong>en</strong>trée non nulle. Le compteur donne le nombre d’emplacem<strong>en</strong>ts utilisés.<br />

Cette vérification pr<strong>en</strong>ds <strong>du</strong> temps et n’est donc utilisée qu’<strong>en</strong> cours <strong>de</strong> développem<strong>en</strong>t<br />

et d’analyse <strong>de</strong> co<strong>de</strong>. Une fois implantée sur cible, ces vérifications sont supprimées.<br />

A vous <strong>de</strong> mesurer le coût <strong>en</strong> temps d’exécution <strong>de</strong> cette vérification <strong>en</strong> utilisant<br />

successivem<strong>en</strong>t les fonctions PC_ElapsedStart() et PC_ElapsedStop() (cf. Annexe).<br />

c. Communications <strong>en</strong>tre tâches<br />

<strong>uC</strong><strong>OS</strong> permet évi<strong>de</strong>mm<strong>en</strong>t <strong>de</strong> faire communiquer <strong>de</strong>s tâches <strong>en</strong>tre elles, par exemple <strong>en</strong><br />

<strong>en</strong>voyant <strong>de</strong>s messages par l’intermédiaire d’une boîte aux lettres (mailbox).<br />

Nous allons ici faire communiquer les tâches 4 et 5 : T4 <strong>en</strong>voie un message à T5 et T5<br />

répondra à T4 <strong>en</strong> lui <strong>en</strong>voyant un Ack(nowledge).<br />

Pour cela nous avons besoin <strong>de</strong> créer 2 mailboxes qui permett<strong>en</strong>t <strong>de</strong> cont<strong>en</strong>ir un (et un<br />

seul) pointeur sur une donnée. Cette donnée est spécifique à l’application et doit être<br />

définie <strong>en</strong> commun par l’expéditeur et le <strong>de</strong>stinataire.<br />

Les étapes pour faire communiquer T4 et T5 sont simples :<br />

• Déclarer 2 mailboxes <strong>en</strong> variables globales. Ce sont <strong>de</strong>s pointeurs sur<br />

<strong>de</strong>s <strong>OS</strong>_EVENT<br />

• Créer les 2 mailboxes par la fonction <strong>OS</strong>MboxCreate (void *) qui<br />

retourne un pointeur sur les structures mailbox<br />

• Dans les fonctions T4 et T5 utiliser les fonctions d’<strong>en</strong>voie<br />

<strong>OS</strong>MboxPost() et d’att<strong>en</strong>te <strong>OS</strong>MboxP<strong>en</strong>d() pour que T4 <strong>en</strong>voie un<br />

caractère qui change à chaque Ack reçu <strong>de</strong> ‘A’ à ‘Z’ <strong>de</strong> manière<br />

circulaire. T5 affichera ce caractère.<br />

4. Exercice 3 : Analyse <strong>de</strong> temps d’exécution<br />

a. Mesure <strong>de</strong> temps d’exécution<br />

Les sources <strong>de</strong> l’exercice 3 sont dans $WORK_DIR\EX3_x86L\TCPP101\SOURCE.<br />

L’objectif <strong>de</strong> cet exercice est inverse à celui <strong>de</strong> l’exercice précéd<strong>en</strong>t.<br />

La fonction d’affichage TaskStartDispInit() est écrite. Elle indique différ<strong>en</strong>tes<br />

mesures pour les tâches <strong>de</strong> l’application.<br />

Combi<strong>en</strong> <strong>de</strong> tâches compos<strong>en</strong>t l’application. Quelles sont les mesures que doit<br />

afficher l’exécution.<br />

Votre objectif est d’utiliser les comman<strong>de</strong>s <strong>uC</strong><strong>OS</strong> pour donner ces mesures à<br />

l’affichage <strong>de</strong> données actuellem<strong>en</strong>t constantes.<br />

4


Université <strong>de</strong> Cergy­Pontoise<br />

<strong>uC</strong><strong>OS</strong> est un <strong>OS</strong> ouvert au s<strong>en</strong>s ou le co<strong>de</strong> source <strong>de</strong> l’<strong>OS</strong> est fourni et modifiable<br />

par les utilisateurs.<br />

Nous allons ici utiliser cette propriété pour réaliser nos mesures <strong>en</strong> ajoutant cette<br />

fonctionnalité par l’intermédiaire <strong>de</strong>s fonctions appelées Hook.<br />

9 fonctions Hook exist<strong>en</strong>t. Nous aurons pour notre cas uniquem<strong>en</strong>t besoin <strong>de</strong><br />

modifier la fonction <strong>OS</strong>TaskSwHook.<br />

Celle­ci est appellé par l’<strong>OS</strong> au mom<strong>en</strong>t <strong>de</strong> chaque changem<strong>en</strong>t <strong>de</strong> contexte.<br />

Au mom<strong>en</strong>t <strong>de</strong> son appel, le pointeur global <strong>OS</strong>TCBCur pointe sur le TCB <strong>de</strong> la<br />

tâche <strong>en</strong> cours d’exécution, alors que <strong>OS</strong>TCBHighRdy pointe sur le TCB <strong>de</strong> la<br />

nouvelle tâche plus prioritaire. Nous n’utiliserons ici que le premier pointeur.<br />

Le champ <strong>OS</strong>TCBExtPtr <strong>de</strong> la structure TCB conti<strong>en</strong>t la structure <strong>de</strong> donnée qui lui<br />

est passée <strong>en</strong> paramètre à la création par la fonction <strong>OS</strong>TaskCreateExt().<br />

C’est cette structure <strong>de</strong> donnée que nous allons utiliser pour mémoriser les<br />

informations dynamiques sur chaque tâche.<br />

Le principe est donc le suivant<br />

• Déclaration d’une structure <strong>de</strong> données TASK_USER_DATA<br />

mémorisant les informations mesurées (déjà écrite <strong>en</strong> tête <strong>de</strong><br />

fichier). Mettre <strong>de</strong>s comm<strong>en</strong>taires pour chaque champ <strong>de</strong> la<br />

structure.<br />

• Passage <strong>de</strong> cette structure <strong>de</strong> données <strong>en</strong> 8 e paramètre <strong>de</strong> la<br />

fonction <strong>OS</strong>TaskCreateExt() jusqu’à prés<strong>en</strong>t laissé à un pointeur<br />

vi<strong>de</strong>.<br />

• Mise à jour <strong>de</strong>s champs <strong>de</strong> cette structure par la fonction<br />

<strong>OS</strong>TaskSwHook à chaque changem<strong>en</strong>t <strong>de</strong> contexte.<br />

• Le temps d’exécution <strong>de</strong> chaque tâche est obt<strong>en</strong>u <strong>en</strong> lancant la<br />

fonction PC_ElapsedStart() à la fin <strong>de</strong> la fonction<br />

<strong>OS</strong>TaskSwHook() et <strong>en</strong> récupérant un INT16U <strong>en</strong> valeur <strong>de</strong><br />

retour <strong>de</strong> la fonction PC_ElapsedStop().<br />

Réaliser ces modifications.<br />

Quelle est la tâche la plus longue. La priorité <strong>de</strong>s tâches appar<strong>en</strong>te est­elle conforme<br />

à celle donnée à leur création ?<br />

Que fait la tâche T1 par rapport aux autres tâches ?<br />

Pourquoi utilise­t­elle un autre mécanisme <strong>de</strong> communication que celui <strong>de</strong> la boîte<br />

aux lettres utilisé précé<strong>de</strong>mm<strong>en</strong>t ?<br />

5. Exercice 4 : Emulation d’un jeu d’instructions à virgule<br />

flottante<br />

a. Architecture cible<br />

Rechercher sur le web l’architecture <strong>du</strong> processeur <strong>de</strong> votre machine.<br />

Donner le schéma <strong>en</strong> bloque <strong>du</strong> processeur.<br />

Dispose­t­elle d’une unité <strong>de</strong> calcul <strong>en</strong> virgule flottante ?<br />

Comm<strong>en</strong>t réalise­t­on <strong>de</strong>s calculs <strong>en</strong> virgule flottante dans le cas ou le processeur<br />

n’<strong>en</strong> dispose pas.<br />

5


Université <strong>de</strong> Cergy­Pontoise<br />

6. Conclusion<br />

Dé<strong>du</strong>iser <strong>de</strong> cette expéri<strong>en</strong>ce un patron (modèle) général d’écriture d’applications <strong>sous</strong><br />

<strong>uC</strong><strong>OS</strong>.<br />

Ce patron doit être indép<strong>en</strong>dant <strong>de</strong> l’application visée et doit <strong>en</strong>suite pouvoir être rempli <strong>de</strong><br />

manière à répondre aux besoins <strong>de</strong> l’application.<br />

Lancer à nouveau un <strong>de</strong> vos exécutables. Au cours <strong>de</strong> son exécution et sans l’interrompre,<br />

lancer égalem<strong>en</strong>t le gestionnaire <strong>de</strong> tâches <strong>de</strong> Windows. Quelle est l’utilisation <strong>du</strong><br />

processeur ? Quelle l’utilisation CPU occupé par le co<strong>de</strong> <strong>uC</strong><strong>OS</strong> ? Que dé<strong>du</strong>isez­vous <strong>de</strong> ces<br />

mesures <strong>du</strong> fonctionnem<strong>en</strong>t <strong>de</strong> <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong> <strong>sous</strong> un <strong>en</strong>vironnem<strong>en</strong>t PC.<br />

7. Annexe A : Fonctions <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong><br />

PC_VectSet(() Fixe le vecteur d'interruption: premier paramètre<br />

est le numéro d'interruption, second paramètre<br />

est le pointeur sur le handler d'interruption.<br />

PC_SetTickRate() Modifie l'unité <strong>de</strong> mesure temporel <strong>de</strong> l'<strong>OS</strong><br />

(standard: 18.20648Hz)<br />

<strong>OS</strong>MboxP<strong>en</strong>d Susp<strong>en</strong>d une tâche <strong>en</strong> att<strong>en</strong>te <strong>de</strong> message (dans<br />

une boîte aux lettres) tant qu'elle ne l'a pas reçu.<br />

<strong>OS</strong>MboxPost() Envoie un message<br />

<strong>OS</strong>Init() Doit être appelé avant toute autre fonction <strong>de</strong><br />

l’<strong>OS</strong>. Elle créée 2 tâches : 1 Tâche Idle et 1<br />

Tâche statistique<br />

<strong>OS</strong>SemCreate() Crée un sémaphore et retourne un pointeur sur<br />

une structure <strong>de</strong> type <strong>OS</strong>_EVENT<br />

<strong>OS</strong>TaskCreate() Création <strong>de</strong> tâche<br />

Argum<strong>en</strong>ts : pointeur sur le co<strong>de</strong> <strong>de</strong> la tâche,<br />

pointeur sur les données d’initialisation,<br />

pointeur sur la pile utilisée, taille <strong>de</strong> la pile,<br />

priorité <strong>de</strong> la tâche<br />

<strong>OS</strong>Start() Lance l’<strong>OS</strong> : création <strong>de</strong>s structures <strong>de</strong> données,<br />

lancem<strong>en</strong>t <strong>du</strong> sche<strong>du</strong>ler<br />

<strong>OS</strong>StatInit() Initialise les statistiques relatives à <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong>.<br />

PC_DispChar() Affiche un caractère quelque part dans une<br />

f<strong>en</strong>être D<strong>OS</strong> (position <strong>en</strong> premier et second<br />

argum<strong>en</strong>t, caractère à afficher <strong>en</strong> troisième et<br />

couleurs <strong>en</strong> <strong>de</strong>rnier)<br />

<strong>OS</strong>TimeDly retar<strong>de</strong> une tâche <strong>de</strong> N unités <strong>de</strong> mesure<br />

temporel (cf PC_SetTickRate()), N étant passé<br />

6


Université <strong>de</strong> Cergy­Pontoise<br />

<strong>en</strong> argum<strong>en</strong>t.<br />

<strong>OS</strong>TimeDlyHMSM(int,int,int,int) même fonctionnalité que <strong>OS</strong>TimeDly mais <strong>en</strong><br />

heures/minutes/secon<strong>de</strong>s/millisecon<strong>de</strong>s<br />

<strong>OS</strong>SemP<strong>en</strong>d(*<strong>OS</strong>_EVENT, INT16U, INT8U) <strong>Prise</strong> <strong>de</strong> semaphore : premier paramètre est un<br />

pointeur sur l’évènem<strong>en</strong>t, 2 e paramètre est un<br />

timeout, 3 e paramètre est un co<strong>de</strong> d'erreur :<br />

<strong>OS</strong>_NO_ERR si le sémaphore est dispo<br />

<strong>OS</strong>_TIMEOUT si le sémaphore n'est pas relâché<br />

avant le timeout spécifié<br />

<strong>OS</strong>_ERR_EVENT_TYP si le premier argum<strong>en</strong>t<br />

ne pointe pas vers un sémaphore<br />

<strong>OS</strong>_ERR_PEVENT_NULL si le premier<br />

argum<strong>en</strong>t est NULL.<br />

<strong>OS</strong>emPost(*<strong>OS</strong>_EVENT) Relâche le sémaphore<br />

<strong>OS</strong>TimeDly(int) La tâche s’<strong>en</strong>dort (état WAITING) p<strong>en</strong>dant le<br />

temps donné <strong>en</strong> paramètre. (Une valeur <strong>de</strong> 1<br />

signifie 1 cycle d’horloge système)<br />

PC_DispClrScr() Fonction <strong>de</strong> réinitialisation <strong>de</strong> l’écran (D<strong>OS</strong>)<br />

PC_DispStr() Affiche une chaîne <strong>de</strong> caractère quelque part à<br />

l’écran<br />

PC_D<strong>OS</strong>SaveReturn() Sauvegar<strong>de</strong> l'<strong>en</strong>vironnem<strong>en</strong>t D<strong>OS</strong> avant le retour<br />

<strong>en</strong> mo<strong>de</strong> console<br />

PC_D<strong>OS</strong>Return Permet <strong>de</strong> rev<strong>en</strong>ir <strong>en</strong> mo<strong>de</strong> D<strong>OS</strong> (utiliser au<br />

préalable PC_D<strong>OS</strong>SaveReturn() pour<br />

sauvegar<strong>de</strong>r les registres importants <strong>du</strong><br />

<strong>OS</strong>TaskCreateExt(*<strong>OS</strong>_STK,* struct,<br />

*<strong>OS</strong>_STK,int,int,*<strong>OS</strong>_STK,sk_size)<br />

processeur pour permettre ce retour à D<strong>OS</strong>).<br />

Version ét<strong>en</strong><strong>du</strong>e <strong>de</strong> <strong>OS</strong>TaskCreateExt() pr<strong>en</strong>ant<br />

<strong>en</strong> plus les argum<strong>en</strong>ts suivants:<br />

­ id <strong>de</strong> la tâche<br />

­ l'adresse <strong>du</strong> bas <strong>de</strong> la pile<br />

­ la taille <strong>de</strong> la pile alloué pour la tâche (<strong>en</strong><br />

nombre d'élém<strong>en</strong>ts: INT8U, INT16U par<br />

exemple suivant le type que pr<strong>en</strong>d <strong>OS</strong>_STK)<br />

­ un pointeur vers une structure <strong>de</strong> données (peut<br />

cont<strong>en</strong>ir le temps que met une tâche pour<br />

s'exécuter, le cont<strong>en</strong>u <strong>de</strong> registres virgule<br />

flottante...)<br />

­ une option <strong>de</strong> partage <strong>en</strong>tre tâches :<br />

<strong>OS</strong>_TASK_OPT_STK_CHK spécifie quel<br />

contrôle <strong>de</strong> pile est permis pour la tâche<br />

<strong>OS</strong>_TASK_OPT_STK_CLR spécifie quelle pile<br />

doit être réinitialisée<br />

<strong>OS</strong>_TASK_OPT_SAVE_FP spécifie quels<br />

registres flottant sont sauvés.<br />

Cette fonction r<strong>en</strong>voie:<br />

­ soit <strong>OS</strong>_NO_ERR <strong>en</strong> cas <strong>de</strong> succès<br />

­ soit <strong>OS</strong>_PRIO_EXIST si la priorité <strong>de</strong>mandée<br />

7


Université <strong>de</strong> Cergy­Pontoise<br />

existe déjà<br />

­ <strong>OS</strong>_NO_MORE_TCB si mucos n'a plus <strong>de</strong><br />

<strong>OS</strong>_TCB à affecter.<br />

Rem: certains indices <strong>de</strong> priorité sont réservés à<br />

certains fonctions système mucos: 0,1,2,3,<br />

<strong>OS</strong>_LOWEST_PRIO­3, <strong>OS</strong>_LOWEST_PRIO­2<br />

<strong>OS</strong>_ENTER_CRITICAL() active et désactive les interruptions <strong>du</strong><br />

processeur.<br />

<strong>OS</strong>MboxCreate() crée une boîte à lettres<br />

PC_GetKey() R<strong>en</strong>voie vrai ou faux <strong>en</strong> fonction <strong>de</strong> la touche<br />

tapée sur le clavier et celle spécifiée <strong>en</strong><br />

argum<strong>en</strong>t <strong>de</strong> cette fonction.<br />

PC_ElapsedInit() Initialise le processus <strong>de</strong> mesure <strong>de</strong> temps<br />

PC_ElapsedStart() Démarrage <strong>de</strong> la mesure <strong>de</strong> temps d’exécution<br />

d’une portion <strong>de</strong> co<strong>de</strong><br />

PC_ElapsedStop() Fin <strong>de</strong> la mesure <strong>de</strong> temps<br />

<strong>OS</strong>TaskStkChk() R<strong>en</strong>voie <strong>de</strong>s informations relatives à la pile<br />

d'exécution:<br />

premier argum<strong>en</strong>t: indice <strong>de</strong> priorité <strong>de</strong> la tâche<br />

second argum<strong>en</strong>t: pointeur sur la donnée <strong>de</strong> type<br />

<strong>OS</strong>_STK_DATA cont<strong>en</strong>ant les champs suivants:<br />

­ INT32U <strong>OS</strong>Free (nb d'octets dispos sur la pile)<br />

­ INT32U <strong>OS</strong>Used (nb d’octets utilisés par la<br />

pile)<br />

<strong>OS</strong>QP<strong>en</strong>d Susp<strong>en</strong>d une tâche <strong>en</strong> att<strong>en</strong>te <strong>de</strong> message (d'une<br />

file d’att<strong>en</strong>te) tant qu'elle ne l'a pas reçu.<br />

<strong>OS</strong>QPost Envoie un message à une autre tâche au moy<strong>en</strong><br />

d'une file d’att<strong>en</strong>te<br />

PC_GetDateTime() Donne l'heure et la date <strong>du</strong> PC<br />

8


Université <strong>de</strong> Cergy­Pontoise<br />

8. Annexe B : Co<strong>de</strong> <strong>de</strong> l’exercice 1<br />

/*<br />

****************************************************************************************<br />

* <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong><br />

*<br />

*****************************************************************************************<br />

*/<br />

#inclu<strong>de</strong> "inclu<strong>de</strong>s.h"<br />

/*<br />

****************************************************************************************<br />

* CONSTANTS<br />

******************************************************************************************<br />

*/<br />

#<strong>de</strong>fine TASK_STK_SIZE 512 /* Size of each task's stacks (# of WORDs) */<br />

#<strong>de</strong>fine N_TASKS 10 /* Number of id<strong>en</strong>tical tasks */<br />

/*<br />

******************************************************************************************<br />

* VARIABLES<br />

******************************************************************************************<br />

*/<br />

<strong>OS</strong>_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* Tasks stacks */<br />

<strong>OS</strong>_STK TaskStartStk[TASK_STK_SIZE];<br />

char TaskData[N_TASKS]; /* Parameters to pass to each task */<br />

<strong>OS</strong>_EVENT *RandomSem;<br />

/*<br />

******************************************************************************************<br />

* FUNCTION PROTOTYPES<br />

******************************************************************************************<br />

*/<br />

void Task(void *data); /* Function prototypes of tasks */<br />

void TaskStart(void *data); /* Function prototypes of Startup task */<br />

static void TaskStartCreateTasks(void);<br />

static void TaskStartDispInit(void);<br />

static void TaskStartDisp(void);<br />

/*<br />

******************************************************************************************<br />

* MAIN<br />

******************************************************************************************<br />

*/<br />

void <strong>main</strong> (void)<br />

{<br />

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* */<br />

<strong>OS</strong>Init(); /* */<br />

PC_D<strong>OS</strong>SaveReturn(); /* */<br />

PC_VectSet(<strong>uC</strong><strong>OS</strong>, <strong>OS</strong>CtxSw); /* */<br />

RandomSem = <strong>OS</strong>SemCreate(1); /* */<br />

<strong>OS</strong>TaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE ­ 1], 0);<br />

<strong>OS</strong>Start(); /* */<br />

9


Université <strong>de</strong> Cergy­Pontoise<br />

}<br />

/*<br />

******************************************************************************************<br />

* STARTUP TASK<br />

******************************************************************************************<br />

*/<br />

void TaskStart (void *pdata)<br />

{<br />

#if <strong>OS</strong>_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */<br />

<strong>OS</strong>_CPU_SR cpu_sr;<br />

#<strong>en</strong>dif<br />

char s[100];<br />

INT16S key;<br />

}<br />

pdata = pdata; /* Prev<strong>en</strong>t compiler warning */<br />

TaskStartDispInit(); /* Initialize the display */<br />

<strong>OS</strong>_ENTER_CRITICAL();<br />

PC_VectSet(0x08, <strong>OS</strong>TickISR); /* */<br />

PC_SetTickRate(<strong>OS</strong>_TICKS_PER_SEC); /* */<br />

<strong>OS</strong>_EXIT_CRITICAL();<br />

<strong>OS</strong>StatInit(); /* Initialize <strong>uC</strong>/<strong>OS</strong>­<strong>II</strong>'s statistics */<br />

TaskStartCreateTasks(); /* */<br />

for (;;) {<br />

TaskStartDisp(); /* Update the display */<br />

}<br />

if (PC_GetKey(&key) == TRUE) { /* See if key has be<strong>en</strong> pressed */<br />

if (key == 0x1B) { /* Yes, see if it's the ESCAPE key */<br />

PC_D<strong>OS</strong>Return(); /* */<br />

}<br />

}<br />

<strong>OS</strong>CtxSwCtr = 0; /* Clear context switch counter */<br />

<strong>OS</strong>TimeDlyHMSM(0, 0, 1, 0); /* */<br />

/*<br />

***************************************************************************************<br />

* CREATE TASKS<br />

*****************************************************************************************<br />

*/<br />

static void TaskStartCreateTasks (void)<br />

{<br />

INT8U i;<br />

for (i = 0; i < N_TASKS; i++) { /* Create N_TASKS id<strong>en</strong>tical tasks */<br />

TaskData[i] = '0' + i; /* Each task will display its own letter */<br />

<strong>OS</strong>TaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE ­ 1], i + 1);<br />

10


Université <strong>de</strong> Cergy­Pontoise<br />

}<br />

}<br />

/*<br />

******************************************************************************************<br />

* TASKS<br />

******************************************************************************************<br />

*/<br />

void Task (void *pdata)<br />

{<br />

INT8U x;<br />

INT8U y;<br />

INT8U err;<br />

}<br />

for (;;) {<br />

<strong>OS</strong>SemP<strong>en</strong>d(RandomSem, 0, &err); /* Acquire semaphore to perform random numbers */<br />

x = random(80); /* Find X position where task number will appear */<br />

y = random(16); /* Find Y position where task number will appear */<br />

<strong>OS</strong>SemPost(RandomSem); /* Release semaphore */<br />

/* Display the task number on the scre<strong>en</strong> */<br />

PC_DispChar(x, y + 5, *(char *)pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);<br />

<strong>OS</strong>TimeDly(1); /* Delay 1 clock tick */<br />

}<br />

11

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!