Toute la vérité sur RTOS. Article # 28. Minuteries logicielles

L'idée des minuteries logicielles a été présentée dans un article précédent . Ce sont des objets du noyau qui fournissent des tâches avec un moyen simple de déclencher des événements à temps, ou, le plus souvent, un moyen d'effectuer des actions sur une base régulière. Tous les détails de la fonctionnalité liée au temps (précision, gestion des interruptions, etc.) dans Nucleus SE ont été discutés dans un article précédent .



Articles précédents de la série:
Article # 27. Heure système
Article # 26. Canaux: services auxiliaires et structures de données
Article # 25. Canaux de données: introduction et services de base
Article # 24. Files d'attente: services auxiliaires et structures de données
Article # 23. Files d'attente: introduction et services de base
Article # 22. Boîtes aux lettres: services auxiliaires et structures de données
Article # 21. Boîtes aux lettres: introduction et services de base
Article # 20. Sémaphores: services auxiliaires et structures de données
Article # 19. Sémaphores: introduction et services de base
Article # 18. Groupes d'indicateurs d'événements: services d'assistance et structures de données
Article # 17. Groupes de drapeaux d'événements: introduction et services de base
Article # 16. Signaux
Article # 15. Partitions de mémoire: services et structures de données
Article # 14. Sections de mémoire: introduction et services de base
Article # 13. Structures de données de tâche et appels d'API non pris en charge
Article # 12. Services pour travailler avec des tâches
Article # 11. Tâches: configuration et introduction à l'API
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.

Utilisation de minuteries


Les temporisateurs de programme peuvent être configurés pour se déclencher une fois, c'est-à-dire qu'ils démarrent, puis, après une période de temps spécifiée, mettent simplement fin au cycle. Ou la minuterie peut être configurée pour redémarrer: une fois le décompte terminé, la minuterie redémarre automatiquement. La durée de fonctionnement après un redémarrage peut différer de la durée de fonctionnement initiale. De plus, la minuterie peut éventuellement être configurée pour exécuter une fonction de terminaison spéciale, qui est exécutée lorsque (ou chaque fois) la minuterie termine le cycle de travail.

Paramètres de la minuterie


Nombre de minuteries


Comme pour la plupart des aspects de Nucleus SE, les paramètres du minuteur sont contrôlés par les directives #define dans nuse_config.h . Le paramètre principal est NUSE_TIMER_NUMBER , qui définit les temporisateurs configurés dans l'application. Par défaut, cette valeur est zéro (c'est-à-dire que les minuteries ne sont pas utilisées dans l'application) et peut prendre des valeurs jusqu'à 16. Une valeur incorrecte entraînera une erreur de compilation, qui sera générée en archivant le fichier nuse_config_check.h (ce fichier est inclus dans nuse_config.c et compile avec elle), ce qui déclenchera la directive #error .

La sélection d'une valeur différente de zéro est l'activateur principal du minuteur. Ce paramètre est utilisé lors de la définition des structures de données et leur taille dépend de sa valeur. De plus, une valeur différente de zéro active les paramètres de l'API.

Activation de la fonction d'achèvement


Dans Nucleus SE, j'ai essayé de trouver l'opportunité de rendre la fonctionnalité facultative, où cela économisera de la mémoire. Un bon exemple est la prise en charge des fonctions de fin de temporisation. Outre le fait que cette fonctionnalité est facultative pour chaque temporisateur, le mécanisme peut être activé (ou non) pour l'ensemble de l'application à l'aide du paramètre NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT dans nuse_config.h . La définition de ce paramètre sur FALSE bloque la définition de deux structures de données dans la ROM, qui seront décrites en détail dans cet article.

Activation de l'API


Chaque fonction API (appel d'utilitaire) dans Nucleus SE a la directive d'activation #define dans nuse_config.h. Pour les minuteries, ces symboles incluent:
NUSE_TIMER_CONTROL
NUSE_TIMER_GET_REMAINING
NUSE_TIMER_RESET
NUSE_TIMER_INFORMATION
NUSE_TIMER_COUNT

Par défaut, tous les activateurs sont définis sur FALSE , donc tous les appels de service sont désactivés, bloquant l'inclusion de code qui les implémente. Pour configurer des minuteurs dans l'application, vous devez sélectionner les appels de service API nécessaires et les définir sur VRAI .

Voici un extrait de code du fichier nuse_config.h par défaut.

#define NUSE_TIMER_NUMBER 0/*      0-16 */ /*    */ #define NUSE_TIMER_CONTROL FALSE #define NUSE_TIMER_GET_REMAINING FALSE #define NUSE_TIMER_RESET FALSE #define NUSE_TIMER_INFORMATION FALSE #define NUSE_TIMER_COUNT FALSE 

Si la fonction API liée à la minuterie est activée et qu'il n'y a pas de temporisation configurée dans l'application (à l'exception de la fonction NUSE_Timer_Count () , qui est toujours activée), une erreur de compilation se produit. Si votre code utilise un appel d'API qui n'a pas été activé, une erreur de mise en page se produira car le code d'implémentation n'était pas inclus dans l'application.

Appels de service de minuterie


Nucleus RTOS prend en charge huit appels d'utilitaire liés à la minuterie qui offrent les fonctionnalités suivantes:

  • Minuterie de gestion (démarrage / arrêt). Nucleus SE est implémenté dans la fonction NUSE_Timer_Control () .
  • Récupération du temps restant du minuteur. Dans Nucleus SE, implémenté dans NUSE_Timer_Get_Remaining () .
  • Restauration de la minuterie à son état d'origine (réinitialisation). Nucleus SE implémenté dans NUSE_Timer_Reset () .
  • Fournir des informations sur une minuterie spécifique. Nucleus SE est implémenté dans NUSE_Timer_Information () .
  • Renvoie le nombre de temporisations configurées (actuellement) dans l'application. Nucleus SE est implémenté dans NUSE_Timer_Count () .
  • Ajout d'un nouveau timer à l'application (création). Nucleus SE n'est pas implémenté.
  • Suppression d'une minuterie de l'application. Nucleus SE n'est pas implémenté.
  • Renvoyer des pointeurs à tous les temporisateurs de l'application. Nucleus SE n'est pas implémenté.

La mise en œuvre de chaque appel de service sera discutée en détail ci-dessous.

Services de minuterie


Les opérations fondamentales qui peuvent être effectuées avec une minuterie sont le contrôle (démarrage et arrêt) et la lecture de la valeur actuelle. Nucleus RTOS et Nucleus SE fournissent deux appels d'utilitaire API de base pour ces opérations.

Contrôle de la minuterie


Un appel utilitaire à l'API Nucleus RTOS pour contrôler la minuterie vous permet d'activer et de désactiver la minuterie (démarrage et arrêt). Nucleus SE offre des fonctionnalités similaires.

Timer Control Challenge dans Nucleus RTOS
Prototype d'appel de service:

STATUS NU_Control_Timer (minuterie NU_TIMER *, validation OPTION);

Paramètres:
minuterie - pointeur vers le bloc de commande de minuterie fourni par l'utilisateur;
enable est la fonction requise; elle peut prendre les valeurs NU_ENABLE_TIMER ou NU_DISABLE_TIMER .

Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INAVLID_TIMER - pointeur de temporisateur invalide;
NU_INAVLID_ENABLE - fonction non valide.

Timer Control Challenge dans Nucleus SE
Cet appel d'API prend en charge toutes les fonctionnalités de l'API RTOS Nucleus.

Prototype d'appel de service:
STATUS NUSE_Timer_Control (temporisateur NUSE_TIMER, activation OPTION);

Paramètres:
timer - index (ID) du timer utilisé;
enable est la fonction requise; elle peut prendre les valeurs NUSE_ENABLE_TIMER ou NUSE_DISABLE_TIMER .

Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INCALID_TIMER - index de temporisateur invalide;
NUSE_INVALID_ENABLE est une fonction non valide.

Implémenter la gestion du minuteur dans Nucleus SE
Le code de fonction API NUSE_Timer_Control () (après vérification des paramètres) est assez simple:

 NUSE_CS_Enter(); if (enable == NUSE_ENABLE_TIMER) { NUSE_Timer_Status[timer] = TRUE; if (NUSE_Timer_Expirations_Counter[timer] == 0) { NUSE_Timer_Value[timer] = NUSE_Timer_Initial_Time[timer]; } else { NUSE_Timer_Value[timer] = NUSE_Timer_Reschedule_Time[timer]; } } else /* enable == NUSE_DISABLE_TIMER */ { NUSE_Timer_Status[timer] = FALSE; } NUSE_CS_Exit(); 

Si la fonction NUSE_DISABLE_TIMER a été spécifiée, l'état du temporisateur (paramètre NUSE_Timer_Status [] ) est défini sur FALSE , ce qui ignore le temporisateur par le gestionnaire d'interruption.

Lorsque vous sélectionnez la fonction NUSE_ENABLE_TIMER, le compteur du minuteur ( NUSE_Timer_Value [] ) est défini sur NUSE_Timer_initial_Time [] , à condition que le minuteur ne se soit jamais arrêté depuis la dernière réinitialisation. Sinon, la valeur NUSE_Timer_Reschedule_Time [] lui est affectée. Ensuite, l'état du temporisateur (paramètre NUSE_Timer_Status [] ) est défini sur TRUE , ce qui entraîne le traitement du temporisateur par le gestionnaire d'interruption.

Lecture programmée


Pour obtenir le temps de temporisation restant, l'appel de service API Nucleus RTOS renvoie le nombre de mesures jusqu'à son expiration. Nucleus SE offre des fonctionnalités similaires.

Appelez pour obtenir le temps restant dans Nucleus RTOS

Prototype d'appel de service:
STATUS NU_Get_Remaining_Time (minuterie NU_TIMER *, UNSIGNED * temps_reste);

Paramètres:
minuterie - pointeur vers le bloc de commande de minuterie fourni par l'utilisateur;
restant_heure - un pointeur vers le stockage de la valeur de temps restant, qui est une variable de type UNSIGNED .

Valeur de retour
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TIMER - pointeur de temporisateur non valide.

Appelez pour obtenir le temps restant dans Nucleus SE
Cet appel d'API prend en charge toutes les fonctionnalités de l'API RTOS Nucleus.

Prototype d'appel de service:
STATUS NUSE_Timer_Get_Remaining (temporisateur NUSE_TIMER, U16 * temps_ restant);

Paramètres:
timer - index (ID) du timer utilisé;
reste_heure - pointeur vers le stockage de la valeur de temps restant, qui est une variable de type U16 .

Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TIMER - index de temporisateur non valide;
NUSE_INVALID_POINTER - pointeur nul sur le temps restant ( NULL ).

Implémentation d'une lecture par minuterie dans Nucleus SE
La variante de code de fonction API NUSE_Timer_Get_Remaining () (après vérification des paramètres) est trivialement simple. La valeur NUSE_Timer_Value [] est obtenue puis renvoyée dans la section critique.

Services de minuterie auxiliaire


Nucleus RTOS dispose de quatre appels d'API qui fournissent des fonctions auxiliaires liées aux temporisateurs: réinitialiser un temporisateur, obtenir des informations sur le temporisateur, obtenir le nombre de temporisateurs dans une application et obtenir des pointeurs vers tous les temporisateurs d'une application. Les trois premières fonctions sont implémentées dans Nucleus SE.

Réinitialisation de la minuterie


Cet appel API réinitialise le temporisateur à son état d'origine non utilisé. La minuterie peut être activée ou désactivée après la fin de cet appel. Il ne peut être utilisé qu'après la désactivation du temporisateur (à l'aide de NUSE_Timer_Control () ). La prochaine fois que le temporisateur sera activé, il sera initialisé avec le paramètre NUSE_Timer_Initial_Time [] . Nucleus RTOS vous permet de fournir un nouvel état initial et une nouvelle heure de replanification, ainsi que de spécifier la fonction d'achèvement lorsque la minuterie est réinitialisée. Dans Nucleus SE, ces valeurs sont définies lors de la configuration et ne peuvent pas être modifiées car elles sont stockées dans la ROM.

Appel pour réinitialiser une minuterie dans Nucleus RTOS

Prototype d'appel de service:
STATUS NU_Reset_Timer (NU_TIMER * timer, VOID (* expiration_routine) (UNSIGNED), UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable);

Paramètres:
minuterie - un pointeur sur une minuterie réinitialisable;
expiration_routine - indique la fonction qui sera exécutée à la fin de la boucle;
initial_time - le nombre initial de minuteries jusqu'à la fin de la boucle;
reschedule_time - le nombre de tics de temporisation jusqu'à la fin du deuxième cycle et des suivants;
enable - l'état requis du temporisateur après une réinitialisation, peut prendre les valeurs NU_ENABLE_TIMER ou NU_DISABLE_TIMER .

Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TIMER - pointeur non valide vers l'unité de commande de la minuterie;
NU_INVALID_FUNCTION - pointeur nul vers la fonction d'achèvement ( NULL );
NU_INVALID_ENABLE - l'état spécifié est incorrect;
NU_NOT_DISABLED - le temporisateur est déjà en cours d'exécution (il doit être arrêté avant d'appeler cette fonction).

Appelez pour réinitialiser la minuterie dans Nucleus SE
Cet appel de service API prend en charge une version simplifiée de la fonctionnalité principale de l'API Nucleus RTOS.

Prototype d'appel de service:
STATUS NUSE_Timer_Reset (temporisateur NUSE_TIMER, activation OPTION);

Paramètres:
timer - index (ID) du timer de réinitialisation;
enable - l'état requis après la réinitialisation, peut prendre les valeurs NUSE_ENABLE_TIMER ou NUSE_DISABLE_TIMER .

Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TIMER - index de temporisateur non valide;
NUSE_INVALID_ENABLE - l'état spécifié est incorrect;
NUSE_NOT_DISABLED - le temporisateur est déjà en cours d'exécution (il doit être arrêté avant d'appeler cette fonction).

Implémentation d'une réinitialisation de la minuterie dans Nucleus SE
La version du code de fonction API NUSE_Timer_Reset () (après vérification des paramètres et de l'état actuel) est assez simple:

 NUSE_CS_Enter(); NUSE_Init_Timer(timer); if (enable == NUSE_ENABLE_TIMER) { NUSE_Timer_Status[timer] = TRUE; } /*  enable == NUSE_DISABLE_TIMER    FALSE */ NUSE_CS_Exit(); 

Un appel à NUSE_Init_Timer () initialise la valeur de temps et efface le compteur d'achèvement. Après cela, si nécessaire, la valeur de l'état requis est vérifiée et si le temporisateur est activé.

Informations sur la minuterie


Cet appel de service vous permet d'obtenir un ensemble d'informations sur la minuterie. L'implémentation de Nucleus SE diffère de Nucleus RTOS en ce qu'elle renvoie moins d'informations car la dénomination des objets n'est pas prise en charge.

Appelez les informations de la minuterie dans Nucleus RTOS

Prototype d'appel de service:
STATUS NU_Timer_Information (NU_TIMER * timer, CHAR * name, OPTION * enable, UNSIGNED * expirations, UNSIGNED * id, UNSIGNED * initial_time, UNSIGNED * reschedule_time);

Paramètres:
timer - un pointeur sur un timer sur lequel des informations sont demandées;
nom - pointeur vers la région à 8 caractères pour le nom de la minuterie;
enable - pointeur sur une variable qui prend l'état actuel de l'activateur de temporisation: NU_ENABLE_TIMER ou NU_DISABLE_TIMER ;
expirations - un pointeur sur une variable qui prend un compteur du nombre de fin du cycle de temporisation depuis sa dernière réinitialisation;
id - pointeur vers une variable qui prend la valeur du paramètre passé à la fonction de fin de cycle de temporisation;
initial_time - un pointeur vers une variable qui prend une valeur dans laquelle le temporisateur sera initialisé après une réinitialisation;
reschedule_time - un pointeur vers une variable qui prend une valeur dans laquelle le temporisateur sera initialisé une fois terminé.

Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TIMER - pointeur de temporisateur non valide.

Appelez les informations de la minuterie 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_Timer_Information (NUSE_TIMER timer, OPTION * enable, U8 * expirations, U8 * id, U16 * initial_time, U16 * reschedule_time);

Paramètres:
timer - index du timer sur lequel des informations sont demandées;
enable - un pointeur sur une variable qui prend la valeur TRUE ou FALSE , selon que le temporisateur est activé ou non;
expirations - un pointeur vers une variable de type U8 qui prend la valeur du nombre de fin de temporisation depuis sa dernière réinitialisation;
id - pointeur vers une variable de type U8 qui prend la valeur du paramètre passé à la fonction de fin de temporisation (retournera une valeur vide si les fonctions de fin sont désactivées);
initial_time - un pointeur vers une variable de type U16 qui prend une valeur par laquelle le temporisateur sera initialisé après une réinitialisation;
reschedule_time - un pointeur vers une variable de type U16 , qui prend la valeur par laquelle le temporisateur sera initialisé une fois terminé.

Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_TIMER - index de temporisateur non valide;
NUSE_INVALID_POINTER - un ou plusieurs paramètres de pointeur sont incorrects.

Implémentation des informations de minuterie dans Nucleus SE
L'implémentation de cet appel d'API est assez simple:

 NUSE_CS_Enter(); if (NUSE_Timer_Status[timer]) { *enable = NUSE_ENABLE_TIMER; } else { *enable = NUSE_DISABLE_TIMER; } *expirations = NUSE_Timer_Expirations_Counter[timer]; #if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT *id = NUSE_Timer_Expiration_Routine_Parameter[timer]; #endif *initial_time = NUSE_Timer_Initial_Time[timer]; *reschedule_time = NUSE_Timer_Reschedule_Time[timer]; NUSE_CS_Exit(); 

La fonction renvoie l'état de la minuterie. La valeur du paramètre de la fonction de terminaison n'est renvoyée que si leur prise en charge a été activée dans l'application.

Obtenir le nombre de minuteries


Cet appel d'utilitaire renvoie le nombre de temporisations configurées dans l'application. Dans Nucleus RTOS, cette valeur peut changer au fil du temps et la valeur de retour affichera le nombre actuel de temporisateurs. Dans Nucleus SE, la valeur de retour est définie pendant la phase d'assemblage et ne peut pas être modifiée.

Appel à un compteur de minuterie dans Nucleus RTOS

Prototype d'appel de service:
UNSIGNED NU_Established_Timers (VOID);

Paramètres: aucun

Valeur de retour: le nombre de temporisations créées dans le système.

Appel du compteur de minuterie dans Nucleus SE
Cet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus RTOS.

Prototype d'appel de service:
U8 NUSE_Timer_Count (void);

Paramètres: aucun

Valeur de retour:
le nombre de temporisations configurées dans l'application

Mise en œuvre du compteur de minuterie


L'implémentation de cet appel API est assez simple: la valeur du symbole #define NUSE_TIMER_NUMBER est retournée .

Structures de données


Les temporisateurs utilisent cinq ou sept structures de données (situées dans la RAM ou la ROM) qui (comme les autres objets Nucleus SE) sont un ensemble de tables, dont la taille et le nombre correspondent au nombre de temporisateurs configurés et aux paramètres sélectionnés.

Je recommande fortement que le code d'application n'utilise pas un accès direct à ces structures de données, mais s'y réfère via les fonctions API fournies. Cela évitera l'incompatibilité avec les futures versions de Nucleus SE et les effets secondaires indésirables, ainsi que simplifiera le portage des applications vers Nucleus RTOS. Ce qui suit est un aperçu détaillé des structures pour simplifier la compréhension des appels de service et du code de débogage.

Données RAM


Ces données ont la structure suivante:
NUSE_Timer_Status [] est un tableau de type U8 qui a une entrée pour chaque temporisateur configuré et stocke l'état du temporisateur (en cours d'exécution ou arrêté: TRUE ou FALSE ).
NUSE_Timer_Value [] est un tableau de type U16 qui a une entrée pour chaque temporisateur configuré et stocke la valeur actuelle du compteur de temporisation.
NUSE_Timer_Expirations_Counter [] - un tableau de type U8 , contenant un compteur du nombre de cas où les temporisateurs ont atteint la fin du cycle depuis leur dernière réinitialisation.

Toutes ces structures de données sont initialisées par la fonction NUSE_Init_Timer () au démarrage de Nucleus SE. L'un des articles suivants contiendra une description complète des procédures de démarrage de Nucleus SE.

Voici les définitions de ces structures de données dans le fichier nuse_init.c :
RAM U8 Timer_Status [NUSE_TIMER_NUMBER];
RAM U16 NUSE_Timer_Value [NUSE_TIMER_NUMBER];
RAM U8 NUSE_Timer_Expirations_Counter [NUSE_TIMER_NUMBER];

Données ROM


La structure de ces données:
NUSE_Timer_Initial_Time [] est un tableau de type U16 qui a une entrée pour chaque temporisateur configuré et stocke la valeur de chaque temporisateur.
NUSE_Timer_Reschedule_Time [] est un tableau de type U16 qui a une entrée pour chaque temporisateur configuré et stocke la valeur à laquelle le temporisateur sera défini une fois terminé. Une valeur de zéro indique que la minuterie est «ponctuelle» et ne doit pas redémarrer automatiquement.
NUSE_Timer_Expiration_Routine_Address [] - un tableau de type ADDR contenant l'adresse des procédures d'expiration du temporisateur. Ce tableau existe uniquement si la prise en charge de la procédure d'expiration du temporisateur a été activée.
NUSE_Timer_Expiration_Routine_Parameter [] - un tableau de type U8 contenant les valeurs du paramètre qui est passé à la fonction de fin de temporisation. Ce tableau existe uniquement si la prise en charge des fonctions d'achèvement a été activée.

Ces structures de données sont déclarées et initialisées (statiquement) dans le fichier nuse_config.c , ainsi:

 ROM U16 NUSE_Timer_Initial_Time[NUSE_TIMER_NUMBER] = { /*   ------ */ }; ROM U16 NUSE_Timer_Reschedule_Time[NUSE_TIMER_NUMBER] = { /*      ------ */ }; #if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT || NUSE_INCLUDE_EVERYTHING /*    */ ROM ADDR NUSE_Timer_Expiration_Routine_Address[NUSE_TIMER_NUMBER] = { /*     ------ */ /*   NULL */ }; ROM U8 NUSE_Timer_Expiration_Routine_Parameter[NUSE_TIMER_NUMBER] = { /*     ------ */ }; #endif 

La quantité de mémoire pour la minuterie


Comme tous les autres objets Nucleus SE, la quantité de données nécessaires pour les temporisateurs est prévisible.

La quantité de données dans la RAM (en octets) pour tous les temporisateurs de l'application peut être calculée comme suit:
NUSE_TIMER_NUMBER * 4

La quantité de données dans la ROM (en octets) pour tous les temporisateurs de l'application, si la prise en charge des fonctions d'achèvement est désactivée, peut être calculée comme suit:
NUSE_TIMER_NUMBER * 4

Sinon, il est égal à:
NUSE_TIMER_NUMBER * (taille de (ADDR) + 5)

Appels d'API non réalisés


Nucleus SE n'implémente pas les trois appels d'API qui peuvent être trouvés dans RTOS.

Création de minuterie


Cet appel API crée une minuterie. Nucleus SE n'en a pas besoin, car les temporisateurs sont créés statiquement.

Prototype d'appel de service:
STATUS NU_Create_Timer (NU_TIMER * timer, CHAR * name, VOID (* expiration_routine) (UNSIGNED), UNSIGNED id, UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable);

Paramètres:
minuterie - pointeur vers le bloc de commande de minuterie fourni par l'utilisateur; il sera utilisé pour contrôler les temporisateurs dans d'autres appels d'API;
nom - pointeur sur le nom à 7 caractères du temporisateur avec un zéro de fin;
expiration_routine - indique la fonction qui doit être exécutée après la fin du temporisateur;
id - un élément de données de type UNSIGNED transmis à la fonction de terminaison: ce paramètre peut être utilisé pour identifier des temporisateurs ayant la même fonction de terminaison;
initial_time - indique le nombre initial de tics du minuteur avant la fin du minuteur;
reschedule_time - indique le nombre de tics de temporisation jusqu'à la fin du deuxième cycle et des suivants; si ce paramètre est égal à zéro, le temporisateur ne s'arrête qu'une seule fois;
enable - ce paramètre peut prendre les valeurs NU_ENABLE_TIMER et NU_DISABLE_TIMER ; NU_ENABLE_TIMER active un temporisateur après sa création; NU_DISABLE_TIMER laisse le temporisateur désactivé; les temporisateurs créés avec le paramètre NU_DISABLE_TIMER doivent être activés en appelant NU_Control_Timer .

Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TIMER - un pointeur nul vers une unité de contrôle de minuterie ( NULL ), ou l'unité de contrôle est déjà en cours d'utilisation;
NU_INVALID_FUNCTION - pointeur nul vers le programme d'achèvement ( NULL );
NU_INVALID_ENABLE - paramètre d' activation non valide;
NU_INVALID_OPERATION - le paramètre initial_time était zéro.

Supprimer la minuterie


Cet appel d'API supprime un minuteur créé précédemment. Nucleus SE n'en a pas besoin, car les temporisateurs sont créés statiquement et ne peuvent pas être supprimés.

Prototype d'appel de service:
STATUS NU_Delete_Timer (NU_TIMER * timer);

Paramètres:
timer - pointeur sur le bloc de contrôle du timer.

Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TIMER - pointeur de temporisateur invalide;
NU_NOT_DISABLED - Le temporisateur spécifié n'est pas désactivé.

Pointeurs de minuterie


Cet appel d'API forme une liste séquentielle de pointeurs vers tous les temporisateurs du système. Nucleus SE n'en a pas besoin, car les temporisateurs sont déterminés par un simple index, pas un pointeur.

Prototype d'appel de service:
UNSIGNED NU_Timer_Pointers (NU_TIMER ** pointer_list, UNSIGNED maximum_pointers);

Paramètres:
pointer_list - pointeur vers un tableau de pointeurs NU_TIMER ; il sera rempli de pointeurs vers des temporisateurs configurés dans le système;
maximum_pointers - le nombre maximum de pointeurs dans le tableau.

Valeur de retour:
Le nombre de pointeurs NU_TIMER placés dans le tableau.

Compatible avec Nucleus RTOS


Comme pour tous les autres objets Nucleus SE, mon objectif était de maximiser la compatibilité du code d'application avec Nucleus RTOS. Les temporisateurs ne font pas exception et, du point de vue de l'utilisateur, ils sont implémentés de la même manière que dans Nucleus RTOS.Il y a aussi une certaine incompatibilité, que j'ai jugée acceptable, étant donné que le code deviendra ainsi plus compréhensible et plus efficace en termes de quantité de mémoire requise. Sinon, les appels d'API Nucleus RTOS peuvent être portés presque directement vers Nucleus SE.

Identificateurs d'objet


Dans Nucleus RTOS, tous les objets sont décrits par une structure de données - un bloc de contrôle qui a un type de données spécifique. Un pointeur vers cette unité de commande est un identificateur de temporisateur. J'ai décidé que dans Nucleus SE, une approche différente est nécessaire pour une utilisation efficace de la mémoire: tous les objets du noyau sont décrits par un ensemble de tables en RAM et / ou ROM. La taille de ces tables est déterminée par le nombre d'objets configurés de chaque type. L'identifiant d'un objet particulier est l'index dans ce tableau. J'ai donc défini NUSE_TIMER comme l'équivalent de U8, une variable (pas un pointeur) de ce type sert d'identifiant du temporisateur. Cette légère incompatibilité est facile à gérer si le code est porté de Nucleus SE vers Nucleus RTOS et vice versa. En règle générale, aucune opération n'est effectuée sur les identificateurs d'objet autres que le déplacement et le stockage.
Nucleus RTOS prend également en charge les minuteries de dénomination. Ces noms sont utilisés uniquement pour le débogage. Je les ai exclus de Nucleus SE pour économiser de la mémoire.

Taille de la minuterie


Dans Nucleus RTOS, les temporisateurs sont implémentés à l'aide de compteurs 32 bits. J'ai décidé de réduire cette valeur à 16 bits dans Nucleus SE. Cela a conduit à des améliorations significatives de l'efficacité de la mémoire et de l'exécution. Nucleus SE peut être modifié si l'application nécessite un temps d'exécution plus long.

Fonctions de complétion


Nucleus SE implémente les fonctions de terminaison d'une manière similaire à Nucleus RTOS, mais elles peuvent être complètement désactivées (ce qui vous permet d'économiser de la mémoire), et elles sont également déterminées statiquement. La fonction de fin ne peut pas être modifiée lorsque la minuterie est réinitialisée.

Appels d'API non réalisés


Nucleus RTOS prend en charge huit appels de service de minuterie. Parmi ceux-ci, trois ne sont pas implémentés dans Nucleus SE. Une description détaillée de ces appels, ainsi que les raisons de cette décision, se trouvent plus haut dans cet article, dans la section «Appels d'API non réalisés».

L'article suivant examinera les interruptions.

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


All Articles