You are on page 1of 11

Universit de Cergy-Pontoise

TP de prise en main de uC/OS-II Le noyau temps rel


Informatique Embarque

1. Introduction
a. Le noyau temps rel uC/OS-II uC/OS (ou microC/OS) est un systme dexploitation temps rel multi-tches premptif. Dvelopp par le Canadien Jean J. Labrosse, uC/OS est un excutif temps rel destin des environnements de trs petite taille construits autour de Microcontrleurs. Il est maintenant disponible sur un grand nombre de processeurs et peut intgrer des protocoles standards comme TCP/IP (C/IP) pour assurer une connectivit IP sur une liaison srie par PPP. Il est utilisable gratuitement pour l'enseignement. Il est aujourdhui dvelopp et maintenu par la socit Micrium : http://www.ucos-ii.com/ uC/OS est dvelopp en C, sauf en ce qui concerne les portions de code qui sont cibledpendant (portage), comme limplantation des oprations de changement de contexte qui sont crites en assembleur. uC/OS fait partie des nombreux systmes dexploitation temps rel aujourdhui disponibles sur le march : Adeos, ChorusOS, eCos, ITRON, LynxOS, MicroC/OS-II, Nucleus, OS-9, OSE, OSEK/VDX, pSOS, QNX, RSX-11, RT-11, RTOS-UH, SCIOPTA, VRTX, VxWorks, Windows CE, RTLinux, RTAI

b. Objectif de la sance i. Objectif Lobjectif de la sance de TP est la prise en main des commandes de base (API1) dun RTOS et de comprendre le principe fondamental de fonctionnement de ce type de systme. uCOS tant un exemple reprsentatif du fonctionnement dun RTOS, le travail ralis sous cet environnement serait facilement instanciable avec un autre systme dexploitation. Cette introduction au dveloppement dapplications embarques temps rel commence par une utilisation de lOS sur PC mais sera ensuite suivi dune utilisation sur une carte de dveloppement embarque. La comprhension des mcanismes de base est donc primordiale pour la suite des TPs. A ce titre, vous devrez lissue des sances de TP raliser une soutenance sur les manipulations, dveloppements et tests que vous aurez raliss. ii. Soutenance 10 minutes de soutenance seront alloues par personne plus 5 minutes de questions. Lors de cette soutenance, il vous sera demand une ou deux dmonstrations sur les 7 exercices raliss. Vous devrez pour chacune expliquer le code de lexercice. Des
1

Application Protocole Interface

Universit de Cergy-Pontoise questions sont pour cela insres dans ce sujet pour vous guider dans la comprhension du systme uC/OS. Cette soutenance devra rendre compte de la particularit du dveloppement dans un cadre temps rel dune part et embarqu dautre part. Par ailleurs en tant que dveloppeur dapplications temps rel au sein de lquipe de dveloppement pdagogique du Dpartement Sciences Informatiques, vous pourrez si ncessaire rendre compte des problmes techniques rencontrs, des limites et contraintes de lenvironnement de dveloppement actuel, et des ventuels Buggs rencontrs faire corriger par lquipe de dveloppement des Outils dexploitation. c. Environnement de dveloppement Vous allez au cours de ces sances prendre connaissance de 2 environnements de dveloppement selon que lapplication que lon cherche implanter sera destine une excution sur PC ou une excution embarque. Lenvironnement de dveloppement sur PC est directement li au langage de programmation utilis pour dvelopper des applications sous uCOS : le langage C. Vous pourrez donc utiliser pour le dveloppement des programmes lditeur de votre choix. Le compilateur C est quand lui soumis quelques contraintes. En effet, les librairies de fonctions uC/OS-II disponibles lUniversit ont t dveloppes et compiles avec BorlandC/C++ version 4.51 pour Windows. Ce compilateur payant nest pas disponible lUniversit. Aussi lOS a-t-il t port pour une version antrieure du compilateur Borland, la version TCPP1.01. Lenvironnement minimal de dveloppement est lutilisation dun logiciel ddition de texte pour la programmation et le lancement des commandes de compilation par commandes DOS. Vous pouvez selon les logiciels de votre PC utiliser un environnement de dveloppement paramtr pour faire appel aux commandes du compilateur (make, cc, asm). Le compilateur est install dans le rprtoire c:\TOOLS\TCPP101\
Si ce nest pas le cas, dcompresser larchive prsente sur http://www-etis.ensea.fr/Members/bmiramond/Cours/M1/UEF5.html cet emplacement.

Vos rpertoires de travail seront situs dans c:\SOFTWARE\UCOS-II\. Ce rpertoire sera dsign dans la suite par $WORK_DIR. d. Les primitives utiles de la librairie uC/OS-II Vous trouverez en annexe la fin de ce document les fonctions C principales de la librairie ucos_ii (API). Note : En cours de TP, vous pouvez demander un livre uC/OS-II disponible dans les armoires de la salle pour le dtail de certains appels ou paramtres dappel lAPI.

2. Exercice 1 : Concurrence de tches


a. Un modle de code Vous trouverez dans le rpertoire $WORK_DIR\EX1_X86L\TCPP101\TEST les fichiers ncessaires la compilation du premier exercice : Test.mak (Makefile), Maketest.bat (script). 2

Universit de Cergy-Pontoise Pour lancer la compilation, vous devez lancer le script Maketest.bat. Laffichage qui apparat nest pas complet, ce sera vous de complter le code et de comprendre sa fonctionnalit. Vous trouverez pour cela dans lannexe B le code complet de lapplication temps rel simple dveloppe avec les fonctions de la librairie ucos_ii. Lobjectif de ce premier exercice est tout dabord de comprendre la structure dun programme sous cet environnement, puis danalyser lutilit des fonctions uCOS. Pour satisfaire au premier objectif, la premire tape de ce TP est de recopier le code fourni en annexe dans le fichier test.c prsent dans $WORK_DIR\EX1_X86L\TCPP101\SOURCE Au cours de lcriture du code, vous placerez des commentaires indiquant la fonctionnalit des fonctions de lOS en vous aidant de lannexe A. Dautres fichiers sont dj prsents dans ce rpertoire comme Include.h et Os_cfg.h. b. Analyse du code Aprs avoir correctement compil le code et raliser son excution, vous allez maintenant procder aux modifications suivantes : Enlever lappel la fonction PCDosSaveReturn() dans la fonction main. Recompiler et excuter. Que se passe-t-il ? Expliquer pourquoi. En quoi lutilisation de uCOS sur PC est-elle diffrente dune utilisation sur plateforme embarque ?

3. Exercice 2 : Mesure de taille de pile dexcution


a. Comprhension de code Vous allez maintenant dans le rpertoire $WORK_DIR\EX2_x86l\TCPP101\ Vous y retrouvez la mme organisation que dans lexemple prcdent. Compiler le code et excuter lapplication. Observer ce qui se passe. Identifier le problme. Vous allez maintenant entrer dans le code (rpertoire SOURCE) et crire la fonction daffichage TaskStartDispInit() de manire ce quun utilisateur comprenne les donnes brutes affiches lcran. Vous devez pour cela partir du code dj prsent comprendre la nature des informations affiches et vous inspirer du code de lexercice 1 pour apporter des indications laffichage. Cette application est compose de 9 tches, que font chacune de ces tches ? b. Analyse de comportement Cet exercice fait appel la fonction OSTaskStkChk() qui ralise des vrifications et des mesures de taille de la pile dexcution. Lanalyse de pile dexcution est primordiale en informatique embarqu et en temps rel lorsque lon ne connat pas de manire statique et dterministe la place mmoire utilise par chaque tche. Dans ce cas, une solution est dallouer plus de place que ncessaire et de laisser uC/OSII mesurer la pile rellement utilise. Pour cela lapplication doit tre lance

Universit de Cergy-Pontoise suffisamment longtemps pour tre reprsentative dune excution en environnement rel. Votre mesure finale doit pouvoir sadapter des variations non prvues de lenvironnement. Une marge de 15 20 % est donc ncessaire. Dans les applications critiques, une marge de 100% est indispensable. Aprs mesure, adapter la taille de pile de chaque tche et vrifier le bon comportement du systme. Que se passe-t-il si la taille de pile alloue est insuffisante ? La fonction OSTaskStckChk() rempli lespace rserv pour la pile de valeurs nulles la cration de chaque tche. La vrification et la mesure de la taille de pile commence au bas de la pile (pointeur Bottom Of Stack : BOS). En avanant dans la pile le pointeur est incrment jusqu trouver une entre non nulle. Le compteur donne le nombre demplacements utiliss. Cette vrification prends du temps et nest donc utilise quen cours de dveloppement et danalyse de code. Une fois implante sur cible, ces vrifications sont supprimes. A vous de mesurer le cot en temps dexcution de cette vrification en utilisant successivement les fonctions PC_ElapsedStart() et PC_ElapsedStop() (cf. Annexe). c. Communications entre tches uCOS permet videmment de faire communiquer des tches entre elles, par exemple en envoyant des messages par lintermdiaire dune bote aux lettres (mailbox). Nous allons ici faire communiquer les tches 4 et 5 : T4 envoie un message T5 et T5 rpondra T4 en lui envoyant un Ack(nowledge). Pour cela nous avons besoin de crer 2 mailboxes qui permettent de contenir un (et un seul) pointeur sur une donne. Cette donne est spcifique lapplication et doit tre dfinie en commun par lexpditeur et le destinataire. Les tapes pour faire communiquer T4 et T5 sont simples : Dclarer 2 mailboxes en variables globales. Ce sont des pointeurs sur des OS_EVENT Crer les 2 mailboxes par la fonction OSMboxCreate (void *) qui retourne un pointeur sur les structures mailbox Dans les fonctions T4 et T5 utiliser les fonctions denvoie OSMboxPost() et dattente OSMboxPend() pour que T4 envoie un caractre qui change chaque Ack reu de A Z de manire circulaire. T5 affichera ce caractre.

4. Exercice 3 : Analyse de temps dexcution


a. Mesure de temps dexcution Les sources de lexercice 3 sont dans $WORK_DIR\EX3_x86L\TCPP101\SOURCE. Lobjectif de cet exercice est inverse celui de lexercice prcdent. La fonction daffichage TaskStartDispInit() est crite. Elle indique diffrentes mesures pour les tches de lapplication. Combien de tches composent lapplication. Quelles sont les mesures que doit afficher lexcution. Votre objectif est dutiliser les commandes uCOS pour donner ces mesures laffichage de donnes actuellement constantes.

Universit de Cergy-Pontoise uCOS est un OS ouvert au sens ou le code source de lOS est fourni et modifiable par les utilisateurs. Nous allons ici utiliser cette proprit pour raliser nos mesures en ajoutant cette fonctionnalit par lintermdiaire des fonctions appeles Hook. 9 fonctions Hook existent. Nous aurons pour notre cas uniquement besoin de modifier la fonction OSTaskSwHook. Celle-ci est appell par lOS au moment de chaque changement de contexte. Au moment de son appel, le pointeur global OSTCBCur pointe sur le TCB de la tche en cours dexcution, alors que OSTCBHighRdy pointe sur le TCB de la nouvelle tche plus prioritaire. Nous nutiliserons ici que le premier pointeur. Le champ OSTCBExtPtr de la structure TCB contient la structure de donne qui lui est passe en paramtre la cration par la fonction OSTaskCreateExt(). Cest cette structure de donne que nous allons utiliser pour mmoriser les informations dynamiques sur chaque tche. Le principe est donc le suivant Dclaration dune structure de donnes TASK_USER_DATA mmorisant les informations mesures (dj crite en tte de fichier). Mettre des commentaires pour chaque champ de la structure. Passage de cette structure de donnes en 8e paramtre de la fonction OSTaskCreateExt() jusqu prsent laiss un pointeur vide. Mise jour des champs de cette structure par la fonction OSTaskSwHook chaque changement de contexte. Le temps dexcution de chaque tche est obtenu en lancant la fonction PC_ElapsedStart() la fin de la fonction OSTaskSwHook() et en rcuprant un INT16U en valeur de retour de la fonction PC_ElapsedStop(). Raliser ces modifications. Quelle est la tche la plus longue. La priorit des tches apparente est-elle conforme celle donne leur cration ? Que fait la tche T1 par rapport aux autres tches ? Pourquoi utilise-t-elle un autre mcanisme de communication que celui de la bote aux lettres utilis prcdemment ?

5. Exercice 4 : Emulation dun jeu dinstructions virgule flottante


a. Architecture cible Rechercher sur le web larchitecture du processeur de votre machine. Donner le schma en bloque du processeur. Dispose-t-elle dune unit de calcul en virgule flottante ? Comment ralise-t-on des calculs en virgule flottante dans le cas ou le processeur nen dispose pas.

Universit de Cergy-Pontoise

6. Conclusion
Dduiser de cette exprience un patron (modle) gnral dcriture dapplications sous uCOS. Ce patron doit tre indpendant de lapplication vise et doit ensuite pouvoir tre rempli de manire rpondre aux besoins de lapplication. Lancer nouveau un de vos excutables. Au cours de son excution et sans linterrompre, lancer galement le gestionnaire de tches de Windows. Quelle est lutilisation du processeur ? Quelle lutilisation CPU occup par le code uCOS ? Que dduisez-vous de ces mesures du fonctionnement de uC/OS-II sous un environnement PC.

7.

Annexe A : Fonctions uC/OS-II


Fixe le vecteur d'interruption: premier paramtre est le numro d'interruption, second paramtre est le pointeur sur le handler d'interruption. Modifie l'unit de mesure temporel de l'OS (standard: 18.20648Hz) Suspend une tche en attente de message (dans une bote aux lettres) tant qu'elle ne l'a pas reu. Envoie un message Doit tre appel avant toute autre fonction de lOS. Elle cre 2 tches : 1 Tche Idle et 1 Tche statistique Cre un smaphore et retourne un pointeur sur une structure de type OS_EVENT Cration de tche Arguments : pointeur sur le code de la tche, pointeur sur les donnes dinitialisation, pointeur sur la pile utilise, taille de la pile, priorit de la tche Lance lOS : cration des structures de donnes, lancement du scheduler Initialise les statistiques relatives uC/OS-II. Affiche un caractre quelque part dans une fentre DOS (position en premier et second argument, caractre afficher en troisime et couleurs en dernier) retarde une tche de N units de mesure temporel (cf PC_SetTickRate()), N tant pass

PC_VectSet(()

PC_SetTickRate() OSMboxPend OSMboxPost() OSInit()

OSSemCreate() OSTaskCreate()

OSStart() OSStatInit() PC_DispChar()

OSTimeDly

Universit de Cergy-Pontoise en argument. mme fonctionnalit que OSTimeDly mais en heures/minutes/secondes/millisecondes Prise de semaphore : premier paramtre est un pointeur sur lvnement, 2e paramtre est un timeout, 3e paramtre est un code d'erreur : OS_NO_ERR si le smaphore est dispo OS_TIMEOUT si le smaphore n'est pas relch avant le timeout spcifi OS_ERR_EVENT_TYP si le premier argument ne pointe pas vers un smaphore OS_ERR_PEVENT_NULL si le premier argument est NULL. Relche le smaphore La tche sendort (tat WAITING) pendant le temps donn en paramtre. (Une valeur de 1 signifie 1 cycle dhorloge systme) Fonction de rinitialisation de lcran (DOS) Affiche une chane de caractre quelque part lcran Sauvegarde l'environnement DOS avant le retour en mode console Permet de revenir en mode DOS (utiliser au pralable PC_DOSSaveReturn() pour sauvegarder les registres importants du processeur pour permettre ce retour DOS). Version tendue de OSTaskCreateExt() prenant en plus les arguments suivants: - id de la tche - l'adresse du bas de la pile - la taille de la pile allou pour la tche (en nombre d'lments: INT8U, INT16U par exemple suivant le type que prend OS_STK) - un pointeur vers une structure de donnes (peut contenir le temps que met une tche pour s'excuter, le contenu de registres virgule flottante...) - une option de partage entre tches : OS_TASK_OPT_STK_CHK spcifie quel contrle de pile est permis pour la tche OS_TASK_OPT_STK_CLR spcifie quelle pile doit tre rinitialise OS_TASK_OPT_SAVE_FP spcifie quels registres flottant sont sauvs. Cette fonction renvoie: - soit OS_NO_ERR en cas de succs - soit OS_PRIO_EXIST si la priorit demande

OSTimeDlyHMSM(int,int,int,int) OSSemPend(*OS_EVENT, INT16U, INT8U)

OSemPost(*OS_EVENT) OSTimeDly(int)

PC_DispClrScr() PC_DispStr() PC_DOSSaveReturn() PC_DOSReturn

OSTaskCreateExt(*OS_STK,* struct, *OS_STK,int,int,*OS_STK,sk_size)

Universit de Cergy-Pontoise existe dj - OS_NO_MORE_TCB si mucos n'a plus de OS_TCB affecter. Rem: certains indices de priorit sont rservs certains fonctions systme mucos: 0,1,2,3, OS_LOWEST_PRIO-3, OS_LOWEST_PRIO-2 active et dsactive les interruptions du processeur. cre une bote lettres Renvoie vrai ou faux en fonction de la touche tape sur le clavier et celle spcifie en argument de cette fonction. Initialise le processus de mesure de temps Dmarrage de la mesure de temps dexcution dune portion de code Fin de la mesure de temps Renvoie des informations relatives la pile d'excution: premier argument: indice de priorit de la tche second argument: pointeur sur la donne de type OS_STK_DATA contenant les champs suivants: - INT32U OSFree (nb d'octets dispos sur la pile) - INT32U OSUsed (nb doctets utiliss par la pile) Suspend une tche en attente de message (d'une file dattente) tant qu'elle ne l'a pas reu. Envoie un message une autre tche au moyen d'une file dattente Donne l'heure et la date du PC

OS_ENTER_CRITICAL() OSMboxCreate() PC_GetKey()

PC_ElapsedInit() PC_ElapsedStart() PC_ElapsedStop() OSTaskStkChk()

OSQPend OSQPost PC_GetDateTime()

Universit de Cergy-Pontoise

8. Annexe B : Code de lexercice 1


/* **************************************************************************************** * uC/OS-II * ***************************************************************************************** */ #include "includes.h" /* **************************************************************************************** * CONSTANTS ****************************************************************************************** */ #define TASK_STK_SIZE 512 /* Size of each task's stacks (# of WORDs) */ #define N_TASKS 10 /* Number of identical tasks */ /* ****************************************************************************************** * VARIABLES ****************************************************************************************** */ OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* Tasks stacks */ OS_STK TaskStartStk[TASK_STK_SIZE]; char TaskData[N_TASKS]; /* Parameters to pass to each task */ OS_EVENT *RandomSem; /* ****************************************************************************************** * FUNCTION PROTOTYPES ****************************************************************************************** */ void Task(void *data); /* Function prototypes of tasks */ void TaskStart(void *data); /* Function prototypes of Startup task */ static void TaskStartCreateTasks(void); static void TaskStartDispInit(void); static void TaskStartDisp(void); /* ****************************************************************************************** * MAIN ****************************************************************************************** */ void main (void) { PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* */ OSInit(); PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw); RandomSem = OSSemCreate(1); /* */ /* */ /* */ /* */

OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0); OSStart(); /* */

Universit de Cergy-Pontoise
}

/* ****************************************************************************************** * STARTUP TASK ****************************************************************************************** */ void TaskStart (void *pdata) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif char s[100]; INT16S key;

pdata = pdata; TaskStartDispInit();

/* Prevent compiler warning /* Initialize the display */

*/

OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); OSStatInit(); TaskStartCreateTasks(); for (;;) { TaskStartDisp();

/* */ /* */

/* Initialize uC/OS-II's statistics /* */

*/

/* Update the display

*/

if (PC_GetKey(&key) == TRUE) { if (key == 0x1B) { PC_DOSReturn(); } } OSCtxSwCtr = 0; OSTimeDlyHMSM(0, 0, 1, 0); } }

/* See if key has been pressed /* Yes, see if it's the ESCAPE key */ /* */

*/

/* Clear context switch counter /* */

*/

/* *************************************************************************************** * CREATE TASKS ***************************************************************************************** */ static void TaskStartCreateTasks (void) { INT8U i;

for (i = 0; i < N_TASKS; i++) { /* Create N_TASKS identical tasks */ TaskData[i] = '0' + i; /* Each task will display its own letter */ OSTaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE - 1], i + 1);

10

Universit de Cergy-Pontoise
} }

/* ****************************************************************************************** * TASKS ****************************************************************************************** */ void Task (void *pdata) { INT8U x; INT8U y; INT8U err;

for (;;) { OSSemPend(RandomSem, 0, &err); /* Acquire semaphore to perform random numbers */ x = random(80); /* Find X position where task number will appear */ y = random(16); /* Find Y position where task number will appear */ OSSemPost(RandomSem); /* Release semaphore */ /* Display the task number on the screen */ PC_DispChar(x, y + 5, *(char *)pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); OSTimeDly(1); /* Delay 1 clock tick */ } }

11

You might also like