Gestion des taches

    Une tache est soit une fonction qui contient une boucle infinie, soit une fonction qui se supprime elle-meme quand elle s'est exécutée. Il faut noter que quand une tache est supprimée, en fait le code n'est pas supprimé mais le scheduler ne tient plus compte de cette tache (état DORMANT). Une tache ressemble à une fonction C avec une type de retour et des arguments mais elle ne renvoie jamais son type de retour. Le type de retour est toujour déclaré "void".

    Nous allons voir comment créer, initialiser, supprimer et modifier la priorité d'une tache.

NOTE : Il faut décider si on fixe ou pas le nombre maximum de tache. Si on le fixe, ce sera plus simple pour déterminé la tache de plus haute priorité rapidement mais un peu moins flexible. Si on le laisse varié au gré de l'utilisateur, on complexifie grandement la détermination de la tache de plus haute priorité. Il me semble que 64 taches, c'est déjà pas mal pour des applications temps-réel. Car il faut toujours essayé de faire le code le plus concis et simple possible pour avoir un OS robuste.

    1 Création de tache.

        Avant de pouvoir utiliser une tache, il faut la créer. Pour créer une tache, il faut passer son adresse et des arguments à la fonction createTask(). Une tache peut être crées avant le le démarrage du mutlitache ou par une autre tache. Il faut évidemment crée au moins une tache avant de démarrer le multitache. La fonction createTask permet donc de créer une tache, elle doit avoir le prototype suivant :

    createTask(void (*task)(void *pd), void *data, STK *stack, INT8U prio) :
        Argument :
        - task : le pointeur vers le code de la tache
        - data : le pointeur vers des données que l'on passe à la tache quand elle commence son exécution.
        - stack : un pointeur vers la pile de la tache.
        - prio : la priorité désirée de la tache

    La fonction createTask commence par vérifier que la priorité désirée est valide,cad qu'elle est comprise dans l'intervalle [0, LOWEST_PRIO]. Ensuite, il faut vérifier que la priorité désirée n'est pas déjà prise par une autre tache, car les priorités sont uniques et donc 2 taches ne peuvent avoir la meme priorité. Si la priorité est libre, on la réserve et on peut reenclencher les interruptions, car le remplissage du TCB ne néccésite pas un blocage des interruptions.

NOTE: Il est fort utile d'avoir une priorité différente pour chaque tache, car une caractéristique essentiel des OS temps réel est qu'ils ont un comportement déterministe. Donc on doit pouvoir prédire le comportement qu'ils aurront dans n'importe qu'elle situation. En attribuant des priorités différentes, a tout moment, il n'y a qu'une seule tache qui possede la plus haute priorité. Donc le scheduler n'a pas de choix à faire, il prend cette tache de plus haute priorité.

    Ensuite, il faut initialiser la pile de la tache, pour cela on va appelé une fonction stackInit(). Cette fonction est spécifique au processeur et initialise la pile de la tache pour qu'elle ressemble à la pile après une interruption et tout les registres sont sauvés.
 
 
 

Il faut placer l'adresse de retour de la fonction, placer les arguments sur le pile. Simuler la valeur de la pile suite à une interruption et placer les registres sur la pile.