
Le concept de problème a été présenté dans les articles précédents. En substance, une tâche est simplement un ensemble de valeurs qui peuvent être chargées dans les registres du processeur (pour la tâche en cours d'exécution) ou peuvent être stockées dans un état prêt pour une commutation contextuelle vers une tâche à l'avenir. Le plus souvent, une tâche a sa propre pile.
Bien sûr, lorsque vous utilisez le planificateur Run to Completion (RTC), le changement de contexte n'est pas utilisé et la tâche peut être considérée uniquement comme la valeur du compteur de programme (point d'entrée de code).
La définition de la tâche n'inclut pas le code lui-même. La tâche doit exécuter le code, mais il ne lui appartient pas. Les tâches peuvent avoir des fonctions communes. De plus, tout le code de plusieurs tâches peut être partagé. Le code général devrait presque toujours être écrit en fonction des exigences réentrantes. La plupart des compilateurs peuvent facilement gérer ce code, mais il faut faire attention aux fonctions de bibliothèque, car elles peuvent ne pas convenir aux applications multitâches.
Une telle définition dicte certaines règles qui doivent être suivies lors du développement des structures de données des tâches et des fonctions API décrites dans cet article. Je passerai en revue la configuration des tâches dans Nucleus SE et commencerai un aperçu détaillé des appels de service (appels API) qui s'appliquent aux tâches dans Nucleus SE et Nucleus RTOS.
Articles précédents de la série:
Article # 10. Scheduler: fonctionnalités avancées et préservation du contexteArticle # 9. Scheduler: implémentationArticle # 8. Nucleus SE: conception interne et déploiementArticle # 7. Nucleus SE: IntroductionArticle # 6. Autres services RTOSArticle # 5. Interaction et synchronisation des tâchesArticle # 4. Tâches, changement de contexte et interruptionsArticle # 3. Tâches et planificationArticle # 2. RTOS: Structure et mode temps réel
Article # 1. RTOS: introduction.
Configuration des tâches
Nombre de tâches
Dans Nucleus SE, la configuration des tâches est principalement pilotée par les directives
#define dans
nuse_config.h . Le paramètre clé
NUSE_TASK_NUMBER détermine le nombre de tâches pouvant être configurées dans l'application. La valeur par défaut est 1 (c'est-à-dire une tâche pendant l'exécution) et la valeur maximale du paramètre est 16. Une valeur incorrecte entraînera une erreur de compilation, qui sera générée en
archivant nuse_config_chech.h (elle est incluse dans
nuse_config.c , ce qui signifie compilé avec ce module), la directive
#error se
déclenchera . Ce paramètre est utilisé pour déterminer les structures de données; leur taille dépend de sa valeur.
Dans Nucleus SE, sauf lors de l'utilisation du planificateur RTC, il est essentiel qu'au moins une tâche soit toujours prête à être exécutée. Lorsque vous utilisez le planificateur de priorité, vous devez vous assurer que la tâche avec la priorité la plus basse ne sera jamais suspendue, une telle tâche doit être considérée comme une "tâche d'arrière-plan".
Contrairement à certains autres cœurs en temps réel, Nucleus SE n'utilise pas de «tâches système», ce qui signifie que les 16 tâches sont disponibles pour le code d'application utilisateur ou le middleware.
Paramètres API
Chaque fonction API (appel d'utilitaire) dans Nucleus SE est activée par la directive
#define dans
nuse_config.h . Pour les tâches, ces paramètres sont:
- NUSE_TASK_SUSPEND
- NUSE_TASK_RESUME
- NUSE_TASK_SLEEP
- NUSE_TASK_RELINQUISH
- NUSE_TASK_CURRENT
- NUSE_TASK_CHECK_STACK
- NUSE_TASK_RESET
- NUSE_TASK_INFORMATION
- NUSE_TASK_COUNT
Par défaut, tous les paramètres ci-dessus sont définis sur
FALSE , désactivant ainsi chaque appel de service et empêchant l'inclusion de tout code qui les implémente. Pour configurer les tâches de l'application, vous devez sélectionner les appels d'API nécessaires et définir les caractères correspondants sur
TRUE .
Voici un
extrait du fichier
nuse_config.h par défaut.

Si votre code utilise un appel d'API qui n'a pas été activé, une erreur apparaîtra lors de la liaison car le code d'implémentation n'était pas inclus dans l'application.
Paramètres fonctionnels
Nucleus SE peut ajouter des fonctionnalités de tâche. Et encore une fois, les paramètres nécessaires sont dans le fichier
nuse_config.h :
NUSE_SUSPEND_ENABLE vous permet de suspendre des tâches. Si cette option n'est pas sélectionnée, toutes les tâches attendent constamment la planification. L'activation de ce paramètre est requise lors de l'utilisation du planificateur de priorité.
NUSE_BLOCKING_ENABLE vous permet de suspendre des tâches à plusieurs appels d'API de fonction. Si cette option est activée,
NUSE_SUSPEND_ENABLE doit également être activé.
NUSE_INITIAL_TASK_STATE_SUPPORT vous permet de définir l'état initial de la tâche. Si cette option n'est pas sélectionnée, toutes les tâches seront ajoutées au planificateur immédiatement après la création.
Appels de tâches utilitaires
Nucleus RTOS prend en charge 16 appels de service (API) pour travailler avec des tâches qui offrent les fonctionnalités suivantes:
Description fonctionnelle | Nucleus RTOS | Nucleus SE |
---|
Suspendre une tâche | NU_Suspend_Task () | NUSE_Task_Suspend () |
Reprendre la tâche | NU_Resume_Task () | NUSE_Task_Resume () |
Suspendre une tâche pour un la période | NU_Sleep () | NUSE_Task_Sleep () |
Version de contrôle du processeur | NU_Relinquish () | NUSE_Task_Relinquish () |
Obtention de l'ID de la tâche en cours | NU_Current_Task_Pointer () | NUSE_Task_Current () |
Vérification de la taille de pile disponible | NU_Check_Stack () | NUSE_Task_Check_Stack () |
Rendre la tâche inutilisée état (réinitialisation) | NU_Reset_Task () | NUSE_Task_Reset () |
Fournir des informations sur une tâche spécifique | NU_Task_Information () | NUSE_Task_Information () |
Obtenir un compteur configuré tâches (en ce moment) dans l'application | NU_Established_Tasks () | NUSE_Task_Count () |
Ajout d'une nouvelle tâche à l'application (création) | NU_Create_Task () | Non implémenté. |
Suppression d'une tâche de l'application | NU_Delete_Task () | Non implémenté. |
Retourner des pointeurs vers toutes les tâches dans l'appli | NU_Task_Pointers () | Non implémenté. |
Changer l'algorithme d'extrusion | NU_Change_Preemption () | Non implémenté. |
Modifier la priorité des tâches | NU_Change_Priority () | Non implémenté. |
Modifier le quantum temporel d'une tâche | NU_Change_Time_Slice () | Non implémenté. |
Achèvement de la tâche | NU_Terminate_Task () | Non implémenté. |
La mise en œuvre de chacun des appels de service ci-dessus est discutée en détail ci-dessous, ainsi que dans les articles suivants sur RTOS.
Services de gestion des tâches
Opérations de base avec des tâches: suspendre une tâche pour une durée indéterminée, reprendre, suspendre une tâche pour une durée spécifique, libérer le processeur. Nucleus RTOS et Nucleus SE fournissent quatre appels d'API de base pour effectuer ces opérations, que je décrirai ci-dessous.
Suspendre une tâche
Nucleus PLUS fournit un appel API simple qui vous permet de suspendre une tâche spécifique indéfiniment. Nucleus SE a un appel de bureau avec des fonctionnalités similaires.
Suspendre une tâche dans Nucleus RTOSPrototype d'appel de service:
STATUS NU_Suspend_Task (tâche NU_TASK *);Paramètres:
task - un pointeur vers l'unité de contrôle de la tâche suspendue (qui peut être courante et son ID peut être obtenu en utilisant
NU_Current_Task_Pointer () , plus dans l'article suivant).
Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TASK - pointeur non valide vers la tâche;
NU_INVALID_SUSPEND - La tâche spécifiée a le statut
NU_FINISHED ou
NU_TERMINATED .
Pause de défi dans Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus PLUS.
Prototype d'appel de service:
STATUS NUSE_Task_Suspend (tâche NUSE_TASK);Paramètres:
task - l'index (ID) de la tâche suspendue (qui peut être en cours, et son ID peut être obtenu en utilisant
NUSE_Task_Current () - plus dans le prochain article).
Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TASK - index de tâche non valide.
Mettre en œuvre la suspension d'une tâche dans Nucleus SELa fonctionnalité principale de la fonction API est assez simple:

En fait, dans cette implémentation, la fonction de planificateur
NUSE_Suspend_Task () est appelée avec le paramètre «arrêt inconditionnel» (
NUSE_PURE_SUSPEND ). Cette fonction appelle le planificateur si la tâche suspendue est en cours.
Reprendre la tâche
Nucleus RTOS fournit un simple appel d'API qui vous permet de reprendre une tâche qui était précédemment suspendue indéfiniment. Nucleus SE a un appel de bureau avec des fonctionnalités similaires.
Tâche de reprise de défi dans Nucleus RTOSPrototype d'appel de service:
STATUS NU_Resume_Task (tâche NU_TASK *);Paramètres:
tâche - un pointeur vers l'unité de contrôle de la tâche renouvelée.
Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TASK - pointeur non valide vers la tâche;
NUSE_INVALID_RESUME - La tâche n'a pas été suspendue sans condition.
Tâches de reprise du défi dans Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus RTOS.
Prototype d'appel de service:
STATUS NUSE_Task_Resume (tâche NUSE_TASK);Paramètres:
task - index (ID) de la tâche renouvelée.
Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TASK - index de tâche non valide;
NUSE_INVALID_RESUME - La tâche n'a pas été suspendue sans condition.
Implémentation de tâches de reprise dans Nucleus SELa fonctionnalité principale de la fonction API est assez simple:

En fait, la fonction de planificateur
NUSE_Wake_Task () est appelée dans cette implémentation. Cette fonction appelle le planificateur si le planificateur prioritaire est utilisé et que la tâche renouvelée a une priorité plus élevée que la tâche actuelle.
Suspension d'une tâche pendant une période de temps spécifique
Nucleus RTOS fournit un appel API simple pour suspendre la tâche en cours pendant une période de temps spécifique. Nucleus SE a un appel de bureau avec des fonctionnalités similaires.
Appelez les tâches de suspension pendant une période spécifique Nucleus RTOSPrototype d'appel de service:
VOID NU_Sleep (ticks NON SIGNES);Paramètres:
ticks - période pendant laquelle la tâche doit être suspendue (en
ticks d' horloge en temps réel).
Valeur de retour:
Non.
Défiez une pause de tâche pour une période spécifique Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus RTOS.
Prototype d'appel de service:
void NUSE_Task_Sleep (U16 ticks);Paramètres:
ticks - période pendant laquelle la tâche doit être suspendue (en
ticks d' horloge en temps réel).
Valeur de retour:
Non.
Implémentation d'une suspension d'une tâche pour une période de temps spécifique dans Nucleus SELa fonctionnalité principale de la fonction API est assez simple:

Ce code charge la valeur de retard dans le paramètre de tâche actuel dans
NUSE_Task_Timeout_Counter [] . Après cela, la tâche est interrompue à l'aide de
NUSE_Suspend_Task () avec la période de suspension (
NUSE_SLEEP_SUSPEND ).
La valeur de délai d'attente est utilisée par le gestionnaire d'interruption d'horloge en temps réel. Le code est illustré ci-dessous et sera discuté plus en détail dans un prochain article.

Version du processeur
Nucleus PLUS fournit un simple appel d'API pour permettre le transfert du contrôle du processeur à l'une des tâches prêtes à exécuter avec la même priorité basée sur l'algorithme Round Robin. Nucleus SE a un appel de bureau avec des fonctionnalités très similaires. Cependant, il ne peut pas être utilisé avec le planificateur de priorités, car plusieurs tâches avec la même priorité ne sont pas prises en charge. Toute tentative d'utilisation de cet appel d'API avec le planificateur de priorité entraînera une erreur. Un appel utilitaire fonctionne avec les planificateurs Round Robin et Time Slice; avec le planificateur Run To Completion, cet appel API est inefficace.
Appel de libération du processeur Nucleus RTOSCet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus PLUS.
Prototype d'appel de service:
VOID NU_Relinquish (VOID);Paramètres:
Sont absents.
Valeur de retour:
Non.
Appel de libération du processeur Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus PLUS.
Prototype d'appel de service:
void NUSE_Task_Relinquish (void);Paramètres:
Sont absents.
Valeur de retour:
Non.
Implémentation de la version du processeur Nucleus SELa fonctionnalité principale de la fonction API:

Essentiellement, cette implémentation appelle la fonction de planificateur
NUSE_Reschedule () . Cette fonction indique simplement au planificateur de terminer la tâche suivante.
Les deux prochains articles continueront de passer en revue les appels d'utilitaires RTOS liés aux tâches à l'aide des exemples Nucleus RTOS et Nucleus SE.
À propos de l'auteur: Colin Walls travaille dans l'industrie électronique depuis plus de trente ans, consacrant la majeure partie de son temps au micrologiciel. Il est maintenant ingénieur firmware chez Mentor Embedded (une division de Mentor Graphics). Colin Walls intervient souvent lors de conférences et séminaires, auteur de nombreux articles techniques et de deux livres sur le firmware. Vit au Royaume-Uni.
Blog professionnel
de Colin , e-mail: colin_walls@mentor.com.
À propos de la traduction: cette série d'articles semblait intéressante en ce que, malgré les approches décrites obsolètes à certains endroits, l'auteur présente au lecteur mal formé les caractéristiques du système d'exploitation en temps réel. J'appartiens moi-même à l'équipe de créateurs du
RTOS russe , que nous avons l'
intention de rendre gratuit , et j'espère que le cycle sera utile aux développeurs novices.