Toute la vérité sur RTOS. Article # 11. Tâches: configuration et introduction à l'API



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 contexte
Article # 9. Scheduler: implémentation
Article # 8. Nucleus SE: conception interne et déploiement
Article # 7. Nucleus SE: Introduction
Article # 6. Autres services RTOS
Article # 5. Interaction et synchronisation des tâches
Article # 4. Tâches, changement de contexte et interruptions
Article # 3. Tâches et planification
Article # 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 fonctionnelleNucleus RTOSNucleus SE
Suspendre une tâcheNU_Suspend_Task ()NUSE_Task_Suspend ()
Reprendre la tâcheNU_Resume_Task ()NUSE_Task_Resume ()
Suspendre une tâche pour un
la période
NU_Sleep ()NUSE_Task_Sleep ()
Version de contrôle du processeurNU_Relinquish ()NUSE_Task_Relinquish ()
Obtention de l'ID de la tâche en coursNU_Current_Task_Pointer ()NUSE_Task_Current ()
Vérification de la taille de pile disponibleNU_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écifiqueNU_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'applicationNU_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'extrusionNU_Change_Preemption ()Non implémenté.
Modifier la priorité des tâchesNU_Change_Priority ()Non implémenté.
Modifier le quantum temporel d'une tâcheNU_Change_Time_Slice ()Non implémenté.
Achèvement de la tâcheNU_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 RTOS
Prototype 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 SE
Cet 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 SE
La 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 RTOS
Prototype 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 SE
Cet 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 SE
La 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 RTOS
Prototype 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 SE
Cet 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 SE
La 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 RTOS
Cet 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 SE
Cet 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 SE
La 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.

Source: https://habr.com/ru/post/fr424481/


All Articles