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.
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.
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.
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.
Nous avons utilisé le fichier de configuration suivant pour minimiser la taille du système:
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).
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.
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.
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
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.
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.