next up previous contents
suivant: Conclusion monter: Développement d'un système d'exploitation précédent: Intégration et utilisation sur   Table des matières

Sous-sections

Exemples d'applications

Nous allons présenter deux exemples simples de programmes qui fonctionnent sous Expresso. Ces exemples permettent de voir comment utiliser quelques services et comment développer des applications sous Expresso.

Exclusion mutuelle

Pour commencer, nous avons fait un programme très simple qui implémente le problème de l'exclusion mutuelle. Nous avons deux tâches qui doivent exécuter une section critique mais les deux tâches ne peuvent jamais se trouver en même temps dans leur section critique respective.

La fonction main() crée un tâche principale taskStart dont la priorité est TASKS_START_PRIO = 12 et la pile est taskStartStack grâce à la fonction createTask() puis appelle la fonction startScheduler.

\fbox{\begin{minipage}{12cm}
\begin{footnotesize}
\texttt{if ((err = createTask(...
...ask start'',err);\\
\}\\
startScheduler();
}
\end{footnotesize}\end{minipage}}













La tâche principale peut ensuite créer un sémaphore semId puis deux tâches task1 et task2 de priorité TASK1_PRIO = 11 et TASK2_PRIO = 10. Donc la tâche deux est la tâche la plus prioritaire du système. Ensuite la tâche principale rentre dans une boucle infinie.

\fbox{\begin{minipage}{15cm}
\begin{footnotesize}
\texttt{semId = semCreate(1,\&...
...sk2 created \textbackslash n'');\\
for(;;);
}
\end{footnotesize}\end{minipage}}













Les deux tâches task1 et task2 ont la même structure, elles sont composées d'une boucle infinie qui se compose des opérations suivantes :

Regardons le code de la tâche 1 par exemple, la tâche 2 fait exactement la même chose mais est plus prioritaire.

\fbox{\begin{minipage}{10cm}
\begin{footnotesize}
\texttt{for(;;) \{\\
\hspace*...
...} delayTask(100);\\
\hspace*{0,5cm}\}\\
\}
}
\end{footnotesize}\end{minipage}}













Nous avons utilisé le fichier de configuration suivant pour minimiser la taille du système:

\fbox{\begin{minipage}{4,5cm}
\begin{footnotesize}
\texttt{\char93 define MAX\_T...
...PRIO\_EN 0\\
\char93 define TASK\_DEL\_EN 0
}
\end{footnotesize}\end{minipage}}













Voici ce que nous obtenons par le port série du Xcopilot, on peut constater que les deux tâches ne sont jamais ensemble dans leur section critique. On peut aussi constater que la deuxième tâche est plus prioritaire car dès qu'elle sort de sa section critique, elle est toujours la plus prioritaire et la tâche 1 ne sera exécutée que lorsque la tâche 2 sera temporisée (dans notre cas).

\fbox{\begin{minipage}{10cm}
\begin{footnotesize}
\texttt{ABCDE\\
Expresso : re...
...cal section\\
Task 1 BEGIN Critical section
}
\end{footnotesize}\end{minipage}}













Une version graphique est aussi disponible ou l'on voit l'exécution des différentes tâches dans deux barres de progression, ce qui permet de visualiser le problème sur l'écran du Palm.

Producteur et consommateur

Nous avons crée un exemple du problème du producteur/consommateur grâce à une file de messages. La tâche 1 envoie des messages dans une file, la tâche 2 les récupère et effectue un calcul sur le résultat. Plus précisément, la tâche 1 envoie 50 nombres entre 0 et 100 qui sont contenu dans un tableau mais qui pourraient provenir de capteur par exemple. La tâche 2 récupère ses nombres, elle retient la somme ainsi que le nombre qu'elle en a recu et calcule la moyenne arithmétique de la suite de nombre déjà recu. Dès que la tâche 1 a envoyé ses 50 nombres, elle se supprime grâce à la fonction deleteTask. Quand la tâche 1 n'envoie plus de messages, la tâche 2 reste bloquée sur la file mais nous avons placé un timeout de 500 ticks d'horloge. Après 3 timeouts successifs, la tâche 2 se supprime aussi.

La fonction main() est exactement la même que celle du premier exemple. La fonction TaskStart() ne diffère que par la création d'une file de message au lieu d'un sémaphore.

\fbox{\begin{minipage}{12cm}
\begin{footnotesize}
\texttt{queueId = queueCreate(...
...art()'',''ERROR queue creation'',err);\\
\}
}
\end{footnotesize}\end{minipage}}













La variable queue est définie comme un tableau de pointeur void et la taille SIZE_QUEUE de la queue est de 100.

La tâche 1 envoie simplement les nombres les uns après les autres avec la fonction queueSend

\fbox{\begin{minipage}{12,5cm}
\begin{footnotesize}
\texttt{void task1(void *dat...
...space*{0,5cm} deleteTask(TASK1\_PRIO);\\
\}
}
\end{footnotesize}\end{minipage}}













La tâche 2 récupère les messages avec la fonction queueWait() mais avec un timeout de 500 ticks d'horloge. Après trois timeout successifs, on arrête d'attendre des messages.

\fbox{\begin{minipage}{12,5cm}
\begin{footnotesize}
\texttt{void task2(void *dat...
...space*{0,5cm} deleteTask(TASK2\_PRIO);\\
\}
}
\end{footnotesize}\end{minipage}}













Ce petit exemple permet de calculer la moyenne arithmétique des nombres du tableau de la tâche 1. Voici ce que nous obtenons par le port série du Xcopilot, on peut remarquer que la moyenne se stabilise au fur et à mesure que les nombres sont envoyés dans la file.

\fbox{\begin{minipage}{11,5cm}
\begin{footnotesize}
\texttt{ABCDE\\
Expresso : ...
... itself\\
\hspace*{5cm} Task2 delete itself
}
\end{footnotesize}\end{minipage}}














next up previous contents
suivant: Conclusion monter: Développement d'un système d'exploitation précédent: Intégration et utilisation sur   Table des matières
Fabian Skivee 2002-06-04