RTX
RTX
RTX
******************
Support de formation
RTX 8.1
Extension temps rel
pour les systmes dexploitation Windows 2000, Windows XP et Windows Vista
******************
Pierre BLANDIN
UE UE
mixte mixte
Support de formation
RTX 8.1
Extension temps rel
pour les systmes dexploitation Windows 2000, Windows XP et Windows Vista
Prsentation de RTX Environnement de dveloppement Processus et threads Allocation de mmoire dterministe Synchronisation et communication inter-processus Horloges et timers Gestion des entres/sorties
********
Pierre BLANDIN
CNAM Laboratoire dAutomatique 21 rue Pinel 75013 PARIS
Rfrences
De la socit INTERVALZERO (anciennement Ardence) :
RTX Documentation du RTX 8.1.1 Evaluation SDK Site web de IntervalZero : http://www.intervalzero.com/index.htm
INTERVALZERO Europe :
ABS - Porte de l'Arnas, Hall C 455 Promenade des Anglais 06299 Nice Cedex 3 Tl : 04 89 06 60 10 FAX : 04 89 06 60 20 Contact : Fabrice BOISSET
[email protected]
Sommaire
INTRODUCTION ...................................................................................................................................7 1. PRSENTATION DE RTX .............................................................................................................9 1.1 1.2 1.3 1.4 DESCRIPTION GNRALE DE RTX ...................................................................................................9 STRUCTURE DE RTX .....................................................................................................................10 ARCHITECTURE INTERNE DU SOUS SYSTME RTSS .......................................................................11 CARACTRISTIQUES DES OBJETS RTSS .........................................................................................12
2. ENVIRONNEMENT DE DVELOPPEMENT ..........................................................................13 2.1 APPLICATION PROGRAMMING INTERFACE (API) ..........................................................................13 2.1.1 Panorama de lAPI temps rel (RTAPI) ..............................................................................13 2.1.2 Panorama de lAPI Win32 supporte par RTX.....................................................................14 2.1.3 Panorama de la bibliothque dexcution du C supporte par RTX.....................................14 2.2 PROCESSUS WIN32 ET PROCESSUS RTSS.....................................................................................14 2.2.1 Structure dune application temps rel utilisant RTX ...........................................................15 2.2.2 Fichiers excutables RTX .....................................................................................................15 2.2.3 Utilisation de larithmtique flottante...................................................................................15 2.3 UTILISATION DE MS VISUAL STUDIO POUR DVELOPPER DES APPLICATIONS RTX..........................15 2.3.1 Entre des chemins daccs aux fichiers .h et .lib de RTX....................................................16 2.3.2 Cration dun projet avec RTX .............................................................................................16 2.3.3 Dfinition du paramtre de taille de pile ..............................................................................17 2.3.4 Installation du Developper Studio Add-in.............................................................................17 2.3.5 Configuration de Visual Studio pour lancer un processus RTSS ..........................................17 3. PROCESSUS ET THREADS ........................................................................................................19 3.1 RAPPEL SUR LES PROCESSUS ET THREADS WINDOWS ...............................................................19 3.1.1 Quest ce quun processus Windows ?..............................................................................19 3.1.2 Cration et terminaison dun thread Windows ................................................................20 3.1.3 Ordonnancement des threads Windows .............................................................................21 3.2 LES PROCESSUS ET THREADS RTSS............................................................................................22 3.2.1 Dmarrage et fermeture dun processus RTSS ................................................................23 3.2.2 Cration et terminaison dun thread RTSS ......................................................................23 3.2.3 Ordonnancement des threads RTSS...................................................................................24 3.3 LES PROCESSUS WIN32 QUI INTERAGISSENT AVEC RTX...........................................................25 3.3.1 Dveloppement dun processus Win32 RTX .........................................................................25 3.3.2 Spectre des niveaux de priorit des threads Win32 RTX ......................................................26 3.3.3 Cas des processus Win32 RTX qui sont aussi des processus GUI ........................................27 3.3.4 Cration et dmarrage dun processus RTSS depuis un processus Win32 RTX ...................27 4. ALLOCATION DE MMOIRE DTERMINISTE ..................................................................29 5. SYNCHRONISATION ET COMMUNICATION INTER-PROCESSUS (IPC).....................31 5.1 5.2 5.3 5.4 MMOIRE PARTAGE (OBJET SHARED MEMORY)..........................................................................32 SMAPHORE COMPTE (OBJET SEMAPHORE)................................................................................33 SMAPHORE DEXCLUSION MUTUELLE (OBJET MUTEX) ................................................................34 VNEMENT (OBJET EVENT) .........................................................................................................35
6. HORLOGES ET TIMERS ............................................................................................................37 6.1 LES SERVICES RELATIFS AUX HORLOGES RTX ..............................................................................37 6.1.1 Les horloges RTX..................................................................................................................37 6.1.2 Systmes monoprocesseurs avec contrleur dinterruptions programmable........................38 6.1.3 Systmes monoprocesseurs avec APIC et systmes multiprocesseurs ..................................38 6.2 LES SERVICES RELATIFS AUX TIMERS ............................................................................................39 7. GESTION DES ENTRES/SORTIES (PORT IO) .....................................................................41 7.1 CE QUE PROPOSE RTX POUR LA GESTION DES E/S.........................................................................41 7.2 LAPI RELATIF AU PORT I/O..........................................................................................................41 7.3 MAPPING DE LA MMOIRE PHYSIQUE .............................................................................................42
ANNEXE 1............................................................................................................................................ 43
CloseHandle................................................................................................................................................44 CreateThread ..............................................................................................................................................44 ExitThread ..................................................................................................................................................47 GetCurrentThread .......................................................................................................................................47 GetExitCodeThread ....................................................................................................................................48 GetLastError ...............................................................................................................................................48 ResumeThread ............................................................................................................................................49 RtCloseHandle............................................................................................................................................50 RtCreateProcess..........................................................................................................................................50 RtGetExitCodeProcess................................................................................................................................52 RtGetThreadPriority ...................................................................................................................................53 RtGetThreadTimeQuantum ........................................................................................................................53 RtOpenProcess............................................................................................................................................54 RtPrintf .......................................................................................................................................................54 RtSetThreadPriority....................................................................................................................................55 RtSetThreadTimeQuantum .........................................................................................................................56 RtSleepFt ....................................................................................................................................................56 SetLastError................................................................................................................................................57 Sleep ...........................................................................................................................................................57 SuspendThread ...........................................................................................................................................58
ANNEXE 2............................................................................................................................................ 59
RtCreateEvent.............................................................................................................................................60 RtCreateMutex............................................................................................................................................61 RtCreateSemaphore ....................................................................................................................................62 RtCreateSharedMemory .............................................................................................................................63 RtOpenEvent ..............................................................................................................................................63 RtOpenMutex .............................................................................................................................................64 RtOpenSemaphore......................................................................................................................................64 RtOpenSharedMemory ...............................................................................................................................65 RtPulseEvent ..............................................................................................................................................66 RtReleaseMutex..........................................................................................................................................66 RtReleaseSemaphore ..................................................................................................................................67 RtResetEvent ..............................................................................................................................................67 RtSetEvent ..................................................................................................................................................68 RtWaitForMultipleObjects .........................................................................................................................68 RtWaitForSingleObjet ................................................................................................................................70
ANNEXE 3............................................................................................................................................ 71
RtCancelTimer............................................................................................................................................73 RtCreateTimer ............................................................................................................................................73 RtDeleteTimer ............................................................................................................................................74 RtDisablePortIo ..........................................................................................................................................75 RtEnablePortIo ...........................................................................................................................................75 RtGetClockResolution ................................................................................................................................77 RtGetClockTime.........................................................................................................................................77 RtGetClockTimerPeriod .............................................................................................................................77 RtMapMemory ...........................................................................................................................................78 RtReadPort * (Uchar, Ushort, Ulong)......................................................................................................78 RtReadPortBuffer * (Uchar, Ushort, Ulong) ...........................................................................................79 RtSetClockTime .........................................................................................................................................80 RtSetTimer..................................................................................................................................................80 RtSetTimerRelative ....................................................................................................................................81 RtUnmapMemory .......................................................................................................................................82 RtWritePort * (Uchar, Ushort, Ulong).....................................................................................................82 RtWritePortBuffer * (Uchar, Ushort, Ulong)...........................................................................................83
Introduction
Dvelopp par la socit amricaine IntervalZero Inc., RTX se prsente comme une extension temps rel aux systmes dexploitation Windows 2000, Windows XP et Windows Vista.
Dans la suite de ce document, nous dsignerons sous le terme de Windows les systmes dexploitation Windows 2000, Windows XP et Windows Vista.
Ces systmes ont t conus comme des systmes dexploitation dusage gnral, destins avant tout tre utiliss dans les applications bureautiques interactives ou dans les systmes serveurs des applications rseau. Grce RTX, ils peuvent fonctionner la fois comme des systmes dexploitations dordre gnral et comme des systmes dexploitation temps rel. Il est donc possible de faire excuter, au standard Windows, sur la mme machine, des applications temps rel et des applications non temps rel. Base sur lAPI Win32, lAPI de RTX fournit les fonctionnalits ncessaires au dveloppement dapplications temps rel complexes.
Pourquoi Windows nest pas un systme dexploitation temps rel ? La raison principale pour laquelle Windows nest pas un systme dexploitation temps rel est que Windows nest pas un systme dterministe. En effet, les temps de latence des interruptions peuvent difficilement tre borns, le temps de masquage des interruptions est officiellement inconnu et les temps de rponse des fonctions de lAPI Win32 ne sont pas dterministes. Malgr lamlioration de son temps de rponse moyen, amlioration due laccroissement de la puissance des microprocesseurs, Windows ne peut pas, par luimme, devenir un systme dexploitation temps rel. En effet, aucune plate-forme matriel ne pourra jamais faire de Windows un systme dexploitation dterministe. Les limites de Windows pour les applications temps rel rsident en dfinitive dans : un nombre trop limit de niveaux de priorits de thread, des dcisions opaques et non dterministes en ce qui lordonnancement des threads, linversion de priorit, notamment lors du traitement des interruptions.
Pour se rendre compte des diffrences de comportement entre un processus RTSS et un processus Windows standard, lancez lapplication Rtx Demo !
Pour cela, dans le menu Dmarrer, pointez sur Programmes, puis suivez le chemin : IntervalZero >> RTX >> Tools et enfin cliquez sur RtxDemo. Consultez RTX Documentation pour une description dtaille de la dmonstration ! Pour cela, allez la rubrique : Using RTX Tools >> Measuring Timer Latencies >> RTX Demo
1 Le temps de latence dune interruption est le temps qui spare lapparition dun vnement externe et lexcution de la premire instruction du gestionnaire dinterruption associ cet vnement Cest donc le temps de prise en compte de lvnement par lapplication.
La version 8.1.1 de RTX est compatible avec Windows 2000 Service Pack 4 et avec Windows XP Service Pack 2 et 3. Extrait du RTX 8.1.1 SDK Installation Guide
... Software Requirements To use RTX, you must have a system with : One of the following operating system configurations : Windows Vista Windows 2000 Professional edition with Service Pack 4, Windows 2000 Server edition with Service Pack 4, Windows XP Professional with Service Pack 2 or 3, Windows Server 2003 with Service Pack 1 or 2, One of the following standard Microsoft HALs installed : Standard PC Advanced Configuration and power Interface (ACPI) PC MPS Multiprocessor PC ACPI Multiprocessor PC ACPI Uniprocessor PC ACPI x86-based PC Internet Explorer 5.01 or higher. Microsoft Visual Studio 6.0 Service Pack 5 or Microsoft Visual Studio .NET 2002, .NET 2003 or .NET 2003 installed if you wish to debug RTX programs with the Visual Studio IDE. NOTE : Administrator privileges are required for installing, uninstalling, and using the
RTX product.
Avant dinstaller RTX 8.1.1 sur votre ordinateur, il est conseill de prendre connaissance de la notice :
1. Prsentation de RTX
1.1 Description gnrale de RTX
RTX vient ajouter un sous systme temps rel Windows : le sous systme RTSS. Cest un sous systme similaire dautres sous systmes de Windows, comme par exemple, Win32, POSIX, WOW ou DOS : comme eux, il a son propre environnement dexcution et sa propre API (Application Programming Interface). Le sous systme RTSS possde en outre son propre ordonnanceur (scheduler) ; il diffre en cela des autres sous systmes, qui eux utilisent lordonnanceur de Windows. RTSS assure donc lordonnancement des threads temps rel. Dans le cas dune application dont le support dexcution est monoprocesseur, lordonnancement de lensemble des threads RTSS se fait prioritairement celui des threads Windows, et mme celui des squences dinterruption gres par Windows. RTX nutilise en fait le systme dexploitation Windows que pour le chargement des processus, ldition de liens des DLL et lallocation mmoire.
Comme un driver de priphrique Windows, le sous systme RTSS peut utiliser la gestion mmoire de bas niveau de Windows pour allouer de la mmoire verrouille et contigu.
RTX propose une API temps rel (RTAPI) qui peut tre utilise aussi bien par les processus Win32 que par les processus RTSS. Cependant, suivant quil sagit dun processus Win32 ou dun processus RTSS les temps de rponse des fonctions de cette API seront trs diffrents. En raison de la compatibilit du sous systme RTSS avec le sous systme Win32, les processus RTSS (temps rel) et les processus Win32 (non temps rel) peuvent partager des objets IPC (Interprocess communication) communs. La communication et la synchronisation entre un processus RTSS et un processus Win32 sen trouvent ainsi grandement facilites. En dfinitive, RTX se prsente comme une extension au systme dexploitation Windows. Aprs installation de RTX, on na pas affaire deux systmes dexploitation spars, mais un seul offrant dsormais les fonctionnalits requises pour le dveloppement dapplications temps rel. Les outils de dveloppement dapplications RTX sont les mmes que ceux utiliss pour le dveloppement dapplications Windows, et la smantique de lAPI temps rel (RTAPI) est identique celle de lAPI Win32.
Response : RTX is a Real-time subsystem that runs on top of Windows and shares the CPU with the Windows OS. RTX does not modify the Windows Kernel, RTX also doesnt make Windows application
run deterministically (<= 40 s). Only RTX processes that run under RTX subsystem can run with deterministic performance. Your RTX deterministic processes can communicate with Win32 applications and perform your real-time tasks behind the scenes. So to an end user, Windows appears to be behaving in real-time When, in fact, the RTX subsystem is responsible.
Processus RTSS
Processus RTSS
appelant lAPI Win32
DLL Win32
HAL Windows
Extension de la HAL La couche HAL (Hardware Abstraction Layer) a t amliore pour le temps rel : isolement des interruptions, timers rapides, interception des crans bleus. Cependant, lorsque RTSS nest pas utilis, il y a aucun changement dans les performances des fonctions de Windows. Cette extension HAL temps rel de RTX maintient un isolement des interruptions entre RTSS et Windows. Ainsi Windows ne peut pas masquer (au niveau du contrleur dinterruption) les interruptions gres par RTSS. Par contre, les interruptions Windows sont masques durant lexcution de RTSS. Cette extension HAL assure une meilleure gestion de lhorloge temps rel (HTR) et des timers en offrant une rsolution leve et une synchronisation entre les horloges et les timers. Dautre part, elle limine les temps de masquage des interruptions suprieurs 5 s. Les temps de latence des interruptions sont les suivants : 10 s en moyenne, 50 s dans le pire des cas avec un warm cache, ~200 s dans le pire des cas avec un cold cache (mmoire 60 ns).
10
Environnement RTSS
Support des autres API de RTX
Module SRI
clients/serveurs (ct Windows)
Module SRI
clients/serveurs (ct RTSS)
Le module SRI Le module SRI (Service Request Interrupt) du sous systme RTSS est un module de communication entre lenvironnement Windows et lenvironnement RTSS. Ce module de communication entre les deux environnements dexcution permet notamment : lenvironnement Windows daccder aux objets de communication inter processus (IPC), objets qui sont grs par RTX dans lenvironnement RTSS, lenvironnement RTSS de demander de lallocation mmoire Windows. En dfinitive, ce module SRI maintient lisolement entre les deux environnements, tout en assurant la communication entre eux.
11
API Win32
CreateMutex ReleaseSemaphore
RTAPI
RtCreateMutex RtReleaseSemaphore
Elles ont une smantique identique celles de Win32 : paramtres dappel identiques, mme si certains de ces paramtres ne sont pas utiliss par le sous systme RTSS. Les attentes (wait) sur les objets sont satisfaites selon des critres de priorit ou, en cas de priorit gale, selon la stratgie Premier entr, premier sorti (FIFO). Laccs aux objets RTSS se fait par handle.
Quest-ce quun handle ? Un handle est tout simplement un entier (gnralement sur 32 bits) identifiant un objet. Obtenu lors de la cration ou de louverture de lobjet, le handle sera utilis ultrieurement comme paramtre dans les fonctions de manipulation dobjets pour dsigner un objet particulier. La valeur relle du handle est sans importance pour le programme dapplication, mais le sous systme (Win32 ou RTSS) qui a communiqu ce numro au moment de la cration de lobjet sait comment sen servir pour identifier ensuite lobjet correspondant. Lorsquon na plus besoin dun handle, il est de bonne pratique de le clore. Pour cela, on utilise la fonction CloseHandle sil sagit dun handle vers un objet Win32, ou la fonction RtCloseHandle sil sagit dun handle vers un objet RTSS. Cependant dans le cas dun handle vers un thread, on utilise toujours la fonction CloseHandle, quil sagisse dun thread Win32 ou dun thread RTSS.
12
2. Environnement de dveloppement
Les privilges de lAdministrateur sont requis pour non seulement installer et dsinstaller RTX 8.1 mais aussi pour lutiliser. Pour linstallation de RTX, consulter le document RTX 8.1.1 SDK Installation Guide.
Extrait des NewsGroups RTX
Question : Is there an alternative to run RTX without administrative rights? Response : Unfortunately, there is no work-around for this. RTX uses Microsofts Service Control
Manager (SCM) to load the HAL extension, RTX subsystem, and RTX processes. It is actually the SCM that requires Administrator privileges, not RTX specifically. In the future, we may implement a custom service loader that would not depend on the SCM this would alleviate the need for Administrator privileges when using RTX. However, this work would not appear until at least the next major RTX release.
Linterface de programmation dapplication est compose de trois ensembles de fonctions : 1. celles de lAPI temps rel (RTAPI), 2. celles de lAPI Win32 supportes par RTX, 3. celles de lAPI de la bibliothque dexcution du C supportes par RTX. 2.1.1 Panorama de lAPI temps rel (RTAPI) Le nom des fonctions constituant la RTAPI (Real Time Application Programming Interface) dbute par le prfixe Rt. Parmi ces fonctions on peut distinguer : Celles qui sont nouvelles, spcifiques RTX : pour ces fonctions il ny a pas de fonctions Win32 quivalentes. Elles apportent lessentiel de ce qui est requis pour la programmation dapplications temps rel.
Par exemple, RtAttachInterruptVector, fonction ncessaire pour la programmation dune application temps rel, na pas dquivalent dans le sous systme Win32.
Celles qui, se prsentant comme des extensions de fonctions Win32, apportent des possibilits supplmentaires pour la programmation temps rel. Pour ces fonctions, il existe donc des fonctions similaires dans lenvironnement de programmation Win32. Les fonctions Rt ont conserv la smantique des fonctions Win32 dorigine, mais leur comportement a t amlior afin de rpondre aux exigences du temps rel.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
13
2.1.2 Panorama de lAPI Win32 supporte par RTX Les fonctions Win32 supportes par RTX, et donc disponibles dans lenvironnement RTSS, ont un comportement strictement identique celui que ces mmes fonctions ont dans lenvironnement Win32. Le nom de ces fonctions nest pas prfix par Rt puisque leur comportement et leur interface dappel sont identiques dans les deux environnements.
Par exemple, des fonctions comme CreateThread et ResumeThread sont disponibles dans lenvironnement RTSS ; elles ont le mme comportement et la mme interface dutilisation que dans lenvironnement Win32.
Cependant, le sous ensemble des fonctions de lAPI Win32 supportes par RTX ne comprend pas de fonctions non essentielles la programmation temps rel ou inappropries pour un comportement dterministe du programme, ce qui est le cas notamment de toutes les fonctions relatives la gestion de linterface graphique GUI (Graphical User Interface).
2.1.3 Panorama de la bibliothque dexcution du C supporte par RTX Un sous ensemble consquent de fonctions de la bibliothque dexcution du langage C (C Run-time library) de Microsoft Visual C++ est disponible dans lenvironnement RTSS. Ces fonctions sont regroupes au sein de deux bibliothques RTXlibc.lib et RTXlibcmt.lib selon quelles sont destines un processus monothread ou un processus multithread.
Elles apportent des amliorations en ce qui concerne la gestion de lallocation mmoire (malloc). A part cela, les fonctions de ces bibliothques ne diffrent pas substantiellement de celles des bibliothques Microsoft. Attention ! Plusieurs Mo de mmoire sont allous au lancement de chaque processus qui utilise RTXlibc.lib ou RTXlibcmt.lib.
Pour un processus Win32, les temps de rponse sont de lordre de 3 10 ms. Pour un processus RTSS, les temps de rponse sont de lordre de quelques s 100 s. Attention ! Ces temps de rponse dpendent aussi : du processeur, du cache, de la vitesse de la mmoire, du bus, du DMA, des sections critiques de Windows durant lesquelles les interruptions sont masques.
14
2.2.1 Structure dune application temps rel utilisant RTX Une application temps rel faisant appel lextension temps rel RTX comportera gnralement au moins deux processus travaillant de concert : un processus Win32 dans lequel sont implmentes les fonctionnalits non temps rel ou temps rel non critique de lapplication ; ce processus peut tirer avantage des fonctions spcifiques au sous systme Win32, comme par exemple les fonctions graphiques de gestion de linterface oprateur (GUI = Graphic User Interface), un processus RTSS dans lequel sont implmentes les fonctionnalits temps rel (dterministes) de lapplication.
Il est important de noter que toutes les fonctions qui comportent une allocation de mmoire, une criture lcran ou une opration dentre/sortie de fichier nont pas un comportement dterministe.
2.2.2 Fichiers excutables RTX RTX gnre 3 types de fichiers excutables : application RTSS, DLL RTSS et RTDLL. Les applications RTSS sont les quivalents temps rel des applications Win32.
Pour ce qui concerne les DLL RTSS et les RTDLL, se reporter RTX SDK Documentation !
2.2.3 Utilisation de larithmtique flottante Les threads qui sexcutent dans lenvironnement RTSS le font toujours en mode kernel. Alors que dans ce mode dexcution le noyau de Windows nautorise pas les oprations en virgule flottante, RTX permet aux threads RTSS dutiliser lunit FPU (FloatingPoint Unit) pour raliser des oprations en virgule flottante. Lutilisation par les programmes RTSS de larithmtique flottante ne ncessite pas la mise en uvre dune procdure particulire. Un programme RTSS peut intgrer les instructions de lunit FPU et faire appel aux routines mathmatiques en virgule flottante comme le ferait un programme Win32 standard.
Lutilisation de lunit FPU dans un processus RTSS provoque cependant une dgradation des performances de 10% due la sauvegarde et la restauration du contexte dexcution.
Aprs linstallation de RTX, est disponible, lintrieur mme de lenvironnement de dveloppement Visual Studio 6.0, un AppWizard spcifique qui permet de crer facilement un espace de travail (workspace) pour un projet dapplication temps rel utilisant RTX. Un espace de travail RTX peut contenir 4 configurations (ou types de processus) : Win32 Release RTSS Release Win32 Debug RTSS Debug
15
5. Dans le champ de saisie qui apparat alors, entrez le chemin daccs au dossier include de RTX comme indiqu dans limage ci-dessus. 6. Pour lentre du chemin daccs aux fichiers .lib, procdez de mme aprs avoir slectionn Library files dans la liste Show directories for. Le chemin par dfaut daccs au dossier lib de RTX est : C:\Program Files\IntervalZero\RTX\lib 7. Cliquez sur le bouton OK pour enregistrer les informations entres.
2.3.2 Cration dun projet avec RTX Pour crer un projet avec lAppWizard RTX, suivez la procdure suivante :
1. Dans le menu File slectionnez puis cliquez sur litem New. 2. Dans la boite de dialogue qui souvre alors, slectionnez lintercalaire Projects, puis dans la liste qui saffiche slectionnez RTXAppWizard. 3. Dans la partie droite de la boite de dialogue renseignez les champs suivants : Nom du projet (Project name) Rpertoire (location) dans lequel sera construit lespace de travail Plate-forme (Platform) pour laquelle lAppWizard RTX construira les diffrentes configurations (il sagit en fait de la plate-forme Win32). 4. Cliquez sur OK. 5. Dans la boite de dialogue qui saffiche alors, slectionnez les options appropries 6. Cliquez sur le bouton Finish ! 7. Saffiche la fentre New Project Information o sont rcapitules les spcifications de cration du nouveau projet. Aprs avoir vrifi quelles sont conformes ce que vous dsirez, cliquez sur le bouton OK ! Sinon, cliquez sur le bouton Cancel !
16
2.3.3 Dfinition du paramtre de taille de pile La dfinition de la taille de pile du thread initial (ou thread primaire) dun processus RTSS se fait dans lenvironnement de dveloppement Visual Studio de la faon suivante :
1. Dans le menu Project cliquez sur litem Setting. 2. Dans la boite de dialogue qui souvre alors, slectionnez lintercalaire Link. 3. Dans la liste droulante Category slectionnez Output, puis dans la zone Stack allocations, tapez la valeur dsire dans les deux champs Reserve et Commit. 4. Cliquez ensuite sur le bouton OK.
Remarques :
Si vous ne spcifiez pas une taille de pile, la valeur par dfaut sera de 2 pages (ou 8192 octets). Si vous spcifiez une valeur de 0 ou de 1, RTX utilisera galement une taille de pile de 2 pages Si une autre valeur est spcifie, celle-ci est arrondie la taille de page suprieure. Dans lenvironnement RTSS, contrairement lenvironnement Win32, la taille de pile dun thread ne peut crotre.
2.3.4 Installation du Developper Studio Add-in Le Developper Studio Add-in est un add-in Microsoft Visual Studio destin faciliter la mise au point des applications RTSS dans lenvironnement de dveloppement Visual Studio. En supposant que linstallation de RTX a t faite aprs celle Visual Studio, effectuez les oprations suivantes pour installer le Developer Studio Add-in :
1. Aprs avoir lanc Visual Studio, ouvrez le menu Tools et cliquez sur litem Customize. 2. Dans la boite de dialogue qui souvre alors, slectionnez lintercalaire Add-ins and Macro Files. 3. Dans le champ Add-ins and Macro Files, cochez Ardence Developer Studio Add-in.
2.3.5 Configuration de Visual Studio pour lancer un processus RTSS Il est possible de lancer lexcution dun processus RTSS depuis lenvironnement de dveloppement Microsoft Visual Studio. Cependant, il est ncessaire au pralable dindiquer Visual Studio lemplacement de lutilitaire RTSSrun. Pour cela, effectuez les oprations suivantes :
1. Dans Visual Studio, ouvrez le menu Project, puis cliquez sur litem Settings. 2. Dans la boite de dialogue qui souvre alors, slectionnez lintercalaire Debug. 3. Dans le champ Executable for debug session, entrez : C:\program files\IntervalZero\RTX\bin\RTSSrun.exe 4. Dans le champ Program arguments, entrez lemplacement de votre fichier .rtss nouvellement cr.
17
3. Processus et threads
Pour les diffrents processus et threads qui peuvent sexcuter sur une machine o sont installs Windows et lextension temps rel RTX, il existe deux environnements dexcution : lenvironnement Win32 et lenvironnement RTSS. Durant toute son existence, un processus sexcute dans lun de ces deux environnements, et ceci sans possibilit den changer.
Nous dsignerons par processus Win32 un processus qui sexcute dans lenvironnement Win32, et par processus RTSS un processus qui sexcute dans lenvironnement RTSS.
Le fait quun processus Win32 et un processus RTSS sexcutent chacun dans un environnement bien distinct a pour consquence que, par exemple, le processus Win32 ne peut manipuler la priorit dun thread RTSS puisque le handle vers ce thread nest valide qu lintrieur de lenvironnement RTSS. De mme les handles vers les objets de type timer et interrupt ne sont valides que dans leur propre environnement dexcution : Win32 ou RTSS. En consquence, une fois crs, un processus Win32 et un processus RTSS ne peuvent interagir, se synchroniser, en un mot cooprer en vue de la ralisation de lobjectif global de lapplication temps rel quen faisant appel aux mcanismes de communication inter processus (IPC) quoffre RTX, savoir aux objets RTSS de type shared memory, semaphore, mutex et event.
Chaque processus Windows sexcute dans une machine virtuelle Win32. Une machine virtuelle (ou environnement dexcution) est dfinie par : un espace dadressage priv de mmoire virtuelle destine lapplication, un contexte dexcution dfini par ltat des registres processeur et des protections daccs : aux fonctions de lAPI (Application Programming Interface), aux entres/sorties, la table des interruptions. Le dmarrage de lexcution dun processus Windows se fait par celui dun seul thread : le thread primaire.
19
Parmi les processus Windows, on distingue : Les processus GUI. Un processus GUI (Graphic User Interface) utilise pour la gestion des entres/sorties avec lutilisateur les fonctions de linterface graphique (GDI = graphic device interface). Le point dentre dun tel processus est la fonction WinMain. Les processus console. Un processus console, ou mode caractre, utilise pour la gestion des entres/sorties avec lutilisateur les fonctions console ou les fonctions de fichiers dE/S (I/O). Le point dentre dun tel processus est la fonction main. A propos du multithreading
Daprs Programmer sous Windows de Ch. PETZOLD Dans un environnement multithread, les programmes peuvent se scinder en lments spars (appels threads dexcution) qui sexcutent de concert. En terme de code, un thread est simplement reprsent par une fonction (fonction susceptible dappeler dautres fonctions). Une application dbute son excution avec son thread primaire, qui dans un programme C traditionnel est la fonction appel main, et dans Windows la fonction WinMain. Une fois dmarr, le programme peut crer de nouveaux threads dexcution en effectuant un appel systme spcifiant le nom de la fonction initiale du thread. Le systme dexploitation fait premptivement basculer le contrle entre les threads, dune manire tout fait similaire celle quil utilise pour la bascule entre processus. Les threads dun programme particulier font tous partie du mme processus. Aussi en partagent-ils les ressources, telles que la mmoire et les fichiers ouverts. Comme les threads partagent la mmoire du programme, ils partagent aussi les variables statiques du processus. Cependant, chaque thread dispose de sa propre pile. Aussi les variables automatiques1 sontelles uniques chaque thread. Chaque thread comporte galement son propre tat du processeur (et du coprocesseur mathmatique), qui est enregistr et restaur durant les bascules entre threads. _________________ Les variables locales une fonction naissent lappel de celle-ci, et elles disparaissent lorsque le programme sort de la fonction. Cest pourquoi lon appelle gnralement ces variables des variables automatiques. Comme les variables automatiques apparaissent et disparaissent au rythme des appels de fonction, elles ne conservent pas leur valeur dun appel lautre et il faut les initialiser explicitement chaque fois que lon entre dans leur fonction (Le langage C. Norme ANSI, pp. 30-31). Les variables automatiques sont uniques chaque thread parce quelles sont stockes sur la pile, et que chaque thread dispose de sa propre pile.
1
3.1.2 Cration et terminaison dun thread Windows La plus petite entit dexcution sous Windows est donc le thread. Chaque application en cours dexcution en contient au minimum un : le thread primaire. Il est cr en mme temps que le processus, et il sexcute toujours partir du point dentre de lapplication (main ou WinMain). Lorsque le thread primaire se termine, lapplication se termine. A partir du thread primaire, il est possible de crer et de lancer de nouveaux threads. Pour le nombre de threads qui peuvent ainsi tre crs lintrieur dun mme processus, il nexiste pas de limite, si ce nest celle impose par la mmoire disponible sur lordinateur. La cration dun nouveau thread se fait en utilisant la fonction CreateThread de lAPI Win32. Cette fonction, dcrite en annexe 1, retourne un handle vers le thread cr. Cet handle pourra tre utilis ultrieurement pour, par exemple, attendre que le thread se termine.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
20
Pour attendre la fin dun thread, on peut utiliser la fonction WaitForSingleObject ainsi : dwWait = WaitForSingleObject (hThread, INFINITE) ; if (dwWait == WAIT_OBJECT_0) CloseHandle (hThread) ; ou bien : WaitForSingleObject (hThread, INFINITE) ; CloseHandle (hThread) ;
Un thread reprsente une partie du processus laquelle le systme dexploitation alloue le CPU pendant un temps donn. Le contexte dexcution dun thread contient : les registres du processeur, la pile du noyau (Kernel level) et la pile utilisateur (User level). Tous les threads dexcution dun processus partagent lespace dadressage virtuel, les variables globales et les ressources systme de ce processus.
Comme tous les threads dun mme processus partagent le mme espace dadressage virtuel, ils peuvent accder aux variables globales du processus.
3.1.3 Ordonnancement des threads Windows Windows est un systme dexploitation premptif. Lordonnanceur de Windows est appel toutes les 20 ms pour, partir des niveaux de priorit des threads Win32 et Win32 RTX dans ltat prt, dterminer le thread qui va obtenir la prochaine tranche de temps CPU. Les threads prts de niveau de priorit le plus lev sont ordonnancs en premier. Quand aucun thread dun niveau de priorit donn nest dans ltat prt, sont ordonnancs les threads prts du niveau de priorit infrieur. Les threads dun mme niveau de priorit sont ordonnancs selon la stratgie du tourniquet (round-robin). Le niveau de priorit dexcution dun thread Windows dpend : dune part de la classe de priorit du processus auquel appartient le thread, et dautre part de lindice de priorit du thread lintrieur de cette classe de priorit. Les classes de priorit Classes de priorit
IDLE_PRIORITY_CLASS
Signification
Classe spcifier pour un processus dont les threads sexcutent seulement quand le systme est au repos. Les threads du processus sont premptes par les threads de nimporte quel processus sexcutant dans une classe de priorit plus leve. Classe spcifier pour un processus sans exigences particulires concernant son ordonnancement. Classe spcifier pour un processus dont des actions critiques doivent tre excutes immdiatement. Les threads dun tel processus premptent les threads des processus des classes NORMAL et IDLE.
NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
Classe spcifier pour un processus qui doit avoir la plus haute REALTIME_PRIORITY_CLASS priorit possible. Les threads dun tel processus premptent les threads de tous les autres processus, y compris ceux du systme dexploitation (qui peuvent raliser des fonctions importantes !).
21
Les fonctions SetPriorityClass et GetPriorityClass permettent respectivement de fixer et de lire la classe de priorit dun processus. Les indices de priorit Priorit
THREAD_PRIORITY_IDLE
Signification
Indice de priorit 1 si la classe de priorit du processus est la classe IDLE, NORMAL ou HIGH. Indice de priorit de 16 si la classe de priorit du processus est la classe REALTIME. Priorit normale - 2 Priorit normale - 1 Priorit normale Priorit normale + 1 Priorit normale + 2 Indice de priorit de 15 si la classe de priorit du processus est la classe IDLE, NORMAL ou HIGH. Indice de priorit de 31 si la classe de priorit du processus est la classe REALTIME.
THREAD_PRIORITY_LOWEST THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL
Les fonctions SetThreadPriority et GetThreadPriority permettent respectivement de fixer et de lire lindice de priorit de base dun thread lintrieur de la classe de priorit du processus. Tous les threads THREAD_PRIORITY_NORMAL. dbutent leur excution avec lindice de priorit
Pour les classes de priorit idle, normal et high_priority le systme dexploitation augmente dynamiquement lindice de priorit de base dun thread lors de loccurrence dvnements importants pour ce thread. Ceci na pas lieu pour la classe de priorit realtime.
22
3.2.1 Dmarrage et fermeture dun processus RTSS Un processus RTSS peut tre cr et dmarrer son excution : soit comme un driver de priphrique lors du dmarrage du systme dexploitation (en utilisant lutilitaire RTSSrun /b), soit partir de la ligne de commande (en utilisant la commande RTSSrun),
Lorsquon double-clique sur le nom du fichier excutable, cest en fait le programme RTSSrun qui effectue le lancement du processus dans lenvironnement RTSS.
soit partir dun processus Win32 (en utilisant la fonction CreateProcess), soit partir dun processus Win32 RTX (en utilisant la fonction RtCreateProcess). La fonction RtCreateProcess nest disponible que dans lenvironnement Win32. Ainsi seul un processus Win32 RTX peut utiliser RtCreateProcess pour crer et dmarrer un processus RTSS. Il est galement possible de lancer lexcution dun processus RTSS depuis Microsoft Visual Studio. Pour configurer cette fin Visual Studio, voir 2.3.4. Quand un processus RTSS est cr, le sous systme RTSS ralise les oprations suivantes : il charge le fichier excutable comme un driver de priphrique, il alloue un espace mmoire de processus dans le pool de mmoire non pagine (mmoire physique), et il cre le thread primaire du processus (il ne cre pas cependant de handle pour ce thread). En standard, 10 processus peuvent tre simultanment actifs dans lenvironnement RTSS. La fermeture dun processus RTSS se produit la suite de lun des vnements suivants : lorsque se termine le dernier thread du processus, lorsquun thread du processus appelle la fonction ExitProcess, lorsque lutilitaire RTSSkill ou le RTSS Task Manager demande la destruction du processus. La mthode prfre - et donc fortement conseille - de fermeture dun processus est celle o chaque thread du processus se termine en excutant la fonction ExitThread. Lorsque tous les threads du processus se sont ainsi termins, le processus lui-mme se termine automatiquement (voir ci-aprs Tech Note Alternative to ExitProcess ).
3.2.2 Cration et terminaison dun thread RTSS La fonction CreateThread permet un processus RTSS de crer un thread lintrieur de lenvironnement dexcution du processus. Le handle et le ID retourns par la fonction ne sont valides qu lintrieur de lenvironnement dexcution du processus appelant.
Suivant lenvironnement dexcution du processus appelant (environnement Win32 ou environnement RTSS), la fonction CreateThread cre soit un thread Win32 soit un thread RTSS.
Le thread est cr avec une priorit de 0. On utilise les fonctions RtGetThreadPriority et RtSetThreadPriority pour respectivement obtenir et modifier le niveau de priorit dun thread. La mthode prfre de terminaison dun thread est celle o le thread lui-mme excute la fonction ExitThread. Quand cette fonction est appele soit explicitement soit 23
indirectement lors du retour de la fonction du thread, la pile du thread courant est dsaffecte, et le thread se termine. Si, lorsque cette fonction est appele, le thread est le dernier thread actif du processus, le processus se termine galement. Il en est de mme si le thread primaire appelle ExitThread. La terminaison dun thread nentrane pas ncessairement une suppression de lobjet thread. Un objet thread est dtruit lorsque est clos le dernier handle vers cet objet. Pour clore le handle vers un thread RTSS, utilisez la fonction CloseHandle et non la fonction RtCloseHandle.
Tech Note : Alternative to ExitProcess
Avoiding the use of the ExitProcess call will lead to more stable code. Microsoft discourages the use of ExitProcess and of terminating a thread from outside the thread. In both cases, the operating system cannot always guarantee that the proper cleanup will be performed. Use of theses can have adverse effects on your system. Rather than calling ExitProcess, have each thread in the process call ExitThread on itself at a safe point. When all the threads in a process have exited themselves properly the process will end and be removed automatically. Your process should include a flag which, when set, signals to all threads that at the next appropriate point that they have to exit. All the threads in the process should test for the flag in appropriate places throughout the thread code. Setting this flag at the point where a process must finish will cause the threads in the process to start shutting themselves down.
3.2.3 Ordonnancement des threads RTSS Lordonnanceur RTSS implmente une politique dordonnancement par priorit des threads de lensemble des processus RTSS, ainsi quun mcanisme de promotion de priorit destin viter le phnomne dinversion de priorit. Le sous systme RTSS ne gre quune seule classe de priorit, classe compose de 128 niveaux de priorit numrots de 0 (le niveau de priorit le plus faible) 127 (le niveau de priorit le plus lev). Un thread RTSS sexcute lun de ces 128 niveaux de priorit. En comptition pour lusage du CPU, les threads dans ltat prt sont ordonnancs en fonction de leur seul niveau de priorit de thread ; lordonnanceur RTSS excute toujours le thread qui a la priorit la plus leve. Les threads RTSS dun mme niveau de priorit sexcutent selon la stratgie dordonnancement premier arriv, premier servi (FIFO) : le thread le plus ancien dans ltat prt sexcute en premier. Si un quantum de temps diffrent de 0 a t dfini, le thread en cours sexcute jusqu expiration de ce temps, puis laisse le CPU un thread prt de mme priorit. Un thread RTSS sexcute jusqu ce quil libre le CPU : en se mettant en attente sur un objet de synchronisation, en se suspendant lui-mme, en abaissant son niveau de priorit ou en levant celui dun autre thread, en provoquant un r-ordonnancement suite un appel Sleep(0), parce qua expir le quantum de temps spcifi, et quun thread de mme priorit est prt sexcuter, au retour dun gestionnaire dinterruption ou dune squence timer (cas des threads dinterruption et des threads timer), parce quil a t interrompu par un thread plus prioritaire.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
24
Tant quun thread RTSS est en cours dexcution, sont masques toutes les interruptions gres par Windows, ainsi que toutes les interruptions gres par les threads de priorit infrieure celle du thread courant. Inversement, toutes les interruptions gres par les threads de priorit suprieure au thread courant sont dmasqus ; ceci permet un thread de priorit suprieure dinterrompre ventuellement lexcution du thread courant. Afin dviter que ne se produise le phnomne dinversion de priorit, lordonnanceur du sous systme RTSS implmente le mcanisme de promotion de priorit.
Si, sur un objet mutex possd dj par un thread, un thread de priorit suprieure appelle la fonction RtWaitForSingleObjet (RtWFSO), la priorit du thread propritaire du mutex sera temporairement promue au niveau de priorit du thread qui effectue lappel RtWFSO. Une tentative ventuelle pour diminuer la priorit du thread propritaire du mutex sera diffre jusqu ce que le thread libre le mutex. Tech Note : Priority promotion in RTX
Priority Promotion is a mechanism which prevents low priority threads from blocking the execution of high priority threads. This blocking can occur if a low priority thread gains ownership of a resource, through a mutex, which the high priority thread needs. Priority promotion occurs only with mutex synchronization objects. Because several threads can affect an RTSS semaphore's resource count, for semaphores there is no notion of ownership. Priority promotion does not occur when multiple threads wait on a semaphore. Hence, priority inversion can occur with the use of semaphores. For example, say a thread with priority 30 were waiting for a mutex. This mutex, however, is owned by a thread with priority 10. If a thread with priority 20 runs, the thread with priority 10 will be promoted temporarily to priority 30, until it releases the mutex, then the threads original priorities are restored.
dautre part, rajouter la bibliothque rtapi_w32.lib la liste des bibliothques auxquelles le programme compil fait lobjet dune dition de liens.
Pour cela, dans le menu Project, cliquez sur litem Settings ; dans la boite de dialogue qui souvre alors, slectionnez lintercalaire Link, puis rajoutez rtapi_w32.lib la fin de la liste de bibliothques qui apparat dans le champ Object/library modules.
Un processus Win32 RTX commence interagir avec RTX la premire fois quil appelle une fonction de la RTAPI. A partir de cet instant, RTX peut allouer des ressources ce processus, modifier la priorit de ses threads et raliser toute autre opration compatible avec son statut de processus Win32. Un processus Win32 RTX a ainsi la possibilit daccder tout la fois aux objets Win32 et aux objets RTSS.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
25
3.3.2 Spectre des niveaux de priorit des threads Win32 RTX Un processus Win32 RTX dmarre son excution dans la classe de priorit normale (NORMAL_PRIORITY_CLASS). Mais ds que le processus appelle RtGetThreadPriority RtSetThreadPriority ou nimporte quelle autre fonction de priorit temps rel, sa classe de priorit devient la classe de priorit REALTIME (REALTIME_PRIORITY_CLASS). Les threads Win32 RTX peuvent se trouver en concurrence avec les threads RTSS lorsquils sont en attente sur un objet RTSS de synchronisation (objet de type semaphore, mutex ou event). Lattente de threads (threads RTSS et/ou threads Win32 RTX) sur un objet RTSS sera satisfaite en fonction de leur niveau de priorit. Par exemple, un thread Win32 RTX avec la priorit RT_PRIORITY_MAX obtiendra la proprit dun mutex avant un thread RTSS de priorit infrieure attendant sur le mme objet. En utilisant la fonction RtSetThreadPriority les threads Win32 RTX ont la possibilit de dfinir et de modifier leur niveau de priorit par rapport celui des threads RTSS. Afin que les processus Win32 RTX puissent utiliser la fonction RtSetThreadPriority, les 7 niveaux de priorit de thread dfinissables par programme lintrieur de la classe de priorit REALTIME sont rpartis de la faon suivante dans lensemble des 128 niveaux de priorit grs par le sous-systme RTSS :
Nom de priorit symbolique RTSS
RT_PRIORITY_MIN RT_PRIORITY_MIN + 1 RT_PRIORITY_MIN + 2 RT_PRIORITY_MIN + 3 RT_PRIORITY_MIN + 4 RT_PRIORITY_MIN + 5 + 126 RT_PRIORITY_MAX
Valeur RTSS
Valeur Win32
0 1 2 3 4 5 126 127
16 22 23 24 25 26 31
Si un thread Win32 RTX appelle la fonction RtSetThreadPriority, la priorit spcifie lors de lappel sera traduite conformment au tableau prcdent.
Par exemple, lappel par un thread Win32 RTX de la fonction : RtSetThreadPriority (Thread, RT_PRIORITY_MIN + 1) donnera lieu un appel par RTX de la fonction : SetThreadPriority (Thread, THREAD_PRIORITY_LOWEST).
Si un thread Win32 RTX appelle la fonction RtGetThreadPriority, celle-ci retournera la priorit temps rel spcifie lors de lappel de la fonction RtSetThreadPriority.
Cependant, dans certains cas, la valeur retourne peut tre errone sil y a eu au pralable un mixage des appels des fonctions RtSetThreadPriority et SetThreadPriority.
26
3.3.3 Cas des processus Win32 RTX qui sont aussi des processus GUI Un processus Win32 RTX dmarre son excution dans la classe de priorit normale (NORMAL_PRIORITY_CLASS) mais passe ensuite dans la classe de priorit temps rel (REALTIME_PRIORITY_CLASS) ds quil effectue un appel de RtGetThreadPriority, de RtSetThreadPriority ou de nimporte quelle autre fonction de priorit temps rel. Cest le comportement dsir pour la majorit des applications puisque cela donne au processus Win32 RTX la meilleure performance temps rel possible. Cependant ceci est source de problmes lorsque des threads de ce processus grent une interface graphique GUI (Graphic User Interface). Quand un thread de la classe de priorit temps rel (REALTIME_PRIORITY_CLASS) interagit avec le domaine GUI de Windows, des ralentissements et des blocages se produisent. Pour viter ces problmes, le processus Win32 RTX doit, au dbut de son excution, demander sexcuter dans la classe de priorit normale (NORMAL_PRIORITY_CLASS) en faisant appel la fonction SetPriorityClass. Au dbut de son excution, un processus de type Win32 RTX + GUI doit donc modifier sa classe de priorit en effectuant lappel suivant : SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS) ;
3.3.4 Cration et dmarrage dun processus RTSS depuis un processus Win32 RTX Un processus Win32 RTX peut crer et lancer lexcution dun processus RTSS en faisant appel la fonction RtCreateProcess. Cette fonction RtCreateProcess ne peut tre utilise que dans lenvironnement dexcution Win32. De ce fait, seul un processus Win32 RTX peut appeler RtCreateProcess pour crer et dmarrer un processus RTSS. La fonction RtCreateProcess retourne dans une structure PROCESS_INFORMATION le handle vers le processus RTSS cr. Ultrieurement, ce handle pourra tre utilis par : la fonction RtWaitForSingleObject lorsque le processus Win32 RTX dsirera attendre la fin du processus RTSS, et la fonction RtCloseHandle lorsque le processus Win32 RTX voudra clore le handle vers le processus RTSS.
ATTENTION ! Puisque le processus RTSS a t cr par une fonction de lAPI temps rel (en loccurrence la fonction RtCreateProcess), il faut imprativement faire appel aux fonctions de cette API : RtWaitForSingleObject et RtCloseHandle.
27
Si cette option nest pas active, la zone mmoire dterministe sera cre la premire fois quun processus RTSS appellera la fonction RtAllocateLocalMemory. La zone mmoire dterministe est cre avec comme taille celle indique dans le champ Pool size (bytes) du panneau de configuration RTX Properties (voir ci-dessus). Quand il a utilis ou allou toute cette mmoire et quil doit satisfaire une nouvelle requte de mmoire locale, le sous systme RTSS doit demander un supplment de mmoire Windows. La quantit de mmoire additionnelle demande Windows correspondra soit la taille initiale de la zone mmoire dterministe soit la taille de la zone mmoire requise.
29
tant donn que toute requte dallocation de mmoire adresse Windows est une opration non dterministe, il faut viter ce scnario o le sous systme RTSS a besoin deffectuer une demande complmentaire de mmoire Windows. Pour cela, il est important de bien valuer les besoins en mmoire des processus RTSS de lapplication et dindiquer la taille de la zone mmoire dterministe qui permettra de les satisfaire. Il est noter que la fonction RtQueryLocalMemory permet de sassurer quil reste assez de mmoire dans la zone de mmoire dterministe. Si dans le panneau de configuration RTX Properties lusage de la zone mmoire dterministe est active, toutes les allocations de mmoire requises par lapplication RTSS, quelles soient explicites ou implicites, seront faites depuis la zone de mmoire locale. Il en rsulte quun certain nombre de fonctions de lAPI de RTX vont devenir des fonctions dterministes.
30
Les noms de tous les objets RTSS de type shared memory, semaphore, mutex et event partagent le mme espace de nommage propre RTX. De ce fait, il est ncessaire de donner un nom distinct chacun des objets crs, mme sil sagit dobjets de types diffrents. La gestion des objets crs laide RtCreateSharedMemory, RtCreateSemaphore, RtCreateMutex ou de RtCreateEvent est toujours assure dans lenvironnement RTSS. Cependant, les processus Win32 RTX peuvent non seulement utiliser mais aussi crer de tels objets, condition de le faire en faisant appel aux fonctions prfixes par Rt.
Dans lenvironnement RTSS, les oprations de manipulation des objets shared memory, semaphore, mutex et event (RtWait, RtRelease, etc.) sont des oprations dterministes. Par contre, celles de cration (RtCreate), douverture (RtOpen) et de clture (RtCloseHandle) de ces objets ne sont dterministes que si lallocation de mmoire se fait depuis le pool de mmoire locale (cf. chapitre 4).
Donner un nom un objet RTSS de type IPC nest pas ncessaire si cet objet est utilis uniquement pour la synchronisation et la communication entre threads appartenant un mme processus. Donner un nom un tel objet est par contre obligatoire si lobjet est utilis pour la synchronisation et la communication entre threads appartenant des processus diffrents.
31
Response : This section of the help is just informing you that using the RTX version,
RtOpenSemaphore, of the Win32 call, OpenSemaphore(), is attempting to open a semaphore from the RTX Subsystem. A Win32 (.exe) process linked with the rtapi_w32.lib and including rtapi.h, has the option to access both RTX and Windows objects. The RtOpenSemaphore() call will attempt to open a semaphore from the RTX Subsystem and the OpenSemaphore() call will attempt to open a Windows Object. Example : OpenSemaphore (0, FALSE, Semaphore); RtOpenSemaphore (0, FALSE, Semaphore); In this example, the same string was used in both calls and they both attempt to open a semaphore. Although, because of the Rt prefix we are trying to open completely different objects handled by completely different subsystems. The call OpenSemaphore() does not access the RTX Object Manager or namespace, so a call to open a RTX object without the Rt prefix in a Win32 process will fail.
Un processus appelle la fonction RtCreateSharedMemory pour crer un objet shared memory. Les autres processus se lient lobjet cr en utilisant la fonction RtOpenSharedMemory ; ils dsignent lobjet par son nom, le nom donn par le processus qui a cr lobjet. Les deux fonctions RtCreateSharedMemory et RtOpenSharedMemory renvoient un pointeur sur le dbut du bloc de mmoire partage. Les objets de synchronisation dcrits ci-aprs (semaphore, mutex et event) peuvent tre utiliss pour protger laccs aux objets shared memory. Fonctions API relatives aux objets shared memory La fonction RtCreateSharedMemory cre une rgion de mmoire physique. Elle retourne un handle vers lobjet shared memory cr, objet dont le nom et la taille sont ceux indiqus dans les paramtres dappel de la fonction. La fonction RtOpenSharedMemory permet un processus douvrir un accs un objet shared memory existant. Elle retourne un handle vers lobjet shared memory qui porte le nom indiqu dans les paramtres dappel de la fonction. Cette fonction RtOpenSharedMemory permet ainsi plusieurs processus douvrir un handle vers le mme objet shared memory.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
32
La fonction RtCloseHandle permet de clore un handle vers un objet shared memory. Quand sont clos tous les handles vers lobjet, celui-ci est dtruit, et la mmoire physique qui lui avait t alloue est restitue au systme.
Tout processus qui a obtenu un accs un objet shared memory (suite lappel de RtCreateSharedMemory ou de RtOpenSharedMemory) doit clore cet accs en appelant la fonction RtCloseHandle.
Fonctions API relatives aux objets semaphore La fonction RtCreateSemaphore cre un objet semaphore, fixe la valeur maximale du compteur ainsi que sa valeur initiale, et ventuellement lui donne un nom. Elle retourne un handle vers lobjet semaphore ainsi cr. La fonction RtOpenSemaphore permet un processus douvrir un accs un objet semaphore existant. Elle retourne un handle vers lobjet semaphore prcdemment cr par un processus laide de RtCreateSemaphore, et dont le nom est celui indiqu dans les paramtres dappel de la fonction. Cette fonction RtOpenSemaphore permet ainsi plusieurs processus douvrir un handle vers le mme objet semaphore. La fonction RtReleaseSemaphore incrmente le compteur de lobjet semaphore de la valeur indique dans lappel de la fonction. La fonction RtWaitForSingleObjet permet un thread de tester ltat courant dun objet semaphore. Si lobjet semaphore est dans ltat signal, son compteur est dcrment de 1 et il y a retour immdiat dans le thread. Si le smaphore est dans ltat non signal, le thread passe dans ltat en attente : il attend que pour lui lobjet semaphore passe dans ltat signal. La fonction RtWaitForMultipleObjects, similaire la fonction RtWaitForSingleObject, permet un thread de tester ltat signal de plusieurs objets (objets de mme type ou de type diffrent), et - dans le cas o aucun deux nest dans ltat signal - de se mettre en attente sur ces objets. Les types dobjets sur lesquels un thread peut se mettre en attente sont les suivants : process, thread, semaphore, mutex et event.
Un processus ou un thread qui se termine est positionn dans ltat signal. Quand un thread se met en attente dun processus ou dun autre thread, il attend en fait que ce processus ou ce thread se termine.
La fonction RtCloseHandle permet de clore un handle vers un objet semaphore. Lorsque ont t clos tous les handles vers un objet semaphore, ce dernier est dtruit.
33
A propos de lutilisation dun objet semaphore Une application utilise gnralement un objet semaphore pour limiter le nombre de threads utilisant une ressource. Avant dutiliser la ressource, un thread spcifie le handle de lobjet semaphore dans un appel une fonction dattente. Quand la fonction dattente retourne, elle dcrmente de 1 le compteur du smaphore. Lorsque le thread a termin dutiliser la ressource, il appelle RtReleaseSemaphore pour incrmenter le compteur du smaphore de 1. La fonction RtReleaseSemahore peut galement tre utilise durant linitialisation dune application. Au dmarrage de lapplication, un objet semaphore est cr en donnant une valeur nulle au compteur ; ceci met lobjet dans ltat non signal et bloque tous les threads voulant accder la ressource protge. Quand lapplication a fini son initialisation, elle utilise RtReleaseSemaphore pour incrmenter le compteur sa valeur maximale afin de permettre un accs normal la ressource protge.
Fonctions API relatives aux objets mutex La fonction RtCreateMutex permet de crer un objet mutex et dindiquer si le thread appelant veut ou non en acqurir immdiatement la proprit. Elle retourne un handle vers lobjet mutex ainsi cr. Plusieurs processus peuvent utiliser la fonction RtCreateMutex pour le mme objet mutex ; ceci est quivalent ce que lun appelle la fonction RtCreateMutex et les autres la fonction RtOpenMutex.
Mais si cette technique est utilise (tous appelant la fonction RtCreateMutex), aucun processus ne devrait demander la proprit immdiate du mutex. Lorsque plusieurs processus demandent la proprit immdiate dun objet mutex, il peut tre difficile en effet de prdire quel processus lobtiendra effectivement.
34
La fonction RtOpenMutex permet un processus douvrir un accs un objet mutex existant. Elle retourne un handle vers lobjet mutex prcdemment cr par un processus laide de RtCreateMutex, et dont le nom est celui indiqu dans les paramtres dappel de la fonction. Cette fonction RtOpenMutex permet ainsi plusieurs processus douvrir un handle vers le mme objet mutex. La fonction RtReleaseMutex permet au thread propritaire dun objet mutex dabandonner son titre de proprit sur cet objet. La fonction RtWaitForSingleObjet permet un thread de tester ltat courant dun objet mutex. Si lobjet mutex est dans ltat signal, il est positionn dans ltat non signal et il y a retour immdiat dans le thread appelant. Si lobjet mutex est dans ltat non signal, le thread passe dans ltat en attente : il attend que pour lui lobjet mutex soit libr. La fonction RtWaitForMultipleObjects, similaire la fonction RtWaitForSingleObject, permet un thread de tester ltat signal de plusieurs objets (objets de mme type ou de type diffrent), et, dans le cas o aucun deux nest dans ltat signal, de se mettre en attente sur ces objets. Les types dobjets sur lesquels un thread peut se mettre en attente sont les suivants : process, thread, semaphore, mutex et event.
Un processus ou un thread qui se termine est positionn dans ltat signal. Quand un thread se met en attente dun processus ou dun autre thread, il attend en fait que ce processus ou ce thread se termine.
La fonction RtCloseHandle permet de clore un handle vers un objet mutex. Lorsque ont t clos tous les handles vers un objet mutex, ce dernier est dtruit.
Known issue
When attempting to open a non-existent named RTX IPC object such as a mutex, semaphore, or shared memory, the error code ERROR_FILE_NOT_FOUND is now returned.
35
La fonction RtSetEvent met dans ltat signal lobjet event spcifi. Sil sagit dun objet event reset manuel, il restera dans ltat signal jusqu ce quil soit explicitement remis dans ltat non signal par la fonction RtResetEvent. Tous les threads qui sont en attente sur cet objet vont poursuivre leur excution. Tant que lobjet restera dans ltat signal, tous les threads qui ultrieurement demanderont se mettre en attente sur cet objet poursuivront immdiatement leur excution. Sil sagit dun objet event reset automatique, ltat de lobjet event la sortie de la fonction RtSetEvent va dpendre du fait quil y ait ou non des threads en attente sur cet objet : Si des threads sont en attente sur cet objet, lobjet event est remis dans ltat non signal, et un seul des threads en attente voit son excution se poursuivre. Si aucun thread nest en attente sur cet objet, lobjet reste dans ltat signal jusquau prochain appel de la fonction RtWaitForSingleObject ou RtWaitForMultipleObjects impliquant cet objet. La fonction RtWaitFor fera alors office de fonction RtResetEvent.
Remarque : Avec un objet event reset automatique, chaque occurrence dun vnement signal par RtSetEvent est prise en compte, et elle lest par un thread et un seul.
La fonction RtPulseEvent met dans ltat signal lobjet event spcifi, puis le remet dans ltat non signal aprs avoir permis la poursuite de lexcution de threads ventuellement en attente sur cet objet : sil sagit dun objet event reset manuel, tous les threads en attente poursuivent leur excution, sil sagit dun objet event reset automatique, un seul dentre eux peut poursuivre son excution.
Remarque : Si donc aucun thread nest en attente sur cet objet, la fonction RtPulseEvent ne fait simplement que mettre lobjet event dans ltat non signal.
La fonction RtResetEvent met dans ltat non signal lobjet event spcifi. Ce dernier restera dans cet tat jusqu ce quil soit mis dans ltat signal par la fonction RtSetEvent ou RtPulseEvent. La fonction RtResetEvent est utilise pour les objets event reset manuel.
Ltat non signal bloque lexcution de tout thread qui a spcifi lobjet event dans un appel RtWaitForSingleObject ou RtWaitForMultipleObjects.
La fonction RtWaitForSingleObjet permet un thread de tester ltat courant dun objet event. Si lobjet event est dans ltat non signal, le thread passe dans ltat en attente. Si lobjet event est dans ltat signal, il y a retour immdiat dans le thread appelant. Pour un objet event reset automatique, la fonction remet lobjet dans ltat non signal avant le retour dans le thread. La fonction RtWaitForMultipleObjects, similaire la fonction RtWaitForSingleObject, permet un thread de tester ltat signal de plusieurs objets (objets de mme type ou de type diffrent), et, dans le cas o aucun deux nest dans ltat signal, de se mettre en attente sur ces objets. Les types dobjets sur lesquels un thread peut se mettre en attente sont les suivants : process, thread, semaphore, mutex et event.
Un processus ou un thread qui se termine est positionn dans ltat signal. Quand un thread se met en attente dun processus ou dun autre thread, il attend en fait que ce processus ou ce thread se termine.
La fonction RtCloseHandle permet de clore un handle vers un objet event. Lorsque ont t clos tous les handles vers un objet event, ce dernier est dtruit.
36
6. Horloges et timers
6.1 Les services relatifs aux horloges RTX
6.1.1 Les horloges RTX Les horloges RTX sont des compteurs spcifiques utiliss pour mesurer le temps. Leurs valeurs sont donnes et fixes en nombre dintervalles (ticks) de 100 ns. Ils sont mis jour par des services fournis par lextension HAL temps rel. Les horloges RTX sont synchronises avec les services des timers RTX. Elles ne sont par contre synchronises ni avec lhorloge systme de Windows ni avec celle donnant la date et lheure (time-of-day clock)1. RTX 8.1 offre trois horloges. Elles sont disponibles aussi bien dans lenvironnement Win32 que dans lenvironnement RTSS :
Nom de lhorloge CLOCK_1 CLOCK_2 CLOCK_3 Rsolution 1 ms 1 s 1 s 1 ms 100, 200, 500 ou 1000 s 100, 200, 500 ou 1000 s Priode pour les timers
Les horloges CLOCK_2 et CLOCK_3 sont bases sur la mme priode du timer de la couche HAL temps rel (HAL extension timer period). Cette priode timer de la HAL est dfinie dans le panneau de configuration RTX Properties. Elle peut avoir pour valeur : 100, 200, 500 ou 1000 s.
37
Fonctions API relatives aux horloges RTX La fonction RtGetClockTime donne la valeur courante dune horloge. La fonction RtSetClockTime initialise la valeur courante dune horloge. La fonction RtGetClockResolution donne la rsolution dune horloge. La fonction RtGetClockTimerPeriod donne la priode timer minimale dune horloge.
6.1.2 Systmes monoprocesseurs avec contrleur dinterruptions programmable Sur les PC standard monoprocesseurs quips dun contrleur dinterruptions programmable (PIC), le timer programmable (Programmable Timer) ne peut pas tre programm pour fonctionner un (even) fraction de seconde (sa priode de base est 838,095344 nanosecondes). Ceci a pour consquence que la priode de temps relle est toujours quelque peu diffrente de la valeur spcifie dans le panneau de configuration de RTX pour la priode timer de lextension HAL (HAL extension timer period). De plus, ce timer programmable est utilis pour mettre jour lhorloge du systme : chaque tick gnr par le timer programmable un incrment de temps fixe est ajoute lhorloge. Windows maintiennent une rsolution de 0,1 s pour cet incrment de temps ; ceci conduit une accumulation derreurs darrondi dont le rsultat est une lgre drive de lhorloge par rapport lheure exacte. En raison de cette drive, Windows lit priodiquement lhorloge qui donne la date et lheure (time-of-day clock), puis procde une correction de la drive. Lhorloge CLOCK_2 de RTX drive galement, mais une vitesse diffrente de celle de lhorloge Windows. Elle est conue pour fonctionner un rythme qui maintient la synchronisation avec la priode timer spcifi Par rapport lhorloge CLOCK_2, lhorloge CLOCK_3 de RTX utilise une priode de temps beaucoup plus prcise pour dfinir et donner les valeurs dhorloge ainsi que pour calculer les valeurs dexpiration et les temps de latence des timers. En consquence, la drive mentionne prcdemment nexiste plus avec lhorloge CLOCK_3.
6.1.3 Systmes monoprocesseurs avec APIC et systmes multiprocesseurs Sur les systmes monoprocesseurs quips du contrleur dinterruptions programmable avanc (APIC) et sur les systmes multiprocesseurs, le timer de lextension HAL de RTX est bas sur le timer APIC local (Local APIC timer). Avec ces systmes, les horloges CLOCK_2 et CLOCK_3 de RTX sont identiques, et ne comportent pas de drive.
Advanced Programmable Interrupt Controller (APIC) HAL Support
Most new PC platforms take advantage of the advanced APIC interrupt controller mode enabling more interrupt lines for better overall system configuration management and reliable performance. Release 6.0 of RTX now supports the APIC HAL in uni-processor and multi-processor configurations, resulting in several benefits for RTX customers. The use of the APIC HAL results in elimination of clock drift, reduction of bus bandwidth utilisation providing approximately a 20 % improvement in both RTX and application performance. In addition, by supporting all of the standard Microsoft HALs, including the newest APIC HAL, RTX utilises a standardised and fully compliant interface to the hardware.
38
39
Cration du timer
Activation du timer
(initialisation du temporisateur)
Thread timer
TantQue (timer actif) faire : Attendre expiration du temporisateur ; Si (one-shot timer) alors : Dsactiver le timer ; sinon Rarmer le temporisateur ; finSi Excuter la squence de traitement ; finTantQue
maSeqTimer
Dsactivation du timer
Suppression du timer
RtDeleteTimer (hTimer) ;
temps
La squence de traitement du timer est une fonction dont largument dentre est de type PVOID, et qui retourne VOID : void RTFCNDCL maSeqTimer (PVOID unused) ;
40
41
RtReadPort* (Uchar, Ushort, Ulong) : ces fonctions lisent directement une donne de un, deux ou quatre octets directement depuis un port dE/S, puis retournent sa valeur. RtWritePort* (Uchar, Ushort, Ulong) : ces fonctions crivent directement une donne de un, deux ou quatre octets directement dans un port dE/S. RtReadPortBuffer* (Uchar, Ushort, Ulong) : ces fonctions copient dans un tampon, directement depuis un port dE/S, une srie de donnes constitues chacune de un, deux ou quatre octets. RtWritePortBuffer* (Uchar, Ushort, Ulong) : ces fonctions copient depuis un tampon, directement dans un port dE/S, une srie de donnes constitues chacune de un, deux ou quatre octets.
******************
42
Annexe 1
Annexe 1
Fiches descriptives des principales fonctions API
de gestion des processus et des threads : CreateThread GetCurrentThread Sleep SuspendThread ResumeThread ExitThread GetExitCodeThread dusage gnral : GetLastError SetLastError RtPrintf CloseHandle RtAllocateLocalMemory RtQueryLocalMemory RtFreeLocalMemory RtCloseHandle
Les fiches sont classes par ordre alphabtique des noms de fonction1 : CloseHandle CreateThread ExitThread GetCurrentThread GetExitCodeThread GetLastError ResumeThread RtAllocateLocalMemory RtCloseHandle RtCreateProcess RtFreeLocalMemory RtGetExitCodeProcess RtGetThreadPriority RtGetThreadTimeQuantum RtOpenProcess RtPrintf RtQueryLocalMemory RtSetThreadPriority RtSetThreadTimeQuantum RtSleepFt SetLastError Sleep SuspendThread (d) d d d d (d)
d d d d
d d d d d d d
La lettre d en face du nom de la fonction indique quil sagit dune fonction dterministe : le temps coul lors de lappel de la fonction est infrieur 5 s. (d) indique que la fonction nest dterministe que si lallocation de mmoire requise par la fonction se fait partir de la zone de mmoire locale. Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
43
Annexe 1
CloseHandle
Fonctions dusage gnral La fonction CloseHandle permet de clore un handle vers un objet.
BOOL
CloseHandle (
HANDLE
hObject,
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Lorsque est clos le dernier handle vers un objet, ce dernier est dtruit. Commentaires Bien que dans lenvironnement RTSS CloseHandle puisse tre utilise pour clore les handles vers les objets RTSS, utilisez de prfrence la fonction RtCloseHandle. Une exception cependant ! Utilisez CloseHandle pour clore un handle vers un thread RTSS. Dans lenvironnement Win32 CloseHandle permet uniquement de clore les handles vers les objets Win32. Voir : CreateThread RtCloseHandle
CreateThread
(d) Processus et threads La fonction CreateThread cre un thread lintrieur de lespace dadressage du processus appelant. Suivant lenvironnement dexcution du processus appelant (environnement Win32 ou environnement RTSS), CreateThread cre un thread Win32 ou un thread RTSS.
HANDLE
CreateThread (
// paramtre ignor
NULL,
DWORD
StackSize, // 0 (valeur par dfaut) ou nombre doctets allous la pile du thread LPTHREAD_START_ROUTINE lpStartAddress, // nom de la fonction que doit excuter le thread LPVOID lpParameter, // NULL ou pointeur sur une donne de nimporte quel type passer au thread DWORD dwCreationFlags, // indicateur dont les valeurs possibles sont 0 et CREATE_SUSPENDED LPDWORD lpThreadId, // NULL ou pointeur sur une variable de 32 bits ); En cas de succs, la fonction retourne un handle vers le thread cr. En cas dchec, la valeur retourne est NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres StackSize Si la valeur de ce paramtre est 0, la taille de la pile du nouveau thread sera : de 8192 octets, si lon est dans lenvironnement RTSS, celle de la pile du thread appelant, si lon est dans lenvironnement Win32. Dans lenvironnement Win32, la taille de la pile augmente quand cela est ncessaire ; par contre, dans lenvironnement RTSS, elle ne peut pas augmenter. lpStartAddress Lexcution du thread commence au dbut de la fonction spcifie par ce paramtre. Ce paramtre doit normalement tre prcd du cast suivant : (LPTHREAD_START_ROUTINE). 44
Annexe 1
dwCreationFlags Si la valeur de ce paramtre est 0, le thread cr dmarre immdiatement son excution. Si la valeur est CREATE_SUSPENDED, le thread cr est mis dans ltat suspendu ; il ne dmarrera son excution que suite un appel de la fonction ResumeThread. lpThreadId Cest un pointeur sur une variable destine recevoir lidentifiant du thread cr. Commentaires Le thread commence son excution au dbut de la fonction spcifie par le paramtre lpStartAddress. Celle-ci accepte comme argument dentre une valeur de 32 bits (cf. paramtre lpParameter). En sortie, elle retourne une valeur de 32 bits ; quand cela se produit, cette valeur est utilise dans lappel implicite ExitThread pour terminer le thread. Le thread est cr avec une priorit de thread de 0. Les fonctions RtGetThreadPriority et RtSetThreadPriority permettent respectivement dobtenir et de modifier la valeur de priorit dun thread. Un objet thread reste dans le systme jusqu ce quil se termine et que tous les handles vers cet objet aient t clos. Pour clore un handle vers un thread Win32 ou un thread RTSS, il faut dans tous les cas utiliser la fonction CloseHandle. Voir : CloseHandle ExitThread ResumeThread RtGetThreadPriority RtSetThreadPriority GetExitCodeThread
Extrait dun programme illustrant lappel de fonctions API relatives aux threads Win32 RTX #include <windows.h> #include <rtapi.h> HANDLE hMaTache ; int prioriteThreadPrimaire ; DWORD WINAPI maTache (PINT pPar) ; int main (int argc, char * argv[]) // Thread primaire dun processus Win32 RTX { RtSetThreadPriority (GetCurrentThread(), RT_PRIORITY_MIN + 1) ; prioriteThreadPrimaire = RtGetThreadPriority (GetCurrentThread()) ; hMaTache = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) maTache, NULL , CREATE_SUSPENDED, NULL) ; RtSetThreadPriority (hMaTache, prioriteThreadPrimaire + 4) ; ResumeThread (hMaTache) ; // Demander au thread maTache de se terminer WaitForSingleObject (hMaTache, INFINITE) ; // Attendre la fin du thread Win32 maTache CloseHandle (hMaTache) ; return 0 ; } DWORD WINAPI maTache (PVOID pvoid) { return 0 ; } // Fonction du thread maTache
45
Annexe 1
Extrait dun programme illustrant lappel de fonctions API relatives aux threads RTSS #include <windows.h> #include <rtapi.h> HANDLE hMaTache ; int argEn ; int prioriteThreadPrimaire ; DWORD WINAPI maTache (PINT pPar) ; void _cdec1 main (int argc, char **argv, char **envp) // Thread primaire dun processus RTSS { RtSetThreadPriority (GetCurrentThread(), RT_PRIORITY_MIN + 5) ; prioriteThreadPrimaire = RtGetThreadPriority (GetCurrentThread()) ; hMaTache = CreateThread (NULL, 0, maTache, &argEn, CREATE_SUSPENDED, NULL) ; RtSetThreadPriority (hMaTache, prioriteThreadPrimaire + 1) ; ResumeThread (hMaTache) ; // Demander au thread maTache de se terminer RtWaitForSingleObject (hMaTache, INFINITE) ; // Attendre la fin du thread RTSS maTache CloseHandle (hMaTache) ; return ; } DWORD WINAPI maTache (PINT pPar) { return 0 ; } // Fonction du thread maTache
Pour que le thread primaire puisse attendre la fin du thread maTache, on doit crire : WaitForSingleObject (hMaTache, INFINITE) ; RtWaitForSingleObject (hMaTache, INFINITE) ; si maTache est un thread Win32 si maTache est un thread RTSS
Passage de donnes un thread On peut utiliser des variables globales pour passer des informations un thread. En effet tous les threads dun mme processus utilisent le mme espace dadressage. De ce fait, un pointeur sur des donnes est valable et accessible pour tous les threads du processus. Il est cependant conseill dviter dabuser des variables globales : elles nuisent la lisibilit et la maintenance du code. Une seconde mthode pour passer des informations un thread consiste utiliser, lors de la cration du thread, le paramtre lpParamter de la fonction CreateThread. Ce dernier peut tre utilis pour passer un pointeur sur une variable simple ou bien un pointeur sur une structure contenant lensemble des valeurs transmettre au nouveau thread. i Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
46
Annexe 1
ExitThread
Processus et threads La fonction ExitThread termine un thread.
VOID
ExitThread (
DWORD
ExitCode,
); Cette fonction ne retourne pas de valeur. A propos des paramtres ExitCode Le code de sortie du thread appelant peut tre rcupr par un autre thread laide de la fonction GetExitCodeThread. Commentaires La mthode prfre de terminaison dun thread est celle o le thread lui-mme excute la fonction ExitThread. Quand cette fonction est appele soit explicitement soit indirectement lors du retour de la fonction du thread, la pile du thread courant est dsaffecte, et le thread se termine. Si, lorsque cette fonction est appele, le thread est le dernier thread actif du processus, le processus se termine galement. Il en est de mme si le thread primaire appelle ExitThread. La terminaison dun thread nentrane pas ncessairement une suppression de lobjet thread. Un objet thread est dtruit lorsque est clos le dernier handle vers cet objet. Voir : CreateThread GetExitCodeThread
Fin dexcution dun thread La mthode conseille darrt de lexcution dun thread consiste lui adresser une notification lui demandant deffectuer une sortie en douceur, cest--dire de se terminer proprement. Cette mthode suppose que le thread en question soit en mesure de vrifier rgulirement si une telle notification lui a t ou non adresse. Par un mcanisme de signalisation appropri, le thread doit donc tre en mesure de dtecter une demande darrt de ses activits, demande quun autre thread (en gnral le thread primaire) est susceptible tout moment de lui adresser.
GetCurrentThread
d Processus et threads
GetCurrentThread (VOID) ;
Cette fonction na pas de paramtre dappel. Commentaires Un pseudo-handle est une constante particulire qui est interprte comme tant le handle du thread courant. Le thread appelant peut utiliser cet handle pour se spcifier luimme chaque fois quun handle de thread est requis.
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
47
Annexe 1
Cette fonction ne peut pas tre utilise par un thread pour crer un handle destin tre utilis par dautres threads dsirant faire rfrence au premier thread. Le handle retourn par GetCurrentThread est toujours interprt comme se rfrant au thread qui lutilise. Quand on nen a plus utilit, il nest pas ncessaire de clore un pseudo-handle ; appeler la fonction CloseHandle vers ce type de handle comme paramtre ne produit aucun effet. Voir : CloseHandle CreateThread
GetExitCodeThread
d Processus et threads La fonction GetExitCodeThread rcupre le code de sortie du thread spcifi.
BOOL
GetExitCodeThread (
hThread, // handle de thread LPDWORD lpExitCode, // pointeur sur une variable de 32 bits destine recevoir
HANDLE // le code de sortie du thread
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Si le thread spcifi nest pas termin, le code de sortie retourn par la fonction est STILL_ACTIVE. Si le thread est termin, le code de sortie peut tre lune des valeurs suivantes : le code de sortie spcifi dans ExitThread, la valeur de retour de la fonction du thread, la valeur de sortie du processus auquel appartient le thread. Voir : CreateThread ExitThread
GetLastError
d Fonctions dusage gnral La fonction GetLastError retourne la valeur du code de la dernire erreur gnre au niveau du thread appelant. Cette fonction na pas de paramtre dappel.
DWORD
GetLastError (VOID) ;
Commentaires Le code de la dernire erreur dtecte par une fonction API est gr au niveau de chaque thread. Les fonctions API modifient la valeur de ce code en appelant SetLastError. Il est recommand dappeler GetlastError immdiatement aprs quune fonction API a indiqu quil tait opportun de le faire. En effet, en cas de succs certaines fonctions appellent SetLastError(0), effaant ainsi le code derreur mmoris par la dernire fonction ayant signal une erreur. Voir : SetLastError
Known issue: In the RTSS environment, GetLastError will always return correct information. However, when a Win32 RTX call fails, GetLastError may not return the correct error code if the API
reference does specify the use of GetLastError.
48
Annexe 1
ResumeThread
d Processus et threads
La fonction ResumeThread dcrmente de 1 le compte de suspension dexcution dun thread. Si la valeur de ce compte atteint zro, lexcution du thread reprend.
DWORD
ResumeThread (
hThread
// handle de thread
HANDLE
); En cas de succs, la fonction retourne la valeur quavait le compte de suspension dexcution du thread immdiatement avant lappel de la fonction. En cas dchec, la valeur retourne est 0xFFFFFFFF ; lappel de GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction ResumeThread teste le compte de suspension dexcution du thread indiqu. Si ce compte est gal 0, le thread nest pas suspendu ; sinon, le compte est dcrment de 1 ; si le rsultat est gal 0, le thread reprend son excution. Si la valeur retourne est gale 0, le thread ntait pas suspendu. Si la valeur est gale 1, le thread tait suspendu, mais son excution a maintenant repris. Si la valeur est suprieure 1, le thread tait dj suspendu au moment de lappel de la fonction, et il lest toujours. Voir : SuspendThread
RtAllocateLocalMemory
(d) Fonctions dusage gnral La fonction RtAllocateLocalMemory alloue de la mmoire de la zone mmoire dterministe (deterministic memory pool).
PVOID
RtAllocateLocalMemory (
ULONG
Size
); En cas de succs, la fonction retourne un pointeur vers la zone mmoire alloue. En cas dchec, elle retourne un pointeur NULL. Commentaires RtAllocateLocalMemory alloue de la mmoire dans lespace dadressage de mmoire virtuelle du processus. Puisque RtAllocateLocalMemory alloue de la mmoire dune zone mmoire locale au sous systme RTSS, il sagit dune allocation de mmoire dterministe. Si cette zone mmoire locale na pas encore t cre ou si la mmoire disponible dans cette zone nest pas suffisante, RtAllocateLocalMemory adresse une demande dallocation mmoire Windows travers le module SRI. Le caractre dterministe de lallocation mmoire est alors perdu. Pour viter cela, appelez au pralable la fonction RtQueryLocalMemory pour savoir sil y a assez de mmoire disponible dans la zone de mmoire locale du sous systme RTSS. Voir : RtFreeLocalMemory RtQueryLocalMemory
49
Annexe 1
RtCloseHandle
Fonctions dusage gnral La fonction RtCloseHandle permet de clore un handle vers un objet.
BOOL
RtCloseHandle (
HANDLE
hObject,
// handle dobjet
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction RtCloseHandle permet de clore les handles vers les objets RTSS suivants :
RtCreateProcess
Processus et threads La fonction RtCreateProcess cre et dmarre un nouveau processus RTSS. Cette fonction ne peut tre utilise que dans lenvironnement Win32.
HANDLE
RtCreateProcess (
lpApplicationName, // NULL ou pointeur sur le nom dun fichier excutable .rtss LPTSTR lpCommandeLine, // NULL ou pointeur sur une chane de caractres NULL, NULL, FALSE, 0, NULL, NULL, NULL, // paramtres ignors LPPROCESS_INFORMATION lpProcessInformation,
LPCTSTR // pointeur sur une structure PROCESS_INFORMATION
); En cas de succs, la fonction retourne une valeur non nulle. En cas dchec, elle retourne 0 ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres lpApplicationName Cest un pointeur sur une chane de caractres zro terminal dsignant le module excuter. La chane doit spcifier le chemin complet et le nom du fichier excuter ; ce doit tre une application RTSS1. La valeur de lpApplicationName peut tre NULL ; dans ce cas, dans la chane pointe par lpCommandLine, le nom du module doit tre le 1er lment dlimit par un espace. lpCommandLine Cest un pointeur sur une chane de caractres zro terminal spcifiant la ligne de commande excuter. Sa valeur peut tre NULL ; dans ce cas, la fonction utilise comme ligne de commande la chane pointe par lpApplicationName.
1
Si le nom du fichier ne contient pas dextension, lextension .rtss est appose au nom indiqu.
50
Annexe 1
lpProcessInformation Cest un pointeur sur une structure PROCESS_INFORMATION destine recevoir linformation didentification du nouveau processus. Pour plus dinformations sur ces paramtres, se rfrer RTX Documentation. Commentaires La fonction RtCreateProcess permet de crer et lancer un nouveau processus RTSS partir dun processus Win32 RTX. En fait, cette fonction fait appel lutilitaire RTSSrun pour crer et lancer le nouveau processus RTSS. Un handle vers le nouveau processus RTSS est retourne dans la structure PROCESS_INFORMATION ; il peut tre utilis dans nimporte quelle fonction qui requiert un handle vers ce type dobjet. De mme, lidentifiant assign au nouveau processus RTSS est retourn dans la structure PROCESS_INFORMATION ; il peut tre utilis dans la fonction RtOpenProcess pour spcifier le processus ouvrir. Cet identifiant est valide jusqu ce que le processus se termine. La fonction RtCreateProcess ne cre pas un handle vers le thread primaire du nouveau processus RTSS. En consquence, pour lpProcessInformation hThread la valeur retourne est NULL, et pour lpProcessInformation dwThreadId elle est 0.
The PROCESS_INFORMATION structure is filled in by the RtCreateProcess function with information about a newly created process and its primary thread.
typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; // valeur retourne : NULL DWORD dwProcessId; DWORD dwThreadId; // valeur retourne : 0 } PROCESS_INFORMATION ;
hProcess hThread dwProcessId dwThreadId Returns a handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object. Returns a handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object. Returns a global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated. Returns a global thread identifiers that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated.
La mthode prfre de fermeture dun processus RTSS est celle o chaque thread du processus se termine en excutant la fonction ExitThread (voir ExitThread). Lorsque tous les threads du processus se sont ainsi termins, le processus lui-mme se termine automatiquement. Quand sest termin le dernier thread dun processus RTSS : tous les objets ouverts par le processus RTSS sont implicitement clos, le code de sortie du processus passe de la valeur STILL_ACTIVE celle retourne par le dernier thread stre termin, lobjet process RTSS est mis dans ltat signal, ce qui permet de satisfaire les threads en attente sur cet objet. Quand le dernier thread dun processus RTSS sest termin et que tous les handles vers le processus ont t clos par des appels RtCloseHandle, le processus RTSS est retir du systme dexploitation. Voir : CloseHandle CreateThread RtGetExitCodeProcess RtOpenProcess
51
Annexe 1
Extrait de programme illustrant lappel de fonctions API relatives aux processus #include <windows.h> #include <rtapi.h> int main (int argc, char* argv[]) // Thread primaire dun processus Win32 RTX { PROCESS_INFORMATION prInfo ; int codeSortie ; RtCreateProcess ("monApplication.rtss", // Crer et lancer un processus RTSS NULL, NULL, NULL, false, 0, NULL, NULL, NULL, &prInfo) ; // Envoyer au processus RTSS un message lui demandant de se terminer RtWaitForSingleObject (prInfo.hProcess, INFINITE) ; // Attendre la fin du processus RTSS RtGetExitCodeProcess (prInfo.hProcess, &codeSortie) ; // Rcuprer son code de sortie RtCloseHandle (prInfo.hProcess) ; // Clore le handle vers le processus RTSS
.
return 0 ; }
RtFreeLocalMemory
d Fonctions dusage gnra La fonction RtFreeLocalMemory libre la mmoire prcdemment alloue la suite dun appel RtAllocateLocalMemory.
BOOL
RtFreeLocalMemory (
PVOID
pVirtualAddress
// pointeur vers le dbut dune zone mmoire // (tel quil a t retourn par RtAllocateLocalMemory)
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE. Voir : RtAllocateLocalMemory RtQueryLocalMemory
RtGetExitCodeProcess
d Processus et threads La fonction RtGetExitCodeProcess rcupre le code de sortie du processus spcifi.
BOOL
RtGetExitCodeProcess (
hProcess, LPDWORD lpExitCode,
HANDLE // handle de processus // pointeur sur une variable de 32 bits destine recevoir // le code de sortie du processus
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur.
52
Annexe 1
Commentaires Si le processus spcifi nest pas termin, le code de sortie retourn par la fonction est STILL_ACTIVE. Si le processus est termin, le code de sortie peut tre lun des suivants : le code de sortie spcifi dans ExitProcess ou RtTerminateProcess, la valeur de retour de la fonction main ou WinMain du processus, la valeur de lexception qui a provoqu la fin du processus. Voir : RtCreateProcess
RtGetThreadPriority
d Processus et threads La fonction RtGetThreadPriority retourne le niveau de priorit du thread spcifi.
INT
RtGetThreadPriority (
HANDLE
hThread,
); En cas de succs, la fonction retourne le niveau de priorit du thread spcifi. En cas dchec, elle retourne THREAD_PRIORITY_ERROR_RETURN ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Se reporter au 3.3.2 Spectre des niveaux de priorit des threads Win32 RTX pour des explications sur les correspondances entre les niveaux de priorit de thread des sous systmes Win32 et RTSS. Voir : RtSetThreadTime
RtGetThreadTimeQuantum
d La fonction RtGetThreadTimeQuantum retourne millisecondes, du quantum de temps du thread spcifi.
DWORD
RtGetThreadTimeQuantum (
hThread, // handle de thread
HANDLE
); En cas de succs, la fonction retourne la valeur courante, en millisecondes, du quantum de temps du thread spcifi. En cas dchec, elle retourne 0 ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Dans lenvironnement Win32, 0 est la seule valeur valide pour le quantum de temps. Elle indique que cest la politique dordonnancement de Windows qui est applique. Dans lenvironnement RTSS, le quantum de temps peut tre nimporte quelle valeur 0. Une valeur de 0 signifie que le thread RTSS sexcutera jusqu laccomplissement de sa tche. La valeur par dfaut du quantum de temps peut tre change dans le panneau de commande de RTSS. Pour cela, lancer lutilitaire RTX Properties. Voir : RtSetThreadTimeQuantum
53
Annexe 1
RtOpenProcess
Processus et threads La fonction RtOpenProcess retourne un handle vers un objet processus existant.
HANDLE
RtOpenProcess (
// paramtre ignor // paramtre ignor // identifiant du processus ouvrir
En cas de succs, la fonction retourne un handle vers le processus spcifi. En cas dchec, elle retourne NULL ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Le handle retourn par RtOpenProcess peut tre utilis par toute fonction qui requiert un handle vers un processus, comme par exemple les fonctions dattente RtWaitForSingleObject ou RtWaitForMultiple Objects. Ce handle doit tre clos avec la fonction CloseHandle. Voir : CloseHandle RtCreateProcess
RtPrintf
Fonctions dusage gnral La fonction RtPrintf convertit, met en forme et imprime la valeur de ses arguments sur la sortie standard.
INT
RtPrintf (
LPCSTR
lpFormat [, argument,]
); En cas de succs, la fonction retourne le nombre de caractres imprims. En cas dchec, elle retourne une valeur ngative. Commentaires La fonction RtPrintf est similaire la fonction printf du langage C. Cependant, RtPrintf ne requiert pas la bibliothque dexcution du C, et peut sexcuter avec nimporte quelle combinaison de bibliothques dexcution. Par contre, dans lenvironnement RTSS, elle ne supporte pas les conversions en virgule flottante.
Pour plus dinformations sur cette fonction, se rfrer RTX Documentation ou la description de la fonction printf du langage C.
54
Annexe 1
RtQueryLocalMemory
d Fonctions dusage gnral
La fonction RtQueryLocalMemory retourne un certain nombre dinformations au sujet de la zone mmoire dterministe (deterministic memory pool).
BOOL
RtQueryLocalMemory (
MemSize, // taille totale en octets de la zone mmoire locale // taille en octets de la mmoire disponible dans cette zone PULONG MemAvail, PULONG MemContig, // taille en octets du bloc le plus grand de mmoire contigu disponible );
PULONG
En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE. Voir : RtAllocateLocalMemory RtFreeLocalMemory
RtSetThreadPriority
d Processus et threads La fonction RtSetThreadPriority attribue une valeur de priorit au thread spcifi.
BOOL
RtSetThreadPriority (
HANDLE
hThread, // handle vers le thread dont la valeur de priorit est dfinir int nPriority, // valeur du niveau de priorit ); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres nPriority Ce paramtre indique le niveau de priorit dsir pour le thread. Sa valeur est comprise entre 0 et 127, 127 correspondant au niveau de priorit le plus lev. Commentaires tant donn que les processus Win32 RTX peuvent utiliser cette fonction RtSetThreadPriority et qu lintrieur de la classe de priorit REALTIME (REALTIME_PRIORITY_CLASS), 7 niveaux de priorit de thread sont dfinissables par programme, la fonction RtSetThreadPriority doit rpartir ces 7 niveaux de priorit entre les 128 valeurs de priorit possibles pour le paramtre nPriority (cf. 3.3.2 Spectre des niveaux de priorit des threads Win32 RTX). Voir : RtGetThreadPriority
55
Annexe 1
RtSetThreadTimeQuantum
d Processus et threads La fonction RtSetThreadTimeQuantum modifie le quantum de temps du thread spcifi.
BOOL
RtSetThreadTimeQuantum (
hThread, DWORD dwQuantumInMS, );
HANDLE
// handle vers le thread dont le quantum de temps est dfinir // nouvelle valeur du quantum de temps en millisecondes
En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Dans lenvironnement Win32, 0 est la seule valeur valide pour le quantum de temps. Cette valeur indique que cest la politique dordonnancement de Windows qui est applique. Dans lenvironnement RTSS, le quantum de temps peut tre nimporte quelle valeur suprieure ou gale 0. Une valeur de 0 signifie que le thread RTSS sexcutera jusqu laccomplissement de sa tche. La valeur par dfaut du quantum de temps peut tre change dans le panneau de commande de RTSS. Pour cela, lancer lutilitaire RTX Properties. Voir : RtGetThreadTimeQuantum
RtSleepFt
d Processus et threads La fonction RtSleepFt suspend lexcution du thread courant pendant le laps de temps spcifi.
VOID
RtSleepFt (
PLARGE_INTEGER
pDuration,
); Cette fonction ne retourne pas de valeur. A propos des paramtres pDuration Ce paramtre spcifie en units de 100 nanosecondes la dure de sommeil du thread courant. Sa valeur doit tre infrieure ou gale une seconde, et suprieure ou gale la priode timer minimale du systme. En donnant une valeur nulle ce paramtre, le thread courant cde le processeur aux ventuels threads de mme priorit que lui, prts sexcuter. Voir : Sleep
Known issue
RtSleepFt() can return early from a sleep period. It can return within one HAL timer tick early of the requested time. For instance, if the HAL timer is at 200 s, RtSleepFt() can return up to 200 s earlier than the requested time.
56
Annexe 1
SetLastError
d Fonctions dusage gnral La fonction SetLastError mmorise pour le thread appelant le code de la dernire erreur.
VOID
SetLastError (
DWORD
ErrCode,
); Cette fonction ne retourne pas de valeur. Commentaires Les codes derreur sont des valeurs sur 32 bits (le bit 31 est le bit le plus significatif). Le bit 29 est rserv pour les codes derreur des applications ; aussi aucun code derreur des fonctions de la RTAPI nutilise ce bit. Lors de la dfinition dun code derreur pour votre application, mettez le bit 29 1, et assurez-vous que le code derreur ainsi dfini nentre pas en conflit avec les codes derreur dfinis pour le systme dexploitation. La plupart des fonctions de RTX appelle SetLastError quand elles chouent. Lchec de la fonction appele est gnralement indique par une valeur de retour telle que FALSE, NULL, 0xFFFFFFFF ou 1. Les applications peuvent, en utilisant GetLastError, rcuprer la valeur mmorise par la fonction SetLastError. Lappel facultatif de GetLastError permet une application de connatre la raison de lchec dune fonction. Le code de la dernire erreur est stock dans une variable locale au thread. Ainsi, dans une application multitche il ne peut y avoir, de la part des threads, dcrasement rciproque de la valeur de ces codes derreur. Voir : GetLastError
Sleep
d Processus et threads La fonction Sleep suspend lexcution du thread courant pendant le laps de temps spcifi.
VOID
Sleep (
ULONG
milliSeconds,
57
Annexe 1
SuspendThread
d Processus et threads La fonction SuspendThread suspend lexcution du thread spcifi, cest--dire arrte lexcution de ce dernier.
DWORD
SuspendThread (
hThread,
// handle du thread suspendre
HANDLE
); En cas de succs, la fonction retourne la valeur quavait, avant lappel de la fonction, le compte de suspension dexcution du thread. En cas dchec, la valeur retourne est 0xFFFFFFFF ; lappel de GetLastError permet alors dobtenir le code de lerreur. Commentaires En cas de succs, lexcution du thread spcifi est suspendue, et le compte de suspension dexcution du thread est incrment de 1. Chaque thread possde en effet un compte de suspension dexcution ; lorsque la valeur de ce compte est suprieure 0, lexcution du thread est suspendue La fonction ResumeThread dcrmente de 1 le compte de suspension dexcution du thread spcifi. Voir : ResumeThread
*********
58
Annexe 2
Annexe 2
Fiches descriptives des fonctions API temps rel relatives la gestion
des objets shared memory : RtCreateSharedMemory RtOpenSharedMemory des objets semaphore : RtCreateSemaphore RtOpenSemaphore RtReleaseSemaphore RtWaitForSingleObjet RtWaitForMultipleObjects des objets mutex : RtCreateMutex RtOpenMutex RtReleaseMutex RtWaitForSingleObjet RtWaitForMultipleObjects des objets event : RtCreateEvent RtOpenEvent RtSetEvent RtPulseEvent RtResetEvent RtWaitForSingleObjet RtWaitForMultipleObjects Les fiches sont classes par ordre alphabtique des noms de fonction1 : RtCreateEvent RtCreateMutex RtCreateSemaphore RtCreateSharedMemory RtOpenEvent RtOpenMutex RtOpenSemaphore RtOpenSharedMemory RtPulseEvent RtReleaseMutex RtReleaseSemaphore RtResetEvent RtSetEvent RtWaitForMultipleObjects RtWaitForSingleObjet
1
(d)
(d) (d) (d) (d) (d) (d) (d) d d d d d d d
La lettre d en face du nom de la fonction indique quil sagit dune fonction dterministe : le temps coul lors de lappel de la fonction est infrieur 5 s. (d) indique que la fonction nest dterministe que si lallocation de mmoire requise par la fonction se fait partir de la zone de mmoire locale.
59
Annexe 2
RtCreateEvent (
// paramtre ignor // spcifie le type de lobjet : event reset manuel ou event reset automatique // tat initial de lobjet event cr // NULL ou pointeur vers une chane de caractres spcifiant le nom de lobjet
En cas de succs, la fonction retourne un handle vers le nouvel objet event. Si lobjet event avec le nom indiqu existait dj avant lappel de la fonction, GetLastError retourne ERROR_ALREADY_EXISTS ; dans le cas contraire, elle retourne 0. En cas dchec, la valeur retourne par la fonction est NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres bManualReset Ce paramtre indique si lobjet crer est : un event reset manuel : bManualReset = TRUE, ou un event reset automatique : bManualReset = FALSE. bInitialState Ce paramtre permet de spcifier ltat initial de lobjet event cr : si bInitialState = TRUE, ltat initial est ltat signal, si bInitialState = FALSE, ltat initial est ltat non-signal. lpName Ce paramtre est une chane de caractres zro terminal limite RTX_MAX_PATH caractres et pouvant contenir nimporte quel caractre except lanti-slash (\). Si lpName correspond au nom dun objet event existant, la fonction RtCreateEvent retourne un handle vers cet objet. Dans ce cas, les paramtres bManualReset et bInitialState sont ignors car ils ont dj t spcifis par le processus crateur de lobjet. Si lpName correspond au nom dun objet existant de type mutex, semaphore ou shared memory, la fonction choue, et GetLastError retourne ERROR_INVALID_HANDLE. Si lpNmal est NULL, lobjet event est cr sans nom. Commentaires Ltat initial de lobjet event est spcifi par bInitialState. La fonction RtSetEvent met un objet event dans ltat signal ; la fonction RtResetEvent le met dans ltat non-signal. Lorsquun objet event reset manuel est dans ltat signal, il reste dans cet tat jusqu ce quil soit explicitement mis dans ltat non-signal par RtResetEvent. Tant que lobjet event est dans ltat signal, tout thread qui est en attente ou qui se met en attente sur cet objet peut poursuivre son excution. Lorsquun objet event reset automatique est dans ltat signal, il reste dans cet tat jusqu ce quun thread en attente, et un seul, soit libr ; le systme remet alors automatiquement lobjet event dans ltat non signal. Si aucun thread nest en attente, lobjet event reste dans ltat signal. Voir : RtCloseHandle RtOpenEvent RtPulseEvent RtResetEvent RtSetEvent
60
Annexe 2
RtCreateMutex (
// paramtre ignor // spcifie ltat de possession initial de lobjet mutex // NULL ou pointeur vers une chane de caractres spcifiant le nom de lobjet
NULL,
En cas de succs, la fonction retourne un handle vers le nouvel objet mutex. Si lobjet mutex avec le nom indiqu existait dj avant lappel de la fonction, GetLastError retourne ERROR_ALREADY_EXISTS ; dans le cas contraire, elle retourne 0. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres bInitialOwner Si la valeur de ce paramtre est TRUE, le thread appelant devient immdiatement propritaire de lobjet mutex cr. lpName Ce paramtre est une chane de caractres zro terminal limite RTX_MAX_PATH caractres et pouvant contenir nimporte quel caractre except lanti-slash (\). Si lpName correspond au nom dun objet mutex existant, la fonction RtCreateMutex retourne un handle vers lobjet existant. Dans ce cas, le paramtre bInitialOwner est ignor car il a dj t spcifi par le thread crateur de lobjet mutex. Si lpName correspond au nom dun objet existant de type event, semaphore ou shared memory, la fonction choue, et GetLastError retourne ERROR_INVALID_HANDLE. Si lpNmal est NULL, lobjet mutex est cr sans nom. Commentaires Un objet mutex est dans ltat signal sil nest la proprit daucun thread. Le thread crateur du mutex peut utiliser le paramtre bInitialOwner pour demander la proprit immdiate du mutex. Hors ce cas, un thread doit utiliser une fonction dattente (RtWaitForSingleObject ou RtWaitForMultipleObjects) pour demander la proprit dun objet mutex. Lorsque un mutex est dans ltat signal, le thread le plus prioritaire parmi ceux en attente sur lobjet obtient la proprit du mutex. Celui-ci passe alors dans ltat non signal ; et il y a retour de la fonction dattente. Un mutex ne peut tre la proprit un instant donn que dun seul thread. Le thread propritaire utilise la fonction RtReleaseMutex pour librer le mutex. Plusieurs processus peuvent utiliser la fonction RtCreateMutex pour le mme objet mutex ; ceci est quivalent ce que lun deux appelle la fonction RtCreateMutex et les autres la fonction RtOpenMutex. Mais si cette technique est utilise (tous appelant la fonction RtCreateMutex), aucun processus ne devrait demander la proprit immdiate du mutex. Lorsque plusieurs processus demandent la proprit immdiate dun objet mutex, il peut tre difficile en effet de prdire quel processus lobtiendra effectivement. Voir : RtCloseHandle RtOpenMutex RtReleaseMutex
61
Annexe 2
RtCreateSemaphore (
// paramtre ignor // valeur initiale du compteur // valeur maximale du compteur
NULL, LONG
lInitialCount, LONG lMaximumCount, LPCTSTR lpName, // NULL ou pointeur vers une chane de caractres spcifiant le nom de lobjet ); En cas de succs, la fonction retourne un handle vers lobjet semaphore. Si lobjet semaphore avec le nom indiqu existait dj avant lappel de la fonction, GetLastError retourne ERROR_ALREADY_EXISTS ; dans le cas contraire, elle retourne 0. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres lInitialCount La valeur de ce paramtre doit tre dune part suprieure ou gale zro, et dautre part infrieure ou gale lMaximumCount. Elle spcifie la valeur initiale du compteur. lMaximumCount Ce paramtre doit avoir une valeur suprieure zro. lpName Ce paramtre est une chane de caractres zro terminal limite RTX_MAX_PATH caractres et pouvant contenir nimporte quel caractre except lanti-slash (\). Si lpName correspond au nom dun objet semaphore existant, la fonction RtCreateSemaphore retourne un handle vers lobjet existant. Dans ce cas, les paramtres lInitialCount et lMaximumCount sont ignors car ils ont dj t spcifis par le thread crateur de lobjet semaphore. Si lpName correspond au nom dun objet existant de type event, mutex, ou shared memory, la fonction choue, et GetLastError retourne ERROR_INVALID_HANDLE. Si lpNmal est NULL, lobjet semaphore est cr sans nom. Commentaires Un objet semaphore est dans ltat signal lorsque la valeur de son compteur est suprieure zro, et dans ltat non signal lorsque cette valeur est gal zro. Chaque fois quest satisfaite lattente dun thread sur un objet semaphore, son compteur est dcrment de 1. Lappel de la fonction RtReleaseSemaphore incrmente le compteur dune valeur spcifie. Le compteur ne peut jamais avoir une valeur infrieure zro ni suprieure la valeur donne par le paramtre lMaximumCount. Voir : RtCloseHandle RtOpenSemaphore RtReleaseSemaphore
62
Annexe 2
RtCreateSharedMemory (
lpProtect, // protection dsire pour laccs la mmoire partage MaximumSizeHigh, // taille de lobjet shared memory : les 32 bits de poids fort DWORD MaximumSizeLow, // taille de lobjet shared memory : les 32 bits de poids faible LPCTSTR lpName, // NULL ou pointeur vers une chane de caractres spcifiant le nom de lobjet VOID **location, // pointeur vers lemplacement o sera stocke ladresse de la mmoire partage ); En cas de succs, la fonction retourne un handle vers lobjet shared memory. Si lobjet shared memory avec le nom indiqu existait dj avant lappel de la fonction, GetLastError retourne ERROR_ALREADY_EXISTS, et la valeur retourne par RtCreateSharedMemory est un handle valide vers lobjet shared memory existant. Si lobjet shared memory avec le nom indiqu nexistait pas, GetLastError retourne 0. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur.
DWORD DWORD
A propos des paramtres flProtect Ce paramtre peut avoir lune des deux valeurs suivantes : PAGE_READONLY accs en lecture seule PAGE_READWRITE accs en criture et lecture lpName Ce paramtre est une chane de caractres zro terminal limite RTX_MAX_PATH caractres et pouvant contenir nimporte quel caractre except lanti-slash (\). Si lpName correspond au nom dun objet shared memory existant, la fonction RtCreateSharedMemory retourne un handle vers lobjet existant, avec comme protection daccs celle indique par le paramtre flProtect. Si lpName correspond au nom dun objet existant de type event, mutex, ou semaphore, la fonction choue, et GetLastError retourne ERROR_INVALID_HANDLE. Si lpNmal est NULL, lobjet shared memory est cr sans nom. Voir : RtCloseHandle RtOpenSharedMemory
RtOpenEvent (
DesiredAccess, // paramtre ignor BOOL bInheritHandle, // paramtre ignor LPCTSTR lpName, // pointeur vers une chane de caractres zro terminal dsignant lobjet
DWORD // event ouvrir (les comparaisons de noms sont sensibles la case)
);
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
63
Annexe 2
En cas de succs, la fonction retourne un handle vers lobjet event. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction RtOpenEvent donne la possibilit plusieurs processus douvrir des handles vers le mme objet event. La fonction russit seulement si un processus a dj cr lobjet event en utilisant RtCreateEvent. Voir : RtCloseHandle RtCreateEvent RtPulseEvent RtResetEvent RtSetEvent
RtOpenMutex (
DesiredAccess, // paramtre ignor BOOL bInheritHandle, // paramtre ignor LPCTSTR lpName, // pointeur vers une chane de caractres zro terminal dsignant lobjet
DWORD // mutex ouvrir (les comparaisons de noms sont sensibles la case)
); En cas de succs, la fonction retourne un handle vers lobjet mutex. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction RtOpenMutex donne la possibilit plusieurs processus douvrir des handles vers le mme objet mutex. La fonction russit seulement si un processus a dj cr lobjet mutex en utilisant RtCreateMutex. Voir : RtCloseHandle RtCreateMutex RtReleaseMutex
RtOpenSemaphore (
DesiredAccess, // paramtre ignor BOOL bInheritHandle, // sa valeur doit tre FALSE LPCTSTR lpName, // pointeur vers une chane de caractres zro terminal dsignant lobjet
DWORD // semaphore ouvrir (les comparaisons de noms sont sensibles la case)
); En cas de succs, la fonction retourne un handle vers lobjet semaphore. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur.
64
Annexe 2
Commentaires La fonction RtOpenSemaphore donne la possibilit plusieurs processus douvrir des handles vers le mme objet semaphore. La fonction russit seulement si un processus a dj cr lobjet semaphore en utilisant RtCreateSemaphore. Voir : RtCloseHandle RtReleaseSemaphore
RtOpenSharedMemory (
DesiredAccess, // mode daccs la mmoire BOOL bInheritHandle, // paramtre ignor LPCTSTR lpName, // pointeur vers une chane de caractres zro terminal dsignant lobjet
DWORD // shared memory ouvrir (les comparaisons de noms sont sensibles la case) VOID
); En cas de succs, la fonction retourne un handle vers lobjet shared memory. En cas dchec, la fonction retourne NULL ; lappel de GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres DesiredAccess Ce paramtre spcifie le mode daccs la mmoire partage. Sa valeur peut tre une des deux valeurs suivantes :
Valeur SHM_MAP_WRITE SHM_MAP_READ Signification Accs en criture et lecture. Lobjet doit avoir t cr avec la protection daccs PAGE_READWRITE. Accs en lecture seule. Lobjet doit avoir t cr avec la protection daccs PAGE_READWRITE ou PAGE_READONLY.
Commentaires Dans le mme processus, diffrents appels RtOpenSharedMemory pour le mme objet shared memory peuvent retourner des valeurs diffrentes pour le paramtre location. Voir : RtCloseHandle RtCreateSharedMemory
65
Annexe 2
RtPulseEvent (
HANDLE
hEvent,
// handle vers un objet event (handle retourn par RtCreateEvent ou // par RtOpenEvent)
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Dans le cas dun objet event reset manuel, tous les threads en attente sont librs. Dans le cas dun objet event reset automatique, la fonction RtPulseEvent ne libre quun seul thread en attente, et cela, mme si plusieurs threads sont en attente. Si aucun thread nest en attente, la fonction RtPulseEvent met simplement lobjet event dans ltat non signal avant de retourner dans le thread appelant. Voir : RtCreateEvent RtOpenEvent RtResetEvent RtSetEvent
RtReleaseMutex d RtReleaseMutex (
HANDLE
Objets mutex
hMutex,
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction RtReleaseMutex choue si le thread appelant na pas la proprit de lobjet mutex spcifi. Un thread obtient la proprit dun objet mutex en spcifiant un handle vers cet objet dans une fonction dattente (RtWaitForSingleObject ou RtWaitForMultipleObjects). Le thread crateur dun objet mutex peut galement obtenir la proprit immdiate de celui-ci sans utiliser une fonction dattente (cf. RtCreateMutex). Quand le thread propritaire dun objet mutex na plus besoin de possder cet objet, il appelle la fonction RtReleaseMutex pour librer lobjet. Voir : RtCreateMutex RtWaitForSingleObject RtOpenMutex RtWaitForMultipleObjects
66
Annexe 2
RtReleaseSemaphore (
HANDLE LONG
hSemaphore,
// handle vers un objet semaphore (handle retourn par // RtCreateSemaphore ou par RtOpenSemaphore) // valeur dont le compteur doit tre incrment // NULL ou pointeur vers une variable de 32 bits
En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. A propos des paramtres lReleaseCount La valeur de ce paramtre doit tre suprieure zro. Si elle conduisait le compteur avoir une valeur suprieure sa valeur maximale (valeur spcifie au moment de la cration de lobjet semaphore), la valeur du compteur ne changerait pas et la fonction retournerait FALSE. lpPreviousCount La variable pointe par ce paramtre est destine recevoir la valeur du compteur avant son incrmentation. Si la connaissance de cette valeur nest pas ncessaire, lpPreviousCount peut tre gal NULL. Voir : RtCreateSemaphore RtOpenSemaphore
RtResetEvent (
HANDLE
hEvent,
// handle vers un objet event (handle retourn par RtCreateEvent ou par // RtOpenEvent)
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires Un objet event reste dans ltat non signal jusquil soit explicitement mis dans ltat signal par la fonction RtSetEvent ou RtPulseEvent. La fonction RtResetEvent est principalement utilise pour les objets event reset manuel ; ces objets event doivent en effet tre explicitement mis dans ltat non signal. Les objets event reset automatique passent automatiquement de ltat signal ltat non signal. Voir : RtCreateEvent RtOpenEvent RtPulseEvent RtSetEvent
67
Annexe 2
RtSetEvent d
La fonction RtSetEvent met dans ltat signal lobjet event spcifi.
BOOL
Objets event
RtSetEvent (
HANDLE
hEvent,
// handle vers un objet event (handle retourn par RtCreateEvent ou par // RtOpenEvent)
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. Commentaires La fonction RtSetEvent met donc dans ltat signal lobjet event spcifi. Sil sagit dun objet event reset manuel, il restera dans ltat signal jusqu ce quil soit explicitement remis dans ltat non signal par la fonction RtResetEvent. Tous les threads qui sont en attente sur cet objet vont poursuivre leur excution. Tant que lobjet restera dans ltat signal, tous les threads qui ultrieurement demanderont se mettre en attente sur cet objet poursuivront immdiatement leur excution. Sil sagit dun objet event reset automatique, ltat de lobjet event la sortie de la fonction RtSetEvent va dpendre du fait quil y ait ou non des threads en attente sur cet objet : Si des threads sont en attente sur cet objet, lobjet event est remis dans ltat non signal, et un seul des threads en attente voit son excution se poursuivre. Si aucun thread nest en attente sur cet objet, lobjet reste dans ltat signal jusquau prochain appel de la fonction RtWaitForSingleObject ou RtWaitForMultipleObjects impliquant cet objet. La fonction RtWaitFor fera alors office de fonction RtResetEvent. Voir : RtCreateEvent RtOpenEvent RtPulseEvent RtSetEvent
RtWaitForMultipleObjects (
nCount, *lpHandles,
// nombre de handles dobjet dans le tableau point par lpHandles // pointeur vers un tableau de handles dobjet // type dattente : la valeur de ce paramtre doit tre FALSE // INFINITE ou temps dattente maximum en millisecondes
DWORD
dwMilliseconds,
); En cas de succs, la fonction indique ce qui a provoqu le retour de la fonction. En cas dchec, elle retourne WAIT_FAILED ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur.
68
Annexe 2
Signification La valeur retourne moins WAIT_OBJECT_0 donne lindice dans le tableau lpHandles de lobjet qui a satisfait lattente. Si plusieurs objets sont dans ltat signal, celui qui a satisfait lattente est celui qui a la plus petite valeur dindice.
+ nCount - 1
WAIT_ABANDONED_0
La valeur retourne moins WAIT_ABANDONED_0 donne lindice dans le tableau lpHandles dun objet 1 qui a satisfait lattente. La WAIT_ABANDONED_0 + nCount - 1 mutex abandonn possession de ce mutex a t donne au thread appelant, et le mutex a t mis dans ltat non signal.
WAIT_TIMEOUT
Le temps dattente sest coul, et aucun des objets spcifis nest pass dans ltat signal.
Le thread propritaire de ce mutex na pas, avant de se terminer, restitu lobjet en appelant le fonction RtReleaseMutex ; on dit que lobjet mutex a t abandonn.
A propos des paramtres nCount La valeur maximale MAX_WFMO de ce paramtre est gale 16. lpHandles Ce paramtre est un pointeur sur un tableau de handles vers des objets RTSS de type process, thread, semaphore, mutex ou event. La liste des handles pointe par lpHandles peut contenir des handles vers des objets de diffrent type ; cependant elle ne doit pas contenir de copies multiples du mme handle. Tous les handles de cette liste doivent tre des handles valides. Si lun deux est clos pendant lattente, le comportement de la fonction est indfini. bWaitAll Ce paramtre spcifie le type dattente. Sa seule valeur possible est FALSE, indiquant une attente de type WAIT FOR ANY : la fonction attend que lun quelconque des objets spcifis soit dans ltat signal. dwMilliseconds Si la valeur de ce paramtre est 0, la fonction teste ltat des objets et retourne immdiatement. Si sa valeur est INFINITE, le temps dattente est illimit ; le retour de la fonction se fera seulement lorsque lun quelconque des objets spcifis sera trouv ou passera dans ltat signal. Commentaires La fonction RtWaitForMultipleObjects teste ltat de tous les objets spcifis ; si aucun deux nest dans ltat signal et que le paramtre dwMilliseconds a une valeur diffrente de 0, le thread appelant passe dans ltat en attente. La fonction modifie ltat de certains types dobjet de synchronisation (cf. Commentaires de la fonction RtWaitForSingleObject). Cette modification a lieu seulement pour lobjet dont ltat signal a provoqu le retour dans la tche. Voir : CreateThread RtOpenProcess RtCreateEvent RtCreateProcess RtCreateSemaphore RtOpenEvent RtOpenSempahore RtWaitForSingleObject RtCreateMutex RtOpenMutex
69
Annexe 2
RtWaitForSingleObjet d
La fonction RtWaitForSingleObject retourne : si ou ds que lobjet spcifi est dans ltat signal, ou bien lorsque sest coul le temps dattente indiqu.
DWORD
Objets IPC
RtWaitForSingleObject (
// handle vers un objet // INFINITE ou temps dattente maximum en millisecondes
En cas de succs, la fonction indique ce qui a provoqu le retour de la fonction. En cas dchec, elle retourne WAIT_FAILED ; lappel de la fonction GetLastError permet alors dobtenir le code de lerreur. En cas de succs, la valeur retourne est lune des valeurs suivantes :
Valeur
WAIT_OBJECT_0
Signification Lobjet spcifi est dans ltat signal. restitu, avant de se terminer, en appelant RtReleaseMutex. La possession du mutex a t donne au thread appelant, et le mutex a t mis dans ltat non signal.
WAIT_TIMEOUT
Le temps dattente sest coul, et lobjet est dans ltat non signal.
A propos des paramtres hHandle Ce paramtre est un handle vers un objet RTSS de type process, thread, semaphore, mutex ou event. dwMilliseconds Si la valeur de ce paramtre est 0, la fonction teste ltat de lobjet et retourne immdiatement. Si sa valeur est INFINITE, le temps dattente est illimit ; le retour de la fonction se fera alors seulement si lobjet spcifi est trouv ou passe dans ltat signal. Commentaires La fonction RtWaitForSingleObject teste ltat de lobjet spcifi. Si lobjet est dans ltat non signal et que le paramtre dwMilliseconds a une valeur diffrente de 0, le thread appelant passe dans ltat en attente. Lorsque lobjet est ou passe dans ltat signal, la fonction peut modifier ltat de lobjet avant deffectuer le retour dans la tche. Ainsi : sil sagit dun objet semaphore, son compteur est dcrment de 1, sil sagit dun objet mutex, celui-ci est mis dans ltat non signal, sil sagit dun objet event reset automatique, celui-ci est mis dans ltat non signal. Voir : CreateThread RtOpenProcess RtCreateEvent RtCreateProcess RtCreateSemaphore RtOpenEvent RtOpenSempahore RtWaitForSingleObject *********
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
RtCreateMutex RtOpenMutex
70
Annexe 3
Annexe 3
Fiches descriptives des fonctions API temps rel relatives la gestion
des horloges : des timers : RtGetClockTime RtGetClockResolution RtCreateTimer RtDeleteTimer RtCancelTimer RtEnablePortIo RtReadPort RtReadPortBuffer RtMapMemory RtSetClockTime RtGetClockTimerPeriod RtSetTimer RtSetTimerRelative RtDisablePortIo RtWritePort RtWritePortBuffer RtUnmapMemory
des entres/sorties :
Les fiches sont classes par ordre alphabtique des noms de fonction1 : RtCancelTimer RtCreateTimer RtDeleteTimer RtDisablePortIo RtEnablePortIo RtGetClockResolution RtGetClockTime RtGetClockTimerPeriod RtMapMemory RtReadPort RtReadPortBuffer RtSetClockTime RtSetTimer RtSetTimerRelative RtUnmapMemory RtWritePort RtWritePortBuffer
d d d d d d d d d d
La lettre d en face du nom de la fonction indique quil sagit dune fonction dterministe : le temps coul lors de lappel de la fonction est infrieur 5 microsecondes. Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
71
Annexe 3
La structure LARGE_INTEGER La structure LARGE_INTEGER est utilise pour reprsenter sur 64 bits une valeur entire signe.
typedef union _LARGE_INTEGER { struct { DWORD LowPart ; LONG HighPart ; } LONGLONG QuadPart ; } LARGE_INTEGER ;
// membre spcifiant les 32 bits de poids faible // membre spcifiant les 32 bits de poids fort // membre spcifiant un entier sign de 64 bits
La structure LARGE_INTEGER est en ralit une union. Si le compilateur est mme de supporter les entiers sur 64 bits (ce qui est le cas pour Visual Studio C++ 6.0), utilisez le membre QuadPart pour stocker lentier de 64 bits ! Autrement, utilisez les membres LowPart et HighPart ! Exemple :
LARGE_INTEGER periode ; periode.QuadPart = 100000 ;
72
Annexe 3
RtCancelTimer Timers
La fonction RtCancelTimer dsactive un timer RTX.
BOOL
RtCancelTimer (
HANDLE
hTimer, pTimeRemaining
// handle vers un timer RTX // NULL ou pointeur vers une structure LARGE_INTEGER
PLARGE_INTEGER
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. A propos des paramtres pTimeRemaining Si lutilisateur fournit un pointeur non NULL vers une structure LARGE_INTEGER, cette structure est utilise pour lui communiquer le temps qui restait scouler avant lexpiration du temporisateur. Commentaires RtCancelTimer dsactive le timer spcifi mais ne le supprime pas. Cest la fonction RtDeleteTimer qui permet de supprimer un timer RTX. Voir : RtCreateTimer RtSetTimer RtSetTimerRelative RtDeleteTimer
RtCreateTimer Timers
La fonction RtCreateTimer cre un timer RTX associ lhorloge indique, et retourne un handle vers ce timer.
HANDLE
RtCreateTimer (
pThreadAttributes,
// paramtre ignor
PSECURITY_ATTRIBUTES ULONG
StackSize,
// 0 (valeur par dfaut) ou nombre doctets allous la pile du thread // pointeur sur une squence de traitement
// NULL ou largument (cast as a PVOID) passer la squence // priorit du thread timer // identifiant de lhorloge (CLOCK_1, CLOCK_2 ou CLOCK_3)
ULONG CLOCK
); En cas de succs, la fonction retourne un handle vers le timer cr. En cas dchec, elle retourne un handle NULL. A propos des paramtres Routine La squence de traitement du timer est une fonction dont largument dentre est de type PVOID, et qui retourne VOID.
73
Annexe 3
Commentaires Pour initialiser le temporisateur, il faut utiliser RtSetTimer ou RtSetTimerRelative. A lexpiration du temporisateur, la squence de traitement indique lors de la cration du timer est excute avec largument Context. Pour excuter une squence de traitement diffrente ou la mme squence avec un paramtre Context diffrent, un nouveau timer doit tre cr. Voir : RtSetTimer RtSetTimerRelative RtDeleteTimer RtCancelTimer
Extrait de programme illustrant lappel de fonctions API relatives aux timers RTX #include <rtapi.h>
int main (int argc, char* argv[]) // Thread primaire dun processus Win32 RTX { HANDLE hTimer ; LARGE_INTEGER periode ; . hTimer = RtCreateTimer (NULL, 0, maSequenceTimer, NULL, RT_PRIORITY_MAX, CLOCK_3) ; periode.QuadPart = 100 000 ; // priode de 10 ms RtSetTimerRelative (hTimer, &periode, &periode) ; RtCancelTimer (hTimer, NULL) ; RtDeleteTimer (hTimer) ; return (0) ; } void RTFCNDCL maSequenceTimer (PVOID unused) { return ; }
RtDeleteTimer Timers
La fonction RtDeleteTimer supprime un timer RTX.
BOOL
RtDeleteTimer (
HANDLE
hTimer
); En cas de succs, la fonction retourne TRUE. Si largument spcifi nest pas valide, elle retourne FALSE.
74
Annexe 3
Commentaires Si le timer que lon veut supprimer est encore actif, on doit dabord le dsactiver en appelant la fonction RtCancelTimer ; on le supprime ensuite en appelant RtDeleteTimer. La fonction RtCloseHandle peut aussi tre utilise pour supprimer un timer RTX. Voir : RtCreateTimer RtSetTimer RtSetTimerRelative RtCancelTimer
RtDisablePortIo E/S
La fonction RtDisablePortIo dsactive laccs direct des ports dE/S.
BOOL
RtDisablePortIo (
PUCHAR ULONG
StartPort,
// adresse du premier port dE/S pour lequel est demande // la dsactivation de laccs direct // entier non sign sur 32 bits donnant le nombre dadresses // (octets) dsactiver partir de StartPort
nNumberOfBytes
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. A propos des paramtres StartPort et nNumberOfBytes Chaque adresse de lespace dE/S (I/O address space) pointe sur un simple octet. Pour les ports qui occupent des emplacements de 2 octets ou de 4 octets, on doit dsactiver laccs direct pour le nombre appropri dadresses de lespace dE/S (cest--dire 2 ou 4). Commentaires Cette fonction na aucun impact sur le dterminisme du sous-systme RTS. Dans lenvironnement RTSS, lappel de cette fonction est une NO-OP (no operation). Voir : RtEnablePortIo RtReadPort* RtWritePort* RtReadPortBuffer* RtWritePortBuffer*
RtEnablePortIo E/S
La fonction RtEnablePortIo active pour des ports dE/S laccs direct par le processus utilisateur.
BOOL
RtEnablePortIo (
PUCHAR ULONG
StartPort,
// adresse du premier port dE/S pour lequel est demande // la permission dun accs direct // entier non sign sur 32 bits donnant le nombre dadresses // (octets) activer partir de StartPort
nNumberOfBytes
);
Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
75
Annexe 3
En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. A propos des paramtres StartPort et nNumberOfBytes Chaque adresse de lespace dE/S (I/O address space) pointe sur un simple octet. Pour les ports qui occupent des emplacements de 2 octets ou de 4 octets, on doit activer laccs direct pour le nombre appropri dadresses de lespace dE/S (cest--dire 2 ou 4). Ladresse du port dE/S pour laquelle laccs direct est demand est passe dans StartPort sous la forme dun pointeur sur un caractre non sign (unsigned char *). Gnralement, cette adresse reprsente celle dun registre ou port dune carte lectronique dE/S. Si laccs un simple octet doit tre activ, nNumberOfBytes sera gal 1. Par contre, si dans lespace dE/S cet emplacement point par StartPort reprsente un mot de 2 octets ou un double mot de 4 octets, alors nNumberOfBytes doit indiquer, en nombre doctets, la largeur du port dE/S. Il est noter que lon peut galement utiliser nNumberOfBytes pour activer lautorisation daccs direct une gamme complte dadresses, indpendamment de la largeur de chacune des donnes. Commentaires RtEnablePortIo active laccs direct lintervalle indiqu dadresses dE/S. Sur les processeurs Pentium, il y a 65 535 adresses de port E/S dun octet. Les mots de 2 octets et les doubles mots de 4 octets occupent respectivement 2 et 4 adresses de port E/S. Cette fonction na aucun impact sur le dterminisme du sous-systme RTS. Dans lenvironnement RTSS, lappel de cette fonction est une NO-OP (no operation).
Voir : RtDisablePortIo
RtReadPort* RtWritePort*
RtReadPortBuffer* RtWritePortBuffer*
Exemple dutilisation de RtEnablePortIo #define CT_PORT ((unsigned char *) 0x340) #define CT_PORT_RANGE 4 if ( ! RtEnablePortIo (CT_PORT, CT_PORT_RANGE) { RtPrintf (Erreur RtEnablePortIo(0x%x, 0x%x) = %d\n, CT_PORT, CT_PORT_RANGE, GetLastError()) ; return 1 ; }
76
Annexe 3
RtGetClockResolution d Horloges
La fonction RtGetClockResolution permet dobtenir la rsolution dune horloge.
BOOL
RtGetClockResolution (
CLOCK
Clock, pResolution
// identifiant dune horloge (CLOCK_1, CLOCK_2 ou CLOCK_3) // pointeur sur une structure LARGE_INTEGER pour le // rangement du rsultat (donn en units de 100ns).
PLARGE_INTEGER
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. Voir : RtSetClockTime RtGetClockTime RtGetClockTimerPeriod
RtGetClockTime d Horloges
La fonction RtGetClockTime permet dobtenir la valeur courante dune horloge.
BOOL
RtGetClockTime (
CLOCK
Clock, pTime
// identifiant dune horloge (CLOCK_1, CLOCK_2 ou CLOCK_3) // pointeur sur une structure LARGE_INTEGER pour le // rangement du rsultat (donn en units de 100ns).
PLARGE_INTEGER
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. Voir : RtSetClockTime RtGetClockResolution RtGetClockTimerPeriod
RtGetClockTimerPeriod d Horloges
La fonction RtGetClockTimerPeriod permet dobtenir la priode timer minimale dune horloge.
BOOL
RtGetClockTimerPeriod (
CLOCK
Clock, ptime
// identifiant dune horloge (CLOCK_1, CLOCK_2 ou CLOCK_3) // pointeur sur une structure LARGE_INTEGER pour le // rangement du rsultat (donn en units de 100ns).
PLARGE_INTEGER
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE.
77
Annexe 3
Commentaires Pour lhorloge indique, la fonction RtGetClockTimerPeriod donne la priode timer minimale. Les timers qui utiliseraient lhorloge avec une dlai dexpiration infrieur cette valeur produiraient des rsultats imprvisibles. Voir : RtSetClockTime RtGetClockTime RtGetClockResolution
RtMapMemory E/S
La fonction RtMapMemory mappe une plage dadresses de mmoire physique dans lespace dadressage de mmoire virtuelle du processus utilisateur.
BOOL
RtMapMemory (
LARGE_INTEGER ULONG
physAddr,
// valeur de type LARGE_INTEGER indiquant la base de la plage // dadresses de mmoire physique mapper // entier non sign sur 32 bits donnant la longueur, en octets, de // la plage dadresses mapper // boolen indiquant si Windows doit ou non utiliser le cache avec // cette mmoire mappe
Length, CacheEnable
BOOLEAN
); En cas de succs, est retourne une adresse virtuelle de lespace dadressage du processus appelant. En cas dchec, une adresse virtuelle NULL est retourne par la fonction. Commentaires RtMapMemory cre une correspondance entre une plage dadresses virtuelles du processus utilisateur et une plage dadresses de mmoire physique ; elle donne ainsi la possibilit au processus utilisateur daccder directement des emplacements de mmoire physique du systme. Ceci est gnralement utilis pour accder des registres de priphrique ou des buffers mapps dans lespace dadressage physique de la machine. Voir : RtUnmapMemory
78
Annexe 3
A propos du paramtre PortAddress Cest ladresse du port dE/S ; celle-ci est passe sous la forme dun pointeur vers le type de donne lire, savoir un pointeur de type PUCHAR, PUSHORT ou PULONG. Voir : RtEnablePortIo RtDisablePortIo RtWritePort* RtReadPortBuffer* RtWritePortBuffer*
Exemple dutilisation de RtEnablePortIo et RtReadPortUchar #define CT_PORT ((unsigned char *) 0x340) #define CT_PORT_RANGE 4 unsigned char cX ; if ( ! RtEnablePortIo (CT_PORT, CT_PORT_RANGE) { RtPrintf (Erreur RtEnablePortIo(0x%x, 0x%x) = %d\n, CT_PORT, CT_PORT_RANGE, GetLastError()) ; return 1 ; } cX = RtReadPortUchar (CT_PORT) ; return 0 ;
E/S
Les fonctions RtReadPortBuffer* copient dans un tampon, directement depuis un port dE/S, une srie de donnes constitues chacune de un, deux ou quatre octets.
VOID VOID VOID
RtReadPortBufferUchar (PUCHAR PortAddress, PUCHAR pBuffer, ULONG nNumberOfBytes) ; RtReadPortBufferUshort (PUSHORT PortAddress, PUSHORT pBuffer, ULONG nNumberOfBytes) ; RtReadPortBufferUlong (PULONG PortAddress, PULONG pBuffer, ULONG nNumberOfBytes) ;
A propos des paramtres PortAddress Cest ladresse du port dE/S ; celle-ci est passe sous la forme dun pointeur vers le type de donne lire, savoir un pointeur de type PUCHAR, PUSHORT ou PULONG. pBuffer Cest un pointeur vers un tampon. nNumberOfBytes Cest un entier non sign sur 32 bits donnant le nombre total doctets lire. Voir : RtEnablePortIo RtDisablePortIo RtReadPort* RtWritePort* RtWritePortBuffer*
79
Annexe 3
RtSetClockTime d
La fonction RtSetClockTime initialise la valeur courante dune horloge.
BOOL
Horloges
RtSetClockTime (
CLOCK
Clock, pTime
// identifiant dune horloge (CLOCK_1, CLOCK_2 ou CLOCK_3) // pointeur vers une structure LARGE_INTEGER donnant, // en units de 100 ns, la nouvelle valeur de lhorloge
PLARGE_INTEGER
); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. Voir : RtGetClockTime RtGetClockResolution RtGetClockTimerPeriod
RtSetTimer d Timers
La fonction RtSetTimer initialise pour un timer RTX le temps absolu de sa premire expiration et lintervalle de rptition des expirations suivantes. Ce faisant, elle rend actif le timer.
BOOL
RtSetTimer (
HANDLE
hTimer,
pExpiration, // pointeur vers une structure LARGE_INTEGER // pointeur vers une structure LARGE_INTEGER PLARGE_INTEGER pInterval ); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. A propos des paramtres pExpiration Ce paramtre est un pointeur vers une structure LARGE_INTEGER qui indique, en units de 100ns, le temps absolu de la premire expiration du temporisateur. pInterval Ce paramtre est un pointeur vers une structure LARGE_INTEGER qui donne, en units de 100 ns, la valeur de lintervalle de temps qui spare les expirations suivantes du temporisateur. Si cette valeur est nulle ou si pInterval est gal NULL, alors le temporisateur nexpirera quune seule fois ; cest un one-shot timer . Lorsquune valeur non nulle est spcifie, celle-ci doit tre un multiple de la priode timer de lextension HAL (HAL extension timer period). Si ce nest pas le cas, RTX forcera la valeur de lintervalle de temps au multiple le plus proche de cette priode. Deux timers dont la valeur de lintervalle de temps est gale cette priode sont ncessairement en phase.
PLARGE_INTEGER
80
Annexe 3
Commentaires Avant de supprimer un timer qui a t initialis (activ) avec la fonction RtSetTimer ou RtSetTimerRelative, on doit dabord sassurer quil ne soit plus actif. A moins quil sagisse dun one-shot timer arriv expiration (le timer alors nest plus actif), on dsactive un timer laide de la fonction RtCancelTimer. Voir : RtCreateTimer RtSetTimerRelative RtCancelTimer RtDeleteTimer
RtSetTimerRelative d Timers
La fonction RtSetTimerRelative initialise pour un timer RTX le temps (par rapport la valeur courante de lhorloge) de sa premire expiration et lintervalle de rptition des expirations suivantes. Ce faisant, elle rend actif le timer.
BOOL
RtSetTimer (
HANDLE
hTimer,
pExpiration, // pointeur vers une structure LARGE_INTEGER // pointeur vers une structure LARGE_INTEGER PLARGE_INTEGER pInterval ); En cas de succs, la fonction retourne TRUE. Si les arguments spcifis ne sont pas valides, elle retourne FALSE. A propos des paramtres pExpiration Ce paramtre est un pointeur vers une structure LARGE_INTEGER qui indique, en units de 100ns, le temps de la premire expiration du temporisateur ; ce temps est exprim par rapport la valeur courante de lhorloge associe au timer lors de sa cration. pInterval Ce paramtre est un pointeur vers une structure LARGE_INTEGER qui donne, en units de 100 ns, la valeur de lintervalle de temps qui spare les expirations suivantes du temporisateur. Si cette valeur est nulle ou si pInterval est gal NULL, alors le temporisateur nexpirera quune seule fois ; cest un one-shot timer . Lorsquune valeur non nulle est spcifie, celle-ci doit tre un multiple de la priode timer de lextension HAL (HAL extension timer period). Si ce nest pas le cas, RTX forcera la valeur de lintervalle de temps au multiple le plus proche de cette priode. Deux timers dont la valeur de lintervalle de temps est gale cette priode sont ncessairement en phase. Commentaires Avant de supprimer un timer qui a t initialis (activ) avec la fonction RtSetTimer ou RtSetTimerRelative, on doit dabord sassurer quil ne soit plus actif. A moins quil sagisse dun one-shot timer arriv expiration (le timer alors nest plus actif), on dsactive un timer laide de la fonction RtCancelTimer. Voir : RtCreateTimer RtSetTimere RtCancelTimer RtDeleteTimer
PLARGE_INTEGER
81
Annexe 3
RtUnmapMemory E/S
La fonction RtUnmapMemory annule le mapping ralis la suite dun prcdent appel RtMapMemory.
BOOL
RtUnmapMemory (
PVOID
pVitualAddress
); En cas de succs, la fonction retourne TRUE. En cas dchec, elle retourne FALSE. Commentaires La valeur de ladresse virtuelle passe par le paramtre pvirtualAddress doit tre la mme que celle de ladresse de base retourne au processus utilisateur lors dun prcdent appel la fonction RtMapMemory. Voir : RtMapMemory
RtWritePortUchar (PUCHAR PortAddress, UCHAR pBuffer) ; RtWritePortUshort (PUSHORT PortAddress, SHORT pBuffer) ; RtWritePortUlong (PULONG PortAddress, ULONG pBuffer) ;
A propos des paramtres PortAddress Cest ladresse du port dE/S ; celle-ci est passe sous la forme dun pointeur vers le type de donne crire, savoir un pointeur de type PUCHAR, PUSHORT ou PULONG. pBuffer Cest la valeur sur un, deux ou quatre octets de la donne qui doit tre crite dans le port dE/S. Voir : RtEnablePortIo RtDisablePortIo RtReadPort* RtReadPortBuffer* RtWritePortBuffer*
82
Annexe 3
Exemple dutilisation de fonctions API de gestion du Port I/O #define CT_PORT ((unsigned char *) 0x340) #define CT_PORT_RANGE 4 unsigned char cX ; if ( ! RtEnablePortIo (CT_PORT, CT_PORT_RANGE) { RtPrintf (Erreur RtEnablePortIo(0x%x, 0x%x) = %d\n, CT_PORT, CT_PORT_RANGE, GetLastError()) ; return 1 ; } cX = RtReadPortUchar (CT_PORT) | 0x03 ; RtWritePortUchar (CT_PORT, cX) ; return 0 ;
RtWritePortBufferUchar (PUCHAR PortAddress, PUCHAR pBuffer, ULONG nNumberOfBytes) ; RtWritePortBufferUshort (PUSHORT PortAddress, PUSHORT pBuffer, ULONG nNumberOfBytes) ; RtWritePortBufferUlong (PULONG PortAddress, PULONG pBuffer, ULONG nNumberOfBytes) ;
A propos des paramtres PortAddress Cest ladresse du port dE/S ; celle-ci est passe sous la forme dun pointeur vers le type de donne crire, savoir un pointeur de type PUCHAR, PUSHORT ou PULONG. pBuffer Cest un pointeur vers un tampon. nNumberOfBytes Cest un entier non sign sur 32 bits donnant le nombre total doctets crire. Voir : RtEnablePortIo RtDisablePortIo RtReadPort* RtWritePort* RtReadPortBuffer*
*********
83
Annexe 4
Annexe 4
Canevas propos par lAppWizard RTX pour le programme dun processus RTSS
// for event server thread code HANDLE hEvent1 ; HANDLE hEvent2 ;
// RTX periodic timer code : // TO DO : Set default timer period to your desired time. // The period needs to be an even multiple of the HAL period found in the control panel. // This example uses a period of 500 micro seconds. liPeriod.QuadPart = 5000 ; // Create a periodic timer if (! (hTimer = RtCreateTimer ( NULL, // security 0, // stack size - 0 uses default TimerHandler, // timer handler NULL, // NULL context (argument to handler) RT_PRIORITY_MAX, // priority CLOCK_3) )) // RTX HAL timer { // TO DO: exception code here // RtPrintf ("RtCreateTimer error = %d\n", GetLastError()) ; ExitProcess(1) ; } if (! RtSetTimerRelative( hTimer, &liPeriod, &liPeriod) ) { // TO DO : exception code here // RtPrintf ("RtSetTimerRelative error = %d\n",GetLastError()) ; ExitProcess (1) ; } /
85
Annexe 4
/ // RTX interrupt handler code // RtAttachInterruptVector associates a handler routine with a hardware interrupt. // Note : level triggered interrupts are not supported in the Win32 environment hInterrupt = RtAttachInterruptVector ( NULL, // thread attributes 0, // stack size - 0 uses default InterruptHandler, // handler routine (void *) &nContext, // context 1, // priority Isa, // interface type 0, // bus number ISA_BUS_VECTOR, // bus interrupt level ISA_BUS_VECTOR ) ; // bus interrupt vector if (! hInterrupt) { // TO DO : exception code here // RtPrintf ("RtAttachInterruptVector error = %d\n", GetLastError()) ; ExitProcess(1) ; } // RTX port I/O code // Enable direct I/O access of CT ports from user context if (! RtEnablePortIo (CT_PORT_BASE, CT_PORT_RANGE) ) { // TO DO : your exception code here // RtPrintf ("RtEnablePortIo error = %d\n", GetLastError()) ; } // Use RTX port I/O functions to read and write to port. // See User's Guide chapter 3, "Using RTX Functionality" for description of functions. // Below is an example of a call to read/write to a port. RtPrintf ("Turning on the speaker for 3 seconds.\n") ; cX = RtReadPortUchar (CT_PORT_BASE) | 0x03 ; RtWritePortUchar (CT_PORT_BASE, cX) ; cX ^= 0x03 ; Sleep(3000) ; // A timer would be more precise. This is just a test. RtWritePortUchar(CT_PORT_BASE, cX) ; // RTX event server code // Create a named event // If an event already exists with this name, hEvent contains the handle to that event. // A call to GetLastError returns ERROR_ALREADY_EXISTS. // If this name is unique, a new event is created. // If this name is currently used for another object, the function fails. hEvent1 = RtCreateEvent ( NULL, TRUE, FALSE, "TestEvent1" ); // security attribute // manual reset // initial state // the event name /
86
Annexe 4
/ hEvent2 = RtCreateEvent( NULL, // security attribute TRUE, // manual reset FALSE, // initial state "TestEvent2" // the event name ); if (!hEvent1 || !hEvent2) { // RtPrintf ("RtCreateEvent error = %d\n", GetLastError()) ; // TO DO : your exception code here ExitProcess (1) ; } // Event code : set the priority of main thread highest if (RtSetThreadPriority (GetCurrentThread(), HIGHESTPRIORITY) == FALSE) { // RtPrintf ("RtSetThreadPriority error = %d\n",GetLastError()) ; // TO DO : your exception code here // ExitProcess(1) ; } // Event code : create a child thread high hThread_high = RtCreateThread(0, 0, ChildThread_high, NULL, CREATE_SUSPENDED, 0 ); if (hThread_high == NULL) { // RtPrintf ("RtCreateThread error = %d\n", GetLastError()) ; // TO DO : your exception code here // ExitProcess(1); } // Event code : set the priority of the child thread high if (RtSetThreadPriority(hThread_high, HIGHPRIORITY) == FALSE) { // RtPrintf ("RtSetThreadPriority error = %d\n", GetLastError()) ; // TO DO : your exception code here // ExitProcess (1) ; } // Event code : resume the child thread high dwSuspendCount = RtResumeThread(hThread_high) ; if (dwSuspendCount == 0xFFFFFFFF) { // RtPrintf ("RtResumeThread error = %d\n", GetLastError()) ; // TO DO : your exception code here // ExitProcess (1) ; } / Pierre BLANDIN, Laboratoire dAutomatique, CNAM Paris
87
Annexe 4
/ RtSetEvent (hEvent1) ; RtWaitForSingleObject (hEvent2, INFINITE) ; RtPrintf ("Main() received Event2\n") ; // TO DO : your program code here // NOTE : At some point in this section, the code must have // a call to RtSetEvent (hEvent) to signal the server to run for a cycle. ExitProcess (0) ; }
// RTX periodic timer handler function // Refer to the RTX Samples directory for examples of periodic timers void RTFCNDCL TimerHandler (PVOID context) { // TO DO : your timer handler code here }
// RTX interrupt handler function // Refer to the RTX Samples directory for examples of interrupt handlers void RTFCNDCL InterruptHandler (void * nContext) { // TO DO : your interrupt handler code here }
// RTX event server child thread // Refer to the RTX Samples directory for examples using events ULONG RTFCNDCL ChildThread_high (void * nContext) { DWORD dwEventReturn ; // wait for single event dwEventReturn = RtWaitForSingleObject( hEvent1, // the handle of object to wait for INFINITE // timeout ); RtPrintf("ChildThread_high Received Event1\n") ; RtSetEvent(hEvent2) ; return (0) ; }
*********
88